1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82#include <linux/module.h>
83#include <linux/errno.h>
84#include <linux/delay.h>
85#include <linux/pci.h>
86#include <linux/init.h>
87#include <linux/blkdev.h>
88#include <linux/spinlock.h>
89#include <linux/stat.h>
90#include <linux/kernel.h>
91#include <linux/proc_fs.h>
92#include <linux/string.h>
93#include <linux/interrupt.h>
94#include <linux/ioport.h>
95#include <linux/slab.h>
96#include <linux/jiffies.h>
97#include <linux/dma-mapping.h>
98#include <asm/io.h>
99
100#include <scsi/scsi.h>
101#include <scsi/scsi_cmnd.h>
102#include <scsi/scsi_device.h>
103#include <scsi/scsi_host.h>
104#include <scsi/scsi_tcq.h>
105
106#include "initio.h"
107
108#define SENSE_SIZE 14
109
110#define i91u_MAXQUEUE 2
111#define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a"
112
113#ifdef DEBUG_i91u
114static unsigned int i91u_debug = DEBUG_DEFAULT;
115#endif
116
117static int initio_tag_enable = 1;
118
119#ifdef DEBUG_i91u
120static int setup_debug = 0;
121#endif
122
123static void i91uSCBPost(u8 * pHcb, u8 * pScb);
124
125#define DEBUG_INTERRUPT 0
126#define DEBUG_QUEUE 0
127#define DEBUG_STATE 0
128#define INT_DISC 0
129
130
131static struct scsi_ctrl_blk *initio_find_busy_scb(struct initio_host * host, u16 tarlun);
132static struct scsi_ctrl_blk *initio_find_done_scb(struct initio_host * host);
133
134static int tulip_main(struct initio_host * host);
135
136static int initio_next_state(struct initio_host * host);
137static int initio_state_1(struct initio_host * host);
138static int initio_state_2(struct initio_host * host);
139static int initio_state_3(struct initio_host * host);
140static int initio_state_4(struct initio_host * host);
141static int initio_state_5(struct initio_host * host);
142static int initio_state_6(struct initio_host * host);
143static int initio_state_7(struct initio_host * host);
144static int initio_xfer_data_in(struct initio_host * host);
145static int initio_xfer_data_out(struct initio_host * host);
146static int initio_xpad_in(struct initio_host * host);
147static int initio_xpad_out(struct initio_host * host);
148static int initio_status_msg(struct initio_host * host);
149
150static int initio_msgin(struct initio_host * host);
151static int initio_msgin_sync(struct initio_host * host);
152static int initio_msgin_accept(struct initio_host * host);
153static int initio_msgout_reject(struct initio_host * host);
154static int initio_msgin_extend(struct initio_host * host);
155
156static int initio_msgout_ide(struct initio_host * host);
157static int initio_msgout_abort_targ(struct initio_host * host);
158static int initio_msgout_abort_tag(struct initio_host * host);
159
160static int initio_bus_device_reset(struct initio_host * host);
161static void initio_select_atn(struct initio_host * host, struct scsi_ctrl_blk * scb);
162static void initio_select_atn3(struct initio_host * host, struct scsi_ctrl_blk * scb);
163static void initio_select_atn_stop(struct initio_host * host, struct scsi_ctrl_blk * scb);
164static int int_initio_busfree(struct initio_host * host);
165static int int_initio_scsi_rst(struct initio_host * host);
166static int int_initio_bad_seq(struct initio_host * host);
167static int int_initio_resel(struct initio_host * host);
168static int initio_sync_done(struct initio_host * host);
169static int wdtr_done(struct initio_host * host);
170static int wait_tulip(struct initio_host * host);
171static int initio_wait_done_disc(struct initio_host * host);
172static int initio_wait_disc(struct initio_host * host);
173static void tulip_scsi(struct initio_host * host);
174static int initio_post_scsi_rst(struct initio_host * host);
175
176static void initio_se2_ew_en(unsigned long base);
177static void initio_se2_ew_ds(unsigned long base);
178static int initio_se2_rd_all(unsigned long base);
179static void initio_se2_update_all(unsigned long base);
180static void initio_read_eeprom(unsigned long base);
181
182
183
184static NVRAM i91unvram;
185static NVRAM *i91unvramp;
186
187static u8 i91udftNvRam[64] =
188{
189
190 0x25, 0xc9,
191 0x40,
192 0x01,
193
194 0x95,
195 0x00,
196 0x00,
197 0x01,
198 NBC1_DEFAULT,
199 0,
200 0,
201 0,
202
203 7,
204 NCC1_DEFAULT,
205 0,
206 0x10,
207
208 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
209 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
210 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
211 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
212
213
214 7,
215 NCC1_DEFAULT,
216 0,
217 0x10,
218
219 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
220 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
221 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
222 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
223 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224 0, 0};
225
226
227static u8 initio_rate_tbl[8] =
228{
229
230 12,
231 18,
232 25,
233 31,
234 37,
235 43,
236 50,
237 62
238};
239
240static void initio_do_pause(unsigned amount)
241{
242
243 unsigned long the_time = jiffies + amount;
244
245 while (time_before_eq(jiffies, the_time))
246 cpu_relax();
247}
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290static void initio_se2_instr(unsigned long base, u8 instr)
291{
292 int i;
293 u8 b;
294
295 outb(SE2CS | SE2DO, base + TUL_NVRAM);
296 udelay(30);
297 outb(SE2CS | SE2CLK | SE2DO, base + TUL_NVRAM);
298 udelay(30);
299
300 for (i = 0; i < 8; i++) {
301 if (instr & 0x80)
302 b = SE2CS | SE2DO;
303 else
304 b = SE2CS;
305 outb(b, base + TUL_NVRAM);
306 udelay(30);
307 outb(b | SE2CLK, base + TUL_NVRAM);
308 udelay(30);
309 instr <<= 1;
310 }
311 outb(SE2CS, base + TUL_NVRAM);
312 udelay(30);
313}
314
315
316
317
318
319
320
321
322void initio_se2_ew_en(unsigned long base)
323{
324 initio_se2_instr(base, 0x30);
325 outb(0, base + TUL_NVRAM);
326 udelay(30);
327}
328
329
330
331
332
333
334
335
336void initio_se2_ew_ds(unsigned long base)
337{
338 initio_se2_instr(base, 0);
339 outb(0, base + TUL_NVRAM);
340 udelay(30);
341}
342
343
344
345
346
347
348
349
350
351static u16 initio_se2_rd(unsigned long base, u8 addr)
352{
353 u8 instr, rb;
354 u16 val = 0;
355 int i;
356
357 instr = (u8) (addr | 0x80);
358 initio_se2_instr(base, instr);
359
360 for (i = 15; i >= 0; i--) {
361 outb(SE2CS | SE2CLK, base + TUL_NVRAM);
362 udelay(30);
363 outb(SE2CS, base + TUL_NVRAM);
364
365
366 rb = inb(base + TUL_NVRAM);
367 rb &= SE2DI;
368 val += (rb << i);
369 udelay(30);
370 }
371
372 outb(0, base + TUL_NVRAM);
373 udelay(30);
374 return val;
375}
376
377
378
379
380
381
382
383
384
385
386static void initio_se2_wr(unsigned long base, u8 addr, u16 val)
387{
388 u8 rb;
389 u8 instr;
390 int i;
391
392 instr = (u8) (addr | 0x40);
393 initio_se2_instr(base, instr);
394 for (i = 15; i >= 0; i--) {
395 if (val & 0x8000)
396 outb(SE2CS | SE2DO, base + TUL_NVRAM);
397 else
398 outb(SE2CS, base + TUL_NVRAM);
399 udelay(30);
400 outb(SE2CS | SE2CLK, base + TUL_NVRAM);
401 udelay(30);
402 val <<= 1;
403 }
404 outb(SE2CS, base + TUL_NVRAM);
405 udelay(30);
406 outb(0, base + TUL_NVRAM);
407 udelay(30);
408
409 outb(SE2CS, base + TUL_NVRAM);
410 udelay(30);
411
412 for (;;) {
413 outb(SE2CS | SE2CLK, base + TUL_NVRAM);
414 udelay(30);
415 outb(SE2CS, base + TUL_NVRAM);
416 udelay(30);
417 if ((rb = inb(base + TUL_NVRAM)) & SE2DI)
418 break;
419 }
420 outb(0, base + TUL_NVRAM);
421}
422
423
424
425
426
427
428
429
430
431static int initio_se2_rd_all(unsigned long base)
432{
433 int i;
434 u16 chksum = 0;
435 u16 *np;
436
437 i91unvramp = &i91unvram;
438 np = (u16 *) i91unvramp;
439 for (i = 0; i < 32; i++)
440 *np++ = initio_se2_rd(base, i);
441
442
443 if (i91unvramp->NVM_Signature != INI_SIGNATURE)
444 return -1;
445
446 np = (u16 *) i91unvramp;
447 for (i = 0; i < 31; i++)
448 chksum += *np++;
449 if (i91unvramp->NVM_CheckSum != chksum)
450 return -1;
451 return 1;
452}
453
454
455
456
457
458
459
460
461static void initio_se2_update_all(unsigned long base)
462{
463 int i;
464 u16 chksum = 0;
465 u16 *np, *np1;
466
467 i91unvramp = &i91unvram;
468
469 np = (u16 *) i91udftNvRam;
470 for (i = 0; i < 31; i++)
471 chksum += *np++;
472 *np = chksum;
473 initio_se2_ew_en(base);
474
475 np = (u16 *) i91udftNvRam;
476 np1 = (u16 *) i91unvramp;
477 for (i = 0; i < 32; i++, np++, np1++) {
478 if (*np != *np1)
479 initio_se2_wr(base, i, *np);
480 }
481 initio_se2_ew_ds(base);
482}
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497static void initio_read_eeprom(unsigned long base)
498{
499 u8 gctrl;
500
501 i91unvramp = &i91unvram;
502
503 gctrl = inb(base + TUL_GCTRL);
504 outb(gctrl | TUL_GCTRL_EEPROM_BIT, base + TUL_GCTRL);
505 if (initio_se2_rd_all(base) != 1) {
506 initio_se2_update_all(base);
507 initio_se2_rd_all(base);
508 }
509
510 gctrl = inb(base + TUL_GCTRL);
511 outb(gctrl & ~TUL_GCTRL_EEPROM_BIT, base + TUL_GCTRL);
512}
513
514
515
516
517
518
519
520
521static void initio_stop_bm(struct initio_host * host)
522{
523
524 if (inb(host->addr + TUL_XStatus) & XPEND) {
525 outb(TAX_X_ABT | TAX_X_CLR_FIFO, host->addr + TUL_XCmd);
526
527 while ((inb(host->addr + TUL_Int) & XABT) == 0)
528 cpu_relax();
529 }
530 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
531}
532
533
534
535
536
537
538
539
540
541static int initio_reset_scsi(struct initio_host * host, int seconds)
542{
543 outb(TSC_RST_BUS, host->addr + TUL_SCtrl0);
544
545 while (!((host->jsint = inb(host->addr + TUL_SInt)) & TSS_SCSIRST_INT))
546 cpu_relax();
547
548
549 outb(0, host->addr + TUL_SSignal);
550
551
552
553
554 initio_do_pause(seconds * HZ);
555
556 inb(host->addr + TUL_SInt);
557 return SCSI_RESET_SUCCESS;
558}
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573static void initio_init(struct initio_host * host, u8 *bios_addr)
574{
575 int i;
576 u8 *flags;
577 u8 *heads;
578
579
580 initio_read_eeprom(host->addr);
581 if (i91unvramp->NVM_SCSIInfo[0].NVM_NumOfTarg == 8)
582 host->max_tar = 8;
583 else
584 host->max_tar = 16;
585
586 host->config = i91unvramp->NVM_SCSIInfo[0].NVM_ChConfig1;
587
588 host->scsi_id = i91unvramp->NVM_SCSIInfo[0].NVM_ChSCSIID;
589 host->idmask = ~(1 << host->scsi_id);
590
591#ifdef CHK_PARITY
592
593 outb(inb(host->addr + TUL_PCMD) | 0x40, host->addr + TUL_PCMD);
594#endif
595
596
597 outb(0x1F, host->addr + TUL_Mask);
598
599 initio_stop_bm(host);
600
601 outb(TSC_RST_CHIP, host->addr + TUL_SCtrl0);
602
603
604 outb(host->scsi_id << 4, host->addr + TUL_SScsiId);
605
606
607
608 if (host->config & HCC_EN_PAR)
609 host->sconf1 = (TSC_INITDEFAULT | TSC_EN_SCSI_PAR);
610 else
611 host->sconf1 = (TSC_INITDEFAULT);
612 outb(host->sconf1, host->addr + TUL_SConfig);
613
614
615 outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1);
616
617 outb(0, host->addr + TUL_SPeriod);
618
619
620 outb(153, host->addr + TUL_STimeOut);
621
622
623 outb((host->config & (HCC_ACT_TERM1 | HCC_ACT_TERM2)),
624 host->addr + TUL_XCtrl);
625 outb(((host->config & HCC_AUTO_TERM) >> 4) |
626 (inb(host->addr + TUL_GCTRL1) & 0xFE),
627 host->addr + TUL_GCTRL1);
628
629 for (i = 0,
630 flags = & (i91unvramp->NVM_SCSIInfo[0].NVM_Targ0Config),
631 heads = bios_addr + 0x180;
632 i < host->max_tar;
633 i++, flags++) {
634 host->targets[i].flags = *flags & ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
635 if (host->targets[i].flags & TCF_EN_255)
636 host->targets[i].drv_flags = TCF_DRV_255_63;
637 else
638 host->targets[i].drv_flags = 0;
639 host->targets[i].js_period = 0;
640 host->targets[i].sconfig0 = host->sconf1;
641 host->targets[i].heads = *heads++;
642 if (host->targets[i].heads == 255)
643 host->targets[i].drv_flags = TCF_DRV_255_63;
644 else
645 host->targets[i].drv_flags = 0;
646 host->targets[i].sectors = *heads++;
647 host->targets[i].flags &= ~TCF_BUSY;
648 host->act_tags[i] = 0;
649 host->max_tags[i] = 0xFF;
650 }
651 printk("i91u: PCI Base=0x%04X, IRQ=%d, BIOS=0x%04X0, SCSI ID=%d\n",
652 host->addr, host->pci_dev->irq,
653 host->bios_addr, host->scsi_id);
654
655 if (host->config & HCC_SCSI_RESET) {
656 printk(KERN_INFO "i91u: Reset SCSI Bus ... \n");
657 initio_reset_scsi(host, 10);
658 }
659 outb(0x17, host->addr + TUL_SCFG1);
660 outb(0xE9, host->addr + TUL_SIntEnable);
661}
662
663
664
665
666
667
668
669
670static struct scsi_ctrl_blk *initio_alloc_scb(struct initio_host *host)
671{
672 struct scsi_ctrl_blk *scb;
673 unsigned long flags;
674
675 spin_lock_irqsave(&host->avail_lock, flags);
676 if ((scb = host->first_avail) != NULL) {
677#if DEBUG_QUEUE
678 printk("find scb at %p\n", scb);
679#endif
680 if ((host->first_avail = scb->next) == NULL)
681 host->last_avail = NULL;
682 scb->next = NULL;
683 scb->status = SCB_RENT;
684 }
685 spin_unlock_irqrestore(&host->avail_lock, flags);
686 return scb;
687}
688
689
690
691
692
693
694
695
696
697static void initio_release_scb(struct initio_host * host, struct scsi_ctrl_blk * cmnd)
698{
699 unsigned long flags;
700
701#if DEBUG_QUEUE
702 printk("Release SCB %p; ", cmnd);
703#endif
704 spin_lock_irqsave(&(host->avail_lock), flags);
705 cmnd->srb = NULL;
706 cmnd->status = 0;
707 cmnd->next = NULL;
708 if (host->last_avail != NULL) {
709 host->last_avail->next = cmnd;
710 host->last_avail = cmnd;
711 } else {
712 host->first_avail = cmnd;
713 host->last_avail = cmnd;
714 }
715 spin_unlock_irqrestore(&(host->avail_lock), flags);
716}
717
718
719static void initio_append_pend_scb(struct initio_host * host, struct scsi_ctrl_blk * scbp)
720{
721
722#if DEBUG_QUEUE
723 printk("Append pend SCB %p; ", scbp);
724#endif
725 scbp->status = SCB_PEND;
726 scbp->next = NULL;
727 if (host->last_pending != NULL) {
728 host->last_pending->next = scbp;
729 host->last_pending = scbp;
730 } else {
731 host->first_pending = scbp;
732 host->last_pending = scbp;
733 }
734}
735
736
737static void initio_push_pend_scb(struct initio_host * host, struct scsi_ctrl_blk * scbp)
738{
739
740#if DEBUG_QUEUE
741 printk("Push pend SCB %p; ", scbp);
742#endif
743 scbp->status = SCB_PEND;
744 if ((scbp->next = host->first_pending) != NULL) {
745 host->first_pending = scbp;
746 } else {
747 host->first_pending = scbp;
748 host->last_pending = scbp;
749 }
750}
751
752static struct scsi_ctrl_blk *initio_find_first_pend_scb(struct initio_host * host)
753{
754 struct scsi_ctrl_blk *first;
755
756
757 first = host->first_pending;
758 while (first != NULL) {
759 if (first->opcode != ExecSCSI)
760 return first;
761 if (first->tagmsg == 0) {
762 if ((host->act_tags[first->target] == 0) &&
763 !(host->targets[first->target].flags & TCF_BUSY))
764 return first;
765 } else {
766 if ((host->act_tags[first->target] >=
767 host->max_tags[first->target]) |
768 (host->targets[first->target].flags & TCF_BUSY)) {
769 first = first->next;
770 continue;
771 }
772 return first;
773 }
774 first = first->next;
775 }
776 return first;
777}
778
779static void initio_unlink_pend_scb(struct initio_host * host, struct scsi_ctrl_blk * scb)
780{
781 struct scsi_ctrl_blk *tmp, *prev;
782
783#if DEBUG_QUEUE
784 printk("unlink pend SCB %p; ", scb);
785#endif
786
787 prev = tmp = host->first_pending;
788 while (tmp != NULL) {
789 if (scb == tmp) {
790 if (tmp == host->first_pending) {
791 if ((host->first_pending = tmp->next) == NULL)
792 host->last_pending = NULL;
793 } else {
794 prev->next = tmp->next;
795 if (tmp == host->last_pending)
796 host->last_pending = prev;
797 }
798 tmp->next = NULL;
799 break;
800 }
801 prev = tmp;
802 tmp = tmp->next;
803 }
804}
805
806static void initio_append_busy_scb(struct initio_host * host, struct scsi_ctrl_blk * scbp)
807{
808
809#if DEBUG_QUEUE
810 printk("append busy SCB %p; ", scbp);
811#endif
812 if (scbp->tagmsg)
813 host->act_tags[scbp->target]++;
814 else
815 host->targets[scbp->target].flags |= TCF_BUSY;
816 scbp->status = SCB_BUSY;
817 scbp->next = NULL;
818 if (host->last_busy != NULL) {
819 host->last_busy->next = scbp;
820 host->last_busy = scbp;
821 } else {
822 host->first_busy = scbp;
823 host->last_busy = scbp;
824 }
825}
826
827
828static struct scsi_ctrl_blk *initio_pop_busy_scb(struct initio_host * host)
829{
830 struct scsi_ctrl_blk *tmp;
831
832
833 if ((tmp = host->first_busy) != NULL) {
834 if ((host->first_busy = tmp->next) == NULL)
835 host->last_busy = NULL;
836 tmp->next = NULL;
837 if (tmp->tagmsg)
838 host->act_tags[tmp->target]--;
839 else
840 host->targets[tmp->target].flags &= ~TCF_BUSY;
841 }
842#if DEBUG_QUEUE
843 printk("Pop busy SCB %p; ", tmp);
844#endif
845 return tmp;
846}
847
848
849static void initio_unlink_busy_scb(struct initio_host * host, struct scsi_ctrl_blk * scb)
850{
851 struct scsi_ctrl_blk *tmp, *prev;
852
853#if DEBUG_QUEUE
854 printk("unlink busy SCB %p; ", scb);
855#endif
856
857 prev = tmp = host->first_busy;
858 while (tmp != NULL) {
859 if (scb == tmp) {
860 if (tmp == host->first_busy) {
861 if ((host->first_busy = tmp->next) == NULL)
862 host->last_busy = NULL;
863 } else {
864 prev->next = tmp->next;
865 if (tmp == host->last_busy)
866 host->last_busy = prev;
867 }
868 tmp->next = NULL;
869 if (tmp->tagmsg)
870 host->act_tags[tmp->target]--;
871 else
872 host->targets[tmp->target].flags &= ~TCF_BUSY;
873 break;
874 }
875 prev = tmp;
876 tmp = tmp->next;
877 }
878 return;
879}
880
881struct scsi_ctrl_blk *initio_find_busy_scb(struct initio_host * host, u16 tarlun)
882{
883 struct scsi_ctrl_blk *tmp, *prev;
884 u16 scbp_tarlun;
885
886
887 prev = tmp = host->first_busy;
888 while (tmp != NULL) {
889 scbp_tarlun = (tmp->lun << 8) | (tmp->target);
890 if (scbp_tarlun == tarlun) {
891 break;
892 }
893 prev = tmp;
894 tmp = tmp->next;
895 }
896#if DEBUG_QUEUE
897 printk("find busy SCB %p; ", tmp);
898#endif
899 return tmp;
900}
901
902static void initio_append_done_scb(struct initio_host * host, struct scsi_ctrl_blk * scbp)
903{
904#if DEBUG_QUEUE
905 printk("append done SCB %p; ", scbp);
906#endif
907
908 scbp->status = SCB_DONE;
909 scbp->next = NULL;
910 if (host->last_done != NULL) {
911 host->last_done->next = scbp;
912 host->last_done = scbp;
913 } else {
914 host->first_done = scbp;
915 host->last_done = scbp;
916 }
917}
918
919struct scsi_ctrl_blk *initio_find_done_scb(struct initio_host * host)
920{
921 struct scsi_ctrl_blk *tmp;
922
923 if ((tmp = host->first_done) != NULL) {
924 if ((host->first_done = tmp->next) == NULL)
925 host->last_done = NULL;
926 tmp->next = NULL;
927 }
928#if DEBUG_QUEUE
929 printk("find done SCB %p; ",tmp);
930#endif
931 return tmp;
932}
933
934static int initio_abort_srb(struct initio_host * host, struct scsi_cmnd *srbp)
935{
936 unsigned long flags;
937 struct scsi_ctrl_blk *tmp, *prev;
938
939 spin_lock_irqsave(&host->semaph_lock, flags);
940
941 if ((host->semaph == 0) && (host->active == NULL)) {
942
943 outb(0x1F, host->addr + TUL_Mask);
944 spin_unlock_irqrestore(&host->semaph_lock, flags);
945
946 tulip_main(host);
947 spin_lock_irqsave(&host->semaph_lock, flags);
948 host->semaph = 1;
949 outb(0x0F, host->addr + TUL_Mask);
950 spin_unlock_irqrestore(&host->semaph_lock, flags);
951 return SCSI_ABORT_SNOOZE;
952 }
953 prev = tmp = host->first_pending;
954 while (tmp != NULL) {
955
956 if (tmp->srb == srbp) {
957 if (tmp == host->active) {
958 spin_unlock_irqrestore(&host->semaph_lock, flags);
959 return SCSI_ABORT_BUSY;
960 } else if (tmp == host->first_pending) {
961 if ((host->first_pending = tmp->next) == NULL)
962 host->last_pending = NULL;
963 } else {
964 prev->next = tmp->next;
965 if (tmp == host->last_pending)
966 host->last_pending = prev;
967 }
968 tmp->hastat = HOST_ABORTED;
969 tmp->flags |= SCF_DONE;
970 if (tmp->flags & SCF_POST)
971 (*tmp->post) ((u8 *) host, (u8 *) tmp);
972 spin_unlock_irqrestore(&host->semaph_lock, flags);
973 return SCSI_ABORT_SUCCESS;
974 }
975 prev = tmp;
976 tmp = tmp->next;
977 }
978
979 prev = tmp = host->first_busy;
980 while (tmp != NULL) {
981 if (tmp->srb == srbp) {
982 if (tmp == host->active) {
983 spin_unlock_irqrestore(&host->semaph_lock, flags);
984 return SCSI_ABORT_BUSY;
985 } else if (tmp->tagmsg == 0) {
986 spin_unlock_irqrestore(&host->semaph_lock, flags);
987 return SCSI_ABORT_BUSY;
988 } else {
989 host->act_tags[tmp->target]--;
990 if (tmp == host->first_busy) {
991 if ((host->first_busy = tmp->next) == NULL)
992 host->last_busy = NULL;
993 } else {
994 prev->next = tmp->next;
995 if (tmp == host->last_busy)
996 host->last_busy = prev;
997 }
998 tmp->next = NULL;
999
1000
1001 tmp->hastat = HOST_ABORTED;
1002 tmp->flags |= SCF_DONE;
1003 if (tmp->flags & SCF_POST)
1004 (*tmp->post) ((u8 *) host, (u8 *) tmp);
1005 spin_unlock_irqrestore(&host->semaph_lock, flags);
1006 return SCSI_ABORT_SUCCESS;
1007 }
1008 }
1009 prev = tmp;
1010 tmp = tmp->next;
1011 }
1012 spin_unlock_irqrestore(&host->semaph_lock, flags);
1013 return SCSI_ABORT_NOT_RUNNING;
1014}
1015
1016
1017static int initio_bad_seq(struct initio_host * host)
1018{
1019 struct scsi_ctrl_blk *scb;
1020
1021 printk("initio_bad_seg c=%d\n", host->index);
1022
1023 if ((scb = host->active) != NULL) {
1024 initio_unlink_busy_scb(host, scb);
1025 scb->hastat = HOST_BAD_PHAS;
1026 scb->tastat = 0;
1027 initio_append_done_scb(host, scb);
1028 }
1029 initio_stop_bm(host);
1030 initio_reset_scsi(host, 8);
1031 return initio_post_scsi_rst(host);
1032}
1033
1034
1035
1036static void initio_exec_scb(struct initio_host * host, struct scsi_ctrl_blk * scb)
1037{
1038 unsigned long flags;
1039
1040 scb->mode = 0;
1041
1042 scb->sgidx = 0;
1043 scb->sgmax = scb->sglen;
1044
1045 spin_lock_irqsave(&host->semaph_lock, flags);
1046
1047 initio_append_pend_scb(host, scb);
1048
1049
1050 if (host->semaph == 1) {
1051
1052 outb(0x1F, host->addr + TUL_Mask);
1053 host->semaph = 0;
1054 spin_unlock_irqrestore(&host->semaph_lock, flags);
1055
1056 tulip_main(host);
1057
1058 spin_lock_irqsave(&host->semaph_lock, flags);
1059 host->semaph = 1;
1060 outb(0x0F, host->addr + TUL_Mask);
1061 }
1062 spin_unlock_irqrestore(&host->semaph_lock, flags);
1063 return;
1064}
1065
1066
1067static int initio_isr(struct initio_host * host)
1068{
1069 if (inb(host->addr + TUL_Int) & TSS_INT_PENDING) {
1070 if (host->semaph == 1) {
1071 outb(0x1F, host->addr + TUL_Mask);
1072
1073 host->semaph = 0;
1074
1075 tulip_main(host);
1076
1077 host->semaph = 1;
1078 outb(0x0F, host->addr + TUL_Mask);
1079 return 1;
1080 }
1081 }
1082 return 0;
1083}
1084
1085static int tulip_main(struct initio_host * host)
1086{
1087 struct scsi_ctrl_blk *scb;
1088
1089 for (;;) {
1090 tulip_scsi(host);
1091
1092
1093 while ((scb = initio_find_done_scb(host)) != NULL) {
1094 if (scb->tastat == INI_QUEUE_FULL) {
1095 host->max_tags[scb->target] =
1096 host->act_tags[scb->target] - 1;
1097 scb->tastat = 0;
1098 initio_append_pend_scb(host, scb);
1099 continue;
1100 }
1101 if (!(scb->mode & SCM_RSENS)) {
1102 if (scb->tastat == 2) {
1103
1104
1105
1106 if (scb->flags & SCF_SENSE) {
1107 u8 len;
1108 len = scb->senselen;
1109 if (len == 0)
1110 len = 1;
1111 scb->buflen = scb->senselen;
1112 scb->bufptr = scb->senseptr;
1113 scb->flags &= ~(SCF_SG | SCF_DIR);
1114
1115
1116 scb->mode = SCM_RSENS;
1117 scb->ident &= 0xBF;
1118 scb->tagmsg = 0;
1119 scb->tastat = 0;
1120 scb->cdblen = 6;
1121 scb->cdb[0] = SCSICMD_RequestSense;
1122 scb->cdb[1] = 0;
1123 scb->cdb[2] = 0;
1124 scb->cdb[3] = 0;
1125 scb->cdb[4] = len;
1126 scb->cdb[5] = 0;
1127 initio_push_pend_scb(host, scb);
1128 break;
1129 }
1130 }
1131 } else {
1132
1133 if (scb->tastat == 2) {
1134
1135 scb->hastat = HOST_BAD_PHAS;
1136 }
1137 scb->tastat = 2;
1138 }
1139 scb->flags |= SCF_DONE;
1140 if (scb->flags & SCF_POST) {
1141
1142 (*scb->post) ((u8 *) host, (u8 *) scb);
1143 }
1144 }
1145
1146 if (inb(host->addr + TUL_SStatus0) & TSS_INT_PENDING)
1147 continue;
1148 if (host->active)
1149 return 1;
1150
1151 if (initio_find_first_pend_scb(host) == NULL)
1152 return 1;
1153 }
1154
1155}
1156
1157static void tulip_scsi(struct initio_host * host)
1158{
1159 struct scsi_ctrl_blk *scb;
1160 struct target_control *active_tc;
1161
1162
1163 if ((host->jsstatus0 = inb(host->addr + TUL_SStatus0)) & TSS_INT_PENDING) {
1164 host->phase = host->jsstatus0 & TSS_PH_MASK;
1165 host->jsstatus1 = inb(host->addr + TUL_SStatus1);
1166 host->jsint = inb(host->addr + TUL_SInt);
1167 if (host->jsint & TSS_SCSIRST_INT) {
1168 int_initio_scsi_rst(host);
1169 return;
1170 }
1171 if (host->jsint & TSS_RESEL_INT) {
1172 if (int_initio_resel(host) == 0)
1173 initio_next_state(host);
1174 return;
1175 }
1176 if (host->jsint & TSS_SEL_TIMEOUT) {
1177 int_initio_busfree(host);
1178 return;
1179 }
1180 if (host->jsint & TSS_DISC_INT) {
1181 int_initio_busfree(host);
1182 return;
1183 }
1184 if (host->jsint & (TSS_FUNC_COMP | TSS_BUS_SERV)) {
1185 if ((scb = host->active) != NULL)
1186 initio_next_state(host);
1187 return;
1188 }
1189 }
1190 if (host->active != NULL)
1191 return;
1192
1193 if ((scb = initio_find_first_pend_scb(host)) == NULL)
1194 return;
1195
1196
1197 outb((host->scsi_id << 4) | (scb->target & 0x0F),
1198 host->addr + TUL_SScsiId);
1199 if (scb->opcode == ExecSCSI) {
1200 active_tc = &host->targets[scb->target];
1201
1202 if (scb->tagmsg)
1203 active_tc->drv_flags |= TCF_DRV_EN_TAG;
1204 else
1205 active_tc->drv_flags &= ~TCF_DRV_EN_TAG;
1206
1207 outb(active_tc->js_period, host->addr + TUL_SPeriod);
1208 if ((active_tc->flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {
1209 initio_select_atn_stop(host, scb);
1210 } else {
1211 if ((active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {
1212 initio_select_atn_stop(host, scb);
1213 } else {
1214 if (scb->tagmsg)
1215 initio_select_atn3(host, scb);
1216 else
1217 initio_select_atn(host, scb);
1218 }
1219 }
1220 if (scb->flags & SCF_POLL) {
1221 while (wait_tulip(host) != -1) {
1222 if (initio_next_state(host) == -1)
1223 break;
1224 }
1225 }
1226 } else if (scb->opcode == BusDevRst) {
1227 initio_select_atn_stop(host, scb);
1228 scb->next_state = 8;
1229 if (scb->flags & SCF_POLL) {
1230 while (wait_tulip(host) != -1) {
1231 if (initio_next_state(host) == -1)
1232 break;
1233 }
1234 }
1235 } else if (scb->opcode == AbortCmd) {
1236 if (initio_abort_srb(host, scb->srb) != 0) {
1237 initio_unlink_pend_scb(host, scb);
1238 initio_release_scb(host, scb);
1239 } else {
1240 scb->opcode = BusDevRst;
1241 initio_select_atn_stop(host, scb);
1242 scb->next_state = 8;
1243 }
1244 } else {
1245 initio_unlink_pend_scb(host, scb);
1246 scb->hastat = 0x16;
1247 initio_append_done_scb(host, scb);
1248 }
1249 return;
1250}
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262static int initio_next_state(struct initio_host * host)
1263{
1264 int next;
1265
1266 next = host->active->next_state;
1267 for (;;) {
1268 switch (next) {
1269 case 1:
1270 next = initio_state_1(host);
1271 break;
1272 case 2:
1273 next = initio_state_2(host);
1274 break;
1275 case 3:
1276 next = initio_state_3(host);
1277 break;
1278 case 4:
1279 next = initio_state_4(host);
1280 break;
1281 case 5:
1282 next = initio_state_5(host);
1283 break;
1284 case 6:
1285 next = initio_state_6(host);
1286 break;
1287 case 7:
1288 next = initio_state_7(host);
1289 break;
1290 case 8:
1291 return initio_bus_device_reset(host);
1292 default:
1293 return initio_bad_seq(host);
1294 }
1295 if (next <= 0)
1296 return next;
1297 }
1298}
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308static int initio_state_1(struct initio_host * host)
1309{
1310 struct scsi_ctrl_blk *scb = host->active;
1311 struct target_control *active_tc = host->active_tc;
1312#if DEBUG_STATE
1313 printk("-s1-");
1314#endif
1315
1316
1317 initio_unlink_pend_scb(host, scb);
1318 initio_append_busy_scb(host, scb);
1319
1320 outb(active_tc->sconfig0, host->addr + TUL_SConfig );
1321
1322 if (host->phase == MSG_OUT) {
1323 outb(TSC_EN_BUS_IN | TSC_HW_RESELECT, host->addr + TUL_SCtrl1);
1324 outb(scb->ident, host->addr + TUL_SFifo);
1325
1326 if (scb->tagmsg) {
1327 outb(scb->tagmsg, host->addr + TUL_SFifo);
1328 outb(scb->tagid, host->addr + TUL_SFifo);
1329 }
1330 if ((active_tc->flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {
1331 active_tc->flags |= TCF_WDTR_DONE;
1332 outb(MSG_EXTEND, host->addr + TUL_SFifo);
1333 outb(2, host->addr + TUL_SFifo);
1334 outb(3, host->addr + TUL_SFifo);
1335 outb(1, host->addr + TUL_SFifo);
1336 } else if ((active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {
1337 active_tc->flags |= TCF_SYNC_DONE;
1338 outb(MSG_EXTEND, host->addr + TUL_SFifo);
1339 outb(3, host->addr + TUL_SFifo);
1340 outb(1, host->addr + TUL_SFifo);
1341 outb(initio_rate_tbl[active_tc->flags & TCF_SCSI_RATE], host->addr + TUL_SFifo);
1342 outb(MAX_OFFSET, host->addr + TUL_SFifo);
1343 }
1344 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
1345 if (wait_tulip(host) == -1)
1346 return -1;
1347 }
1348 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
1349 outb((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)), host->addr + TUL_SSignal);
1350
1351 return 3;
1352}
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363static int initio_state_2(struct initio_host * host)
1364{
1365 struct scsi_ctrl_blk *scb = host->active;
1366 struct target_control *active_tc = host->active_tc;
1367#if DEBUG_STATE
1368 printk("-s2-");
1369#endif
1370
1371 initio_unlink_pend_scb(host, scb);
1372 initio_append_busy_scb(host, scb);
1373
1374 outb(active_tc->sconfig0, host->addr + TUL_SConfig);
1375
1376 if (host->jsstatus1 & TSS_CMD_PH_CMP)
1377 return 4;
1378
1379 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
1380 outb((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)), host->addr + TUL_SSignal);
1381
1382 return 3;
1383}
1384
1385
1386
1387
1388
1389
1390
1391
1392static int initio_state_3(struct initio_host * host)
1393{
1394 struct scsi_ctrl_blk *scb = host->active;
1395 struct target_control *active_tc = host->active_tc;
1396 int i;
1397
1398#if DEBUG_STATE
1399 printk("-s3-");
1400#endif
1401 for (;;) {
1402 switch (host->phase) {
1403 case CMD_OUT:
1404 for (i = 0; i < (int) scb->cdblen; i++)
1405 outb(scb->cdb[i], host->addr + TUL_SFifo);
1406 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
1407 if (wait_tulip(host) == -1)
1408 return -1;
1409 if (host->phase == CMD_OUT)
1410 return initio_bad_seq(host);
1411 return 4;
1412
1413 case MSG_IN:
1414 scb->next_state = 3;
1415 if (initio_msgin(host) == -1)
1416 return -1;
1417 break;
1418
1419 case STATUS_IN:
1420 if (initio_status_msg(host) == -1)
1421 return -1;
1422 break;
1423
1424 case MSG_OUT:
1425 if (active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) {
1426 outb(MSG_NOP, host->addr + TUL_SFifo);
1427 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
1428 if (wait_tulip(host) == -1)
1429 return -1;
1430 } else {
1431 active_tc->flags |= TCF_SYNC_DONE;
1432
1433 outb(MSG_EXTEND, host->addr + TUL_SFifo);
1434 outb(3, host->addr + TUL_SFifo);
1435 outb(1, host->addr + TUL_SFifo);
1436 outb(initio_rate_tbl[active_tc->flags & TCF_SCSI_RATE], host->addr + TUL_SFifo);
1437 outb(MAX_OFFSET, host->addr + TUL_SFifo);
1438 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
1439 if (wait_tulip(host) == -1)
1440 return -1;
1441 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
1442 outb(inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7), host->addr + TUL_SSignal);
1443
1444 }
1445 break;
1446 default:
1447 return initio_bad_seq(host);
1448 }
1449 }
1450}
1451
1452
1453
1454
1455
1456
1457
1458
1459static int initio_state_4(struct initio_host * host)
1460{
1461 struct scsi_ctrl_blk *scb = host->active;
1462
1463#if DEBUG_STATE
1464 printk("-s4-");
1465#endif
1466 if ((scb->flags & SCF_DIR) == SCF_NO_XF) {
1467 return 6;
1468 }
1469 for (;;) {
1470 if (scb->buflen == 0)
1471 return 6;
1472
1473 switch (host->phase) {
1474
1475 case STATUS_IN:
1476 if ((scb->flags & SCF_DIR) != 0)
1477 scb->hastat = HOST_DO_DU;
1478 if ((initio_status_msg(host)) == -1)
1479 return -1;
1480 break;
1481
1482 case MSG_IN:
1483 scb->next_state = 0x4;
1484 if (initio_msgin(host) == -1)
1485 return -1;
1486 break;
1487
1488 case MSG_OUT:
1489 if (host->jsstatus0 & TSS_PAR_ERROR) {
1490 scb->buflen = 0;
1491 scb->hastat = HOST_DO_DU;
1492 if (initio_msgout_ide(host) == -1)
1493 return -1;
1494 return 6;
1495 } else {
1496 outb(MSG_NOP, host->addr + TUL_SFifo);
1497 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
1498 if (wait_tulip(host) == -1)
1499 return -1;
1500 }
1501 break;
1502
1503 case DATA_IN:
1504 return initio_xfer_data_in(host);
1505
1506 case DATA_OUT:
1507 return initio_xfer_data_out(host);
1508
1509 default:
1510 return initio_bad_seq(host);
1511 }
1512 }
1513}
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523static int initio_state_5(struct initio_host * host)
1524{
1525 struct scsi_ctrl_blk *scb = host->active;
1526 long cnt, xcnt;
1527
1528#if DEBUG_STATE
1529 printk("-s5-");
1530#endif
1531
1532 cnt = inl(host->addr + TUL_SCnt0) & 0x0FFFFFF;
1533
1534 if (inb(host->addr + TUL_XCmd) & 0x20) {
1535
1536
1537 if (host->jsstatus0 & TSS_PAR_ERROR)
1538 scb->hastat = HOST_DO_DU;
1539 if (inb(host->addr + TUL_XStatus) & XPEND) {
1540
1541 outb(inb(host->addr + TUL_XCtrl) | 0x80, host->addr + TUL_XCtrl);
1542
1543 while (inb(host->addr + TUL_XStatus) & XPEND)
1544 cpu_relax();
1545 }
1546 } else {
1547
1548 if ((inb(host->addr + TUL_SStatus1) & TSS_XFER_CMP) == 0) {
1549 if (host->active_tc->js_period & TSC_WIDE_SCSI)
1550 cnt += (inb(host->addr + TUL_SFifoCnt) & 0x1F) << 1;
1551 else
1552 cnt += (inb(host->addr + TUL_SFifoCnt) & 0x1F);
1553 }
1554 if (inb(host->addr + TUL_XStatus) & XPEND) {
1555 outb(TAX_X_ABT, host->addr + TUL_XCmd);
1556
1557 while ((inb(host->addr + TUL_Int) & XABT) == 0)
1558 cpu_relax();
1559 }
1560 if ((cnt == 1) && (host->phase == DATA_OUT)) {
1561 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
1562 if (wait_tulip(host) == -1)
1563 return -1;
1564 cnt = 0;
1565 } else {
1566 if ((inb(host->addr + TUL_SStatus1) & TSS_XFER_CMP) == 0)
1567 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
1568 }
1569 }
1570 if (cnt == 0) {
1571 scb->buflen = 0;
1572 return 6;
1573 }
1574
1575 xcnt = (long) scb->buflen - cnt;
1576 scb->buflen = (u32) cnt;
1577 if (scb->flags & SCF_SG) {
1578 struct sg_entry *sgp;
1579 unsigned long i;
1580
1581 sgp = &scb->sglist[scb->sgidx];
1582 for (i = scb->sgidx; i < scb->sgmax; sgp++, i++) {
1583 xcnt -= (long) sgp->len;
1584 if (xcnt < 0) {
1585 xcnt += (long) sgp->len;
1586 sgp->data += (u32) xcnt;
1587 sgp->len -= (u32) xcnt;
1588 scb->bufptr += ((u32) (i - scb->sgidx) << 3);
1589
1590 scb->sglen = (u8) (scb->sgmax - i);
1591
1592 scb->sgidx = (u16) i;
1593
1594 return 4;
1595 }
1596
1597 }
1598 return 6;
1599 } else {
1600 scb->bufptr += (u32) xcnt;
1601 }
1602 return 4;
1603}
1604
1605
1606
1607
1608
1609
1610
1611
1612static int initio_state_6(struct initio_host * host)
1613{
1614 struct scsi_ctrl_blk *scb = host->active;
1615
1616#if DEBUG_STATE
1617 printk("-s6-");
1618#endif
1619 for (;;) {
1620 switch (host->phase) {
1621 case STATUS_IN:
1622 if ((initio_status_msg(host)) == -1)
1623 return -1;
1624 break;
1625
1626 case MSG_IN:
1627 scb->next_state = 6;
1628 if ((initio_msgin(host)) == -1)
1629 return -1;
1630 break;
1631
1632 case MSG_OUT:
1633 outb(MSG_NOP, host->addr + TUL_SFifo);
1634 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
1635 if (wait_tulip(host) == -1)
1636 return -1;
1637 break;
1638
1639 case DATA_IN:
1640 return initio_xpad_in(host);
1641
1642 case DATA_OUT:
1643 return initio_xpad_out(host);
1644
1645 default:
1646 return initio_bad_seq(host);
1647 }
1648 }
1649}
1650
1651
1652
1653
1654
1655
1656
1657int initio_state_7(struct initio_host * host)
1658{
1659 int cnt, i;
1660
1661#if DEBUG_STATE
1662 printk("-s7-");
1663#endif
1664
1665 cnt = inb(host->addr + TUL_SFifoCnt) & 0x1F;
1666 if (cnt) {
1667 for (i = 0; i < cnt; i++)
1668 inb(host->addr + TUL_SFifo);
1669 }
1670 switch (host->phase) {
1671 case DATA_IN:
1672 case DATA_OUT:
1673 return initio_bad_seq(host);
1674 default:
1675 return 6;
1676 }
1677}
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687static int initio_xfer_data_in(struct initio_host * host)
1688{
1689 struct scsi_ctrl_blk *scb = host->active;
1690
1691 if ((scb->flags & SCF_DIR) == SCF_DOUT)
1692 return 6;
1693
1694 outl(scb->buflen, host->addr + TUL_SCnt0);
1695 outb(TSC_XF_DMA_IN, host->addr + TUL_SCmd);
1696
1697 if (scb->flags & SCF_SG) {
1698 outl(((u32) scb->sglen) << 3, host->addr + TUL_XCntH);
1699 outl(scb->bufptr, host->addr + TUL_XAddH);
1700 outb(TAX_SG_IN, host->addr + TUL_XCmd);
1701 } else {
1702 outl(scb->buflen, host->addr + TUL_XCntH);
1703 outl(scb->bufptr, host->addr + TUL_XAddH);
1704 outb(TAX_X_IN, host->addr + TUL_XCmd);
1705 }
1706 scb->next_state = 0x5;
1707 return 0;
1708}
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719static int initio_xfer_data_out(struct initio_host * host)
1720{
1721 struct scsi_ctrl_blk *scb = host->active;
1722
1723 if ((scb->flags & SCF_DIR) == SCF_DIN)
1724 return 6;
1725
1726 outl(scb->buflen, host->addr + TUL_SCnt0);
1727 outb(TSC_XF_DMA_OUT, host->addr + TUL_SCmd);
1728
1729 if (scb->flags & SCF_SG) {
1730 outl(((u32) scb->sglen) << 3, host->addr + TUL_XCntH);
1731 outl(scb->bufptr, host->addr + TUL_XAddH);
1732 outb(TAX_SG_OUT, host->addr + TUL_XCmd);
1733 } else {
1734 outl(scb->buflen, host->addr + TUL_XCntH);
1735 outl(scb->bufptr, host->addr + TUL_XAddH);
1736 outb(TAX_X_OUT, host->addr + TUL_XCmd);
1737 }
1738
1739 scb->next_state = 0x5;
1740 return 0;
1741}
1742
1743int initio_xpad_in(struct initio_host * host)
1744{
1745 struct scsi_ctrl_blk *scb = host->active;
1746 struct target_control *active_tc = host->active_tc;
1747
1748 if ((scb->flags & SCF_DIR) != SCF_NO_DCHK)
1749 scb->hastat = HOST_DO_DU;
1750 for (;;) {
1751 if (active_tc->js_period & TSC_WIDE_SCSI)
1752 outl(2, host->addr + TUL_SCnt0);
1753 else
1754 outl(1, host->addr + TUL_SCnt0);
1755
1756 outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
1757 if (wait_tulip(host) == -1)
1758 return -1;
1759 if (host->phase != DATA_IN) {
1760 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
1761 return 6;
1762 }
1763 inb(host->addr + TUL_SFifo);
1764 }
1765}
1766
1767int initio_xpad_out(struct initio_host * host)
1768{
1769 struct scsi_ctrl_blk *scb = host->active;
1770 struct target_control *active_tc = host->active_tc;
1771
1772 if ((scb->flags & SCF_DIR) != SCF_NO_DCHK)
1773 scb->hastat = HOST_DO_DU;
1774 for (;;) {
1775 if (active_tc->js_period & TSC_WIDE_SCSI)
1776 outl(2, host->addr + TUL_SCnt0);
1777 else
1778 outl(1, host->addr + TUL_SCnt0);
1779
1780 outb(0, host->addr + TUL_SFifo);
1781 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
1782 if ((wait_tulip(host)) == -1)
1783 return -1;
1784 if (host->phase != DATA_OUT) {
1785 outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1);
1786 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
1787 return 6;
1788 }
1789 }
1790}
1791
1792int initio_status_msg(struct initio_host * host)
1793{
1794 struct scsi_ctrl_blk *scb = host->active;
1795 u8 msg;
1796
1797 outb(TSC_CMD_COMP, host->addr + TUL_SCmd);
1798 if (wait_tulip(host) == -1)
1799 return -1;
1800
1801
1802 scb->tastat = inb(host->addr + TUL_SFifo);
1803
1804 if (host->phase == MSG_OUT) {
1805 if (host->jsstatus0 & TSS_PAR_ERROR)
1806 outb(MSG_PARITY, host->addr + TUL_SFifo);
1807 else
1808 outb(MSG_NOP, host->addr + TUL_SFifo);
1809 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
1810 return wait_tulip(host);
1811 }
1812 if (host->phase == MSG_IN) {
1813 msg = inb(host->addr + TUL_SFifo);
1814 if (host->jsstatus0 & TSS_PAR_ERROR) {
1815 if ((initio_msgin_accept(host)) == -1)
1816 return -1;
1817 if (host->phase != MSG_OUT)
1818 return initio_bad_seq(host);
1819 outb(MSG_PARITY, host->addr + TUL_SFifo);
1820 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
1821 return wait_tulip(host);
1822 }
1823 if (msg == 0) {
1824
1825 if ((scb->tastat & 0x18) == 0x10)
1826 return initio_bad_seq(host);
1827 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
1828 outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
1829 return initio_wait_done_disc(host);
1830
1831 }
1832 if (msg == MSG_LINK_COMP || msg == MSG_LINK_FLAG) {
1833 if ((scb->tastat & 0x18) == 0x10)
1834 return initio_msgin_accept(host);
1835 }
1836 }
1837 return initio_bad_seq(host);
1838}
1839
1840
1841
1842int int_initio_busfree(struct initio_host * host)
1843{
1844 struct scsi_ctrl_blk *scb = host->active;
1845
1846 if (scb != NULL) {
1847 if (scb->status & SCB_SELECT) {
1848 initio_unlink_pend_scb(host, scb);
1849 scb->hastat = HOST_SEL_TOUT;
1850 initio_append_done_scb(host, scb);
1851 } else {
1852 initio_unlink_busy_scb(host, scb);
1853 scb->hastat = HOST_BUS_FREE;
1854 initio_append_done_scb(host, scb);
1855 }
1856 host->active = NULL;
1857 host->active_tc = NULL;
1858 }
1859 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
1860 outb(TSC_INITDEFAULT, host->addr + TUL_SConfig);
1861 outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1);
1862 return -1;
1863}
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876static int int_initio_scsi_rst(struct initio_host * host)
1877{
1878 struct scsi_ctrl_blk *scb;
1879 int i;
1880
1881
1882 if (inb(host->addr + TUL_XStatus) & 0x01) {
1883 outb(TAX_X_ABT | TAX_X_CLR_FIFO, host->addr + TUL_XCmd);
1884
1885 while ((inb(host->addr + TUL_Int) & 0x04) == 0)
1886 cpu_relax();
1887 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
1888 }
1889
1890 while ((scb = initio_pop_busy_scb(host)) != NULL) {
1891 scb->hastat = HOST_BAD_PHAS;
1892 initio_append_done_scb(host, scb);
1893 }
1894 host->active = NULL;
1895 host->active_tc = NULL;
1896
1897
1898 for (i = 0; i < host->max_tar; i++)
1899 host->targets[i].flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
1900 return -1;
1901}
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912int int_initio_resel(struct initio_host * host)
1913{
1914 struct scsi_ctrl_blk *scb;
1915 struct target_control *active_tc;
1916 u8 tag, msg = 0;
1917 u8 tar, lun;
1918
1919 if ((scb = host->active) != NULL) {
1920
1921 if (scb->status & SCB_SELECT)
1922 scb->status &= ~SCB_SELECT;
1923 host->active = NULL;
1924 }
1925
1926 tar = inb(host->addr + TUL_SBusId);
1927
1928 lun = inb(host->addr + TUL_SIdent) & 0x0F;
1929
1930 active_tc = &host->targets[tar];
1931 host->active_tc = active_tc;
1932 outb(active_tc->sconfig0, host->addr + TUL_SConfig);
1933 outb(active_tc->js_period, host->addr + TUL_SPeriod);
1934
1935
1936 if (active_tc->drv_flags & TCF_DRV_EN_TAG) {
1937 if ((initio_msgin_accept(host)) == -1)
1938 return -1;
1939 if (host->phase != MSG_IN)
1940 goto no_tag;
1941 outl(1, host->addr + TUL_SCnt0);
1942 outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
1943 if (wait_tulip(host) == -1)
1944 return -1;
1945 msg = inb(host->addr + TUL_SFifo);
1946
1947 if (msg < MSG_STAG || msg > MSG_OTAG)
1948 goto no_tag;
1949
1950 if (initio_msgin_accept(host) == -1)
1951 return -1;
1952
1953 if (host->phase != MSG_IN)
1954 goto no_tag;
1955
1956 outl(1, host->addr + TUL_SCnt0);
1957 outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
1958 if (wait_tulip(host) == -1)
1959 return -1;
1960 tag = inb(host->addr + TUL_SFifo);
1961 scb = host->scb + tag;
1962 if (scb->target != tar || scb->lun != lun) {
1963 return initio_msgout_abort_tag(host);
1964 }
1965 if (scb->status != SCB_BUSY) {
1966 return initio_msgout_abort_tag(host);
1967 }
1968 host->active = scb;
1969 if ((initio_msgin_accept(host)) == -1)
1970 return -1;
1971 } else {
1972 no_tag:
1973 if ((scb = initio_find_busy_scb(host, tar | (lun << 8))) == NULL) {
1974 return initio_msgout_abort_targ(host);
1975 }
1976 host->active = scb;
1977 if (!(active_tc->drv_flags & TCF_DRV_EN_TAG)) {
1978 if ((initio_msgin_accept(host)) == -1)
1979 return -1;
1980 }
1981 }
1982 return 0;
1983}
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993static int int_initio_bad_seq(struct initio_host * host)
1994{
1995 struct scsi_ctrl_blk *scb;
1996 int i;
1997
1998 initio_reset_scsi(host, 10);
1999
2000 while ((scb = initio_pop_busy_scb(host)) != NULL) {
2001 scb->hastat = HOST_BAD_PHAS;
2002 initio_append_done_scb(host, scb);
2003 }
2004 for (i = 0; i < host->max_tar; i++)
2005 host->targets[i].flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
2006 return -1;
2007}
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018static int initio_msgout_abort_targ(struct initio_host * host)
2019{
2020
2021 outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN), host->addr + TUL_SSignal);
2022 if (initio_msgin_accept(host) == -1)
2023 return -1;
2024 if (host->phase != MSG_OUT)
2025 return initio_bad_seq(host);
2026
2027 outb(MSG_ABORT, host->addr + TUL_SFifo);
2028 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
2029
2030 return initio_wait_disc(host);
2031}
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041static int initio_msgout_abort_tag(struct initio_host * host)
2042{
2043
2044 outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN), host->addr + TUL_SSignal);
2045 if (initio_msgin_accept(host) == -1)
2046 return -1;
2047 if (host->phase != MSG_OUT)
2048 return initio_bad_seq(host);
2049
2050 outb(MSG_ABORT_TAG, host->addr + TUL_SFifo);
2051 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
2052
2053 return initio_wait_disc(host);
2054
2055}
2056
2057
2058
2059
2060
2061
2062
2063static int initio_msgin(struct initio_host * host)
2064{
2065 struct target_control *active_tc;
2066
2067 for (;;) {
2068 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
2069
2070 outl(1, host->addr + TUL_SCnt0);
2071 outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
2072 if (wait_tulip(host) == -1)
2073 return -1;
2074
2075 switch (inb(host->addr + TUL_SFifo)) {
2076 case MSG_DISC:
2077 outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
2078 return initio_wait_disc(host);
2079 case MSG_SDP:
2080 case MSG_RESTORE:
2081 case MSG_NOP:
2082 initio_msgin_accept(host);
2083 break;
2084 case MSG_REJ:
2085 outb((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)),
2086 host->addr + TUL_SSignal);
2087 active_tc = host->active_tc;
2088 if ((active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0)
2089 outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN),
2090 host->addr + TUL_SSignal);
2091 initio_msgin_accept(host);
2092 break;
2093 case MSG_EXTEND:
2094 initio_msgin_extend(host);
2095 break;
2096 case MSG_IGNOREWIDE:
2097 initio_msgin_accept(host);
2098 break;
2099 case MSG_COMP:
2100 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
2101 outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
2102 return initio_wait_done_disc(host);
2103 default:
2104 initio_msgout_reject(host);
2105 break;
2106 }
2107 if (host->phase != MSG_IN)
2108 return host->phase;
2109 }
2110
2111}
2112
2113static int initio_msgout_reject(struct initio_host * host)
2114{
2115 outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN), host->addr + TUL_SSignal);
2116
2117 if (initio_msgin_accept(host) == -1)
2118 return -1;
2119
2120 if (host->phase == MSG_OUT) {
2121 outb(MSG_REJ, host->addr + TUL_SFifo);
2122 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
2123 return wait_tulip(host);
2124 }
2125 return host->phase;
2126}
2127
2128static int initio_msgout_ide(struct initio_host * host)
2129{
2130 outb(MSG_IDE, host->addr + TUL_SFifo);
2131 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
2132 return wait_tulip(host);
2133}
2134
2135static int initio_msgin_extend(struct initio_host * host)
2136{
2137 u8 len, idx;
2138
2139 if (initio_msgin_accept(host) != MSG_IN)
2140 return host->phase;
2141
2142
2143 outl(1, host->addr + TUL_SCnt0);
2144 outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
2145 if (wait_tulip(host) == -1)
2146 return -1;
2147
2148 len = inb(host->addr + TUL_SFifo);
2149 host->msg[0] = len;
2150 for (idx = 1; len != 0; len--) {
2151
2152 if ((initio_msgin_accept(host)) != MSG_IN)
2153 return host->phase;
2154 outl(1, host->addr + TUL_SCnt0);
2155 outb(TSC_XF_FIFO_IN, host->addr + TUL_SCmd);
2156 if (wait_tulip(host) == -1)
2157 return -1;
2158 host->msg[idx++] = inb(host->addr + TUL_SFifo);
2159 }
2160 if (host->msg[1] == 1) {
2161 u8 r;
2162 if (host->msg[0] != 3)
2163 return initio_msgout_reject(host);
2164 if (host->active_tc->flags & TCF_NO_SYNC_NEGO) {
2165 host->msg[3] = 0;
2166 } else {
2167 if (initio_msgin_sync(host) == 0 &&
2168 (host->active_tc->flags & TCF_SYNC_DONE)) {
2169 initio_sync_done(host);
2170 return initio_msgin_accept(host);
2171 }
2172 }
2173
2174 r = inb(host->addr + TUL_SSignal);
2175 outb((r & (TSC_SET_ACK | 7)) | TSC_SET_ATN,
2176 host->addr + TUL_SSignal);
2177 if (initio_msgin_accept(host) != MSG_OUT)
2178 return host->phase;
2179
2180 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
2181
2182 initio_sync_done(host);
2183
2184 outb(MSG_EXTEND, host->addr + TUL_SFifo);
2185 outb(3, host->addr + TUL_SFifo);
2186 outb(1, host->addr + TUL_SFifo);
2187 outb(host->msg[2], host->addr + TUL_SFifo);
2188 outb(host->msg[3], host->addr + TUL_SFifo);
2189 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
2190 return wait_tulip(host);
2191 }
2192 if (host->msg[0] != 2 || host->msg[1] != 3)
2193 return initio_msgout_reject(host);
2194
2195 if (host->active_tc->flags & TCF_NO_WDTR) {
2196 host->msg[2] = 0;
2197 } else {
2198 if (host->msg[2] > 2)
2199 return initio_msgout_reject(host);
2200 if (host->msg[2] == 2) {
2201 host->msg[2] = 1;
2202 } else {
2203 if ((host->active_tc->flags & TCF_NO_WDTR) == 0) {
2204 wdtr_done(host);
2205 if ((host->active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0)
2206 outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN), host->addr + TUL_SSignal);
2207 return initio_msgin_accept(host);
2208 }
2209 }
2210 }
2211 outb(((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN), host->addr + TUL_SSignal);
2212
2213 if (initio_msgin_accept(host) != MSG_OUT)
2214 return host->phase;
2215
2216 outb(MSG_EXTEND, host->addr + TUL_SFifo);
2217 outb(2, host->addr + TUL_SFifo);
2218 outb(3, host->addr + TUL_SFifo);
2219 outb(host->msg[2], host->addr + TUL_SFifo);
2220 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
2221 return wait_tulip(host);
2222}
2223
2224static int initio_msgin_sync(struct initio_host * host)
2225{
2226 char default_period;
2227
2228 default_period = initio_rate_tbl[host->active_tc->flags & TCF_SCSI_RATE];
2229 if (host->msg[3] > MAX_OFFSET) {
2230 host->msg[3] = MAX_OFFSET;
2231 if (host->msg[2] < default_period) {
2232 host->msg[2] = default_period;
2233 return 1;
2234 }
2235 if (host->msg[2] >= 59)
2236 host->msg[3] = 0;
2237 return 1;
2238 }
2239
2240 if (host->msg[3] == 0) {
2241 return 0;
2242 }
2243 if (host->msg[2] < default_period) {
2244 host->msg[2] = default_period;
2245 return 1;
2246 }
2247 if (host->msg[2] >= 59) {
2248 host->msg[3] = 0;
2249 return 1;
2250 }
2251 return 0;
2252}
2253
2254static int wdtr_done(struct initio_host * host)
2255{
2256 host->active_tc->flags &= ~TCF_SYNC_DONE;
2257 host->active_tc->flags |= TCF_WDTR_DONE;
2258
2259 host->active_tc->js_period = 0;
2260 if (host->msg[2])
2261 host->active_tc->js_period |= TSC_WIDE_SCSI;
2262 host->active_tc->sconfig0 &= ~TSC_ALT_PERIOD;
2263 outb(host->active_tc->sconfig0, host->addr + TUL_SConfig);
2264 outb(host->active_tc->js_period, host->addr + TUL_SPeriod);
2265
2266 return 1;
2267}
2268
2269static int initio_sync_done(struct initio_host * host)
2270{
2271 int i;
2272
2273 host->active_tc->flags |= TCF_SYNC_DONE;
2274
2275 if (host->msg[3]) {
2276 host->active_tc->js_period |= host->msg[3];
2277 for (i = 0; i < 8; i++) {
2278 if (initio_rate_tbl[i] >= host->msg[2])
2279 break;
2280 }
2281 host->active_tc->js_period |= (i << 4);
2282 host->active_tc->sconfig0 |= TSC_ALT_PERIOD;
2283 }
2284 outb(host->active_tc->sconfig0, host->addr + TUL_SConfig);
2285 outb(host->active_tc->js_period, host->addr + TUL_SPeriod);
2286
2287 return -1;
2288}
2289
2290
2291static int initio_post_scsi_rst(struct initio_host * host)
2292{
2293 struct scsi_ctrl_blk *scb;
2294 struct target_control *active_tc;
2295 int i;
2296
2297 host->active = NULL;
2298 host->active_tc = NULL;
2299 host->flags = 0;
2300
2301 while ((scb = initio_pop_busy_scb(host)) != NULL) {
2302 scb->hastat = HOST_BAD_PHAS;
2303 initio_append_done_scb(host, scb);
2304 }
2305
2306 active_tc = &host->targets[0];
2307 for (i = 0; i < host->max_tar; active_tc++, i++) {
2308 active_tc->flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
2309
2310 active_tc->js_period = 0;
2311 active_tc->sconfig0 = host->sconf1;
2312 host->act_tags[0] = 0;
2313 host->targets[i].flags &= ~TCF_BUSY;
2314 }
2315
2316 return -1;
2317}
2318
2319static void initio_select_atn_stop(struct initio_host * host, struct scsi_ctrl_blk * scb)
2320{
2321 scb->status |= SCB_SELECT;
2322 scb->next_state = 0x1;
2323 host->active = scb;
2324 host->active_tc = &host->targets[scb->target];
2325 outb(TSC_SELATNSTOP, host->addr + TUL_SCmd);
2326}
2327
2328
2329static void initio_select_atn(struct initio_host * host, struct scsi_ctrl_blk * scb)
2330{
2331 int i;
2332
2333 scb->status |= SCB_SELECT;
2334 scb->next_state = 0x2;
2335
2336 outb(scb->ident, host->addr + TUL_SFifo);
2337 for (i = 0; i < (int) scb->cdblen; i++)
2338 outb(scb->cdb[i], host->addr + TUL_SFifo);
2339 host->active_tc = &host->targets[scb->target];
2340 host->active = scb;
2341 outb(TSC_SEL_ATN, host->addr + TUL_SCmd);
2342}
2343
2344static void initio_select_atn3(struct initio_host * host, struct scsi_ctrl_blk * scb)
2345{
2346 int i;
2347
2348 scb->status |= SCB_SELECT;
2349 scb->next_state = 0x2;
2350
2351 outb(scb->ident, host->addr + TUL_SFifo);
2352 outb(scb->tagmsg, host->addr + TUL_SFifo);
2353 outb(scb->tagid, host->addr + TUL_SFifo);
2354 for (i = 0; i < scb->cdblen; i++)
2355 outb(scb->cdb[i], host->addr + TUL_SFifo);
2356 host->active_tc = &host->targets[scb->target];
2357 host->active = scb;
2358 outb(TSC_SEL_ATN3, host->addr + TUL_SCmd);
2359}
2360
2361
2362
2363
2364
2365
2366
2367
2368int initio_bus_device_reset(struct initio_host * host)
2369{
2370 struct scsi_ctrl_blk *scb = host->active;
2371 struct target_control *active_tc = host->active_tc;
2372 struct scsi_ctrl_blk *tmp, *prev;
2373 u8 tar;
2374
2375 if (host->phase != MSG_OUT)
2376 return int_initio_bad_seq(host);
2377
2378 initio_unlink_pend_scb(host, scb);
2379 initio_release_scb(host, scb);
2380
2381
2382 tar = scb->target;
2383 active_tc->flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE | TCF_BUSY);
2384
2385
2386
2387 prev = tmp = host->first_busy;
2388 while (tmp != NULL) {
2389 if (tmp->target == tar) {
2390
2391 if (tmp == host->first_busy) {
2392 if ((host->first_busy = tmp->next) == NULL)
2393 host->last_busy = NULL;
2394 } else {
2395 prev->next = tmp->next;
2396 if (tmp == host->last_busy)
2397 host->last_busy = prev;
2398 }
2399 tmp->hastat = HOST_ABORTED;
2400 initio_append_done_scb(host, tmp);
2401 }
2402
2403 else {
2404 prev = tmp;
2405 }
2406 tmp = tmp->next;
2407 }
2408 outb(MSG_DEVRST, host->addr + TUL_SFifo);
2409 outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
2410 return initio_wait_disc(host);
2411
2412}
2413
2414static int initio_msgin_accept(struct initio_host * host)
2415{
2416 outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
2417 return wait_tulip(host);
2418}
2419
2420static int wait_tulip(struct initio_host * host)
2421{
2422
2423 while (!((host->jsstatus0 = inb(host->addr + TUL_SStatus0))
2424 & TSS_INT_PENDING))
2425 cpu_relax();
2426
2427 host->jsint = inb(host->addr + TUL_SInt);
2428 host->phase = host->jsstatus0 & TSS_PH_MASK;
2429 host->jsstatus1 = inb(host->addr + TUL_SStatus1);
2430
2431 if (host->jsint & TSS_RESEL_INT)
2432 return int_initio_resel(host);
2433 if (host->jsint & TSS_SEL_TIMEOUT)
2434 return int_initio_busfree(host);
2435 if (host->jsint & TSS_SCSIRST_INT)
2436 return int_initio_scsi_rst(host);
2437
2438 if (host->jsint & TSS_DISC_INT) {
2439 if (host->flags & HCF_EXPECT_DONE_DISC) {
2440 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
2441 initio_unlink_busy_scb(host, host->active);
2442 host->active->hastat = 0;
2443 initio_append_done_scb(host, host->active);
2444 host->active = NULL;
2445 host->active_tc = NULL;
2446 host->flags &= ~HCF_EXPECT_DONE_DISC;
2447 outb(TSC_INITDEFAULT, host->addr + TUL_SConfig);
2448 outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1);
2449 return -1;
2450 }
2451 if (host->flags & HCF_EXPECT_DISC) {
2452 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
2453 host->active = NULL;
2454 host->active_tc = NULL;
2455 host->flags &= ~HCF_EXPECT_DISC;
2456 outb(TSC_INITDEFAULT, host->addr + TUL_SConfig);
2457 outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1);
2458 return -1;
2459 }
2460 return int_initio_busfree(host);
2461 }
2462
2463 if (host->jsint & (TSS_FUNC_COMP | TSS_BUS_SERV))
2464 return host->phase;
2465 return host->phase;
2466}
2467
2468static int initio_wait_disc(struct initio_host * host)
2469{
2470 while (!((host->jsstatus0 = inb(host->addr + TUL_SStatus0)) & TSS_INT_PENDING))
2471 cpu_relax();
2472
2473 host->jsint = inb(host->addr + TUL_SInt);
2474
2475 if (host->jsint & TSS_SCSIRST_INT)
2476 return int_initio_scsi_rst(host);
2477 if (host->jsint & TSS_DISC_INT) {
2478 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
2479 outb(TSC_INITDEFAULT, host->addr + TUL_SConfig);
2480 outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1);
2481 host->active = NULL;
2482 return -1;
2483 }
2484 return initio_bad_seq(host);
2485}
2486
2487static int initio_wait_done_disc(struct initio_host * host)
2488{
2489 while (!((host->jsstatus0 = inb(host->addr + TUL_SStatus0))
2490 & TSS_INT_PENDING))
2491 cpu_relax();
2492
2493 host->jsint = inb(host->addr + TUL_SInt);
2494
2495 if (host->jsint & TSS_SCSIRST_INT)
2496 return int_initio_scsi_rst(host);
2497 if (host->jsint & TSS_DISC_INT) {
2498 outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
2499 outb(TSC_INITDEFAULT, host->addr + TUL_SConfig);
2500 outb(TSC_HW_RESELECT, host->addr + TUL_SCtrl1);
2501 initio_unlink_busy_scb(host, host->active);
2502
2503 initio_append_done_scb(host, host->active);
2504 host->active = NULL;
2505 return -1;
2506 }
2507 return initio_bad_seq(host);
2508}
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519static irqreturn_t i91u_intr(int irqno, void *dev_id)
2520{
2521 struct Scsi_Host *dev = dev_id;
2522 unsigned long flags;
2523 int r;
2524
2525 spin_lock_irqsave(dev->host_lock, flags);
2526 r = initio_isr((struct initio_host *)dev->hostdata);
2527 spin_unlock_irqrestore(dev->host_lock, flags);
2528 if (r)
2529 return IRQ_HANDLED;
2530 else
2531 return IRQ_NONE;
2532}
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * cblk, struct scsi_cmnd * cmnd)
2547{
2548 struct scatterlist *sglist;
2549 struct sg_entry *sg;
2550 int i, nseg;
2551 long total_len;
2552 dma_addr_t dma_addr;
2553
2554
2555 cblk->post = i91uSCBPost;
2556 cblk->srb = cmnd;
2557 cblk->opcode = ExecSCSI;
2558 cblk->flags = SCF_POST;
2559 cblk->target = cmnd->device->id;
2560 cblk->lun = cmnd->device->lun;
2561 cblk->ident = cmnd->device->lun | DISC_ALLOW;
2562
2563 cblk->flags |= SCF_SENSE;
2564
2565
2566 dma_addr = dma_map_single(&host->pci_dev->dev, cmnd->sense_buffer,
2567 SENSE_SIZE, DMA_FROM_DEVICE);
2568 cblk->senseptr = (u32)dma_addr;
2569 cblk->senselen = SENSE_SIZE;
2570 cmnd->SCp.ptr = (char *)(unsigned long)dma_addr;
2571 cblk->cdblen = cmnd->cmd_len;
2572
2573
2574 cblk->hastat = 0;
2575 cblk->tastat = 0;
2576
2577 memcpy(cblk->cdb, cmnd->cmnd, cmnd->cmd_len);
2578
2579
2580 if (cmnd->device->tagged_supported) {
2581 cblk->tagmsg = SIMPLE_QUEUE_TAG;
2582 } else {
2583 cblk->tagmsg = 0;
2584 }
2585
2586
2587 nseg = scsi_dma_map(cmnd);
2588 BUG_ON(nseg < 0);
2589 if (nseg) {
2590 dma_addr = dma_map_single(&host->pci_dev->dev, &cblk->sglist[0],
2591 sizeof(struct sg_entry) * TOTAL_SG_ENTRY,
2592 DMA_BIDIRECTIONAL);
2593 cblk->bufptr = (u32)dma_addr;
2594 cmnd->SCp.dma_handle = dma_addr;
2595
2596 cblk->sglen = nseg;
2597
2598 cblk->flags |= SCF_SG;
2599 total_len = 0;
2600 sg = &cblk->sglist[0];
2601 scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) {
2602 sg->data = cpu_to_le32((u32)sg_dma_address(sglist));
2603 sg->len = cpu_to_le32((u32)sg_dma_len(sglist));
2604 total_len += sg_dma_len(sglist);
2605 ++sg;
2606 }
2607
2608 cblk->buflen = (scsi_bufflen(cmnd) > total_len) ?
2609 total_len : scsi_bufflen(cmnd);
2610 } else {
2611 cblk->buflen = 0;
2612 cblk->sglen = 0;
2613 }
2614}
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626static int i91u_queuecommand_lck(struct scsi_cmnd *cmd,
2627 void (*done)(struct scsi_cmnd *))
2628{
2629 struct initio_host *host = (struct initio_host *) cmd->device->host->hostdata;
2630 struct scsi_ctrl_blk *cmnd;
2631
2632 cmd->scsi_done = done;
2633
2634 cmnd = initio_alloc_scb(host);
2635 if (!cmnd)
2636 return SCSI_MLQUEUE_HOST_BUSY;
2637
2638 initio_build_scb(host, cmnd, cmd);
2639 initio_exec_scb(host, cmnd);
2640 return 0;
2641}
2642
2643static DEF_SCSI_QCMD(i91u_queuecommand)
2644
2645
2646
2647
2648
2649
2650
2651
2652static int i91u_bus_reset(struct scsi_cmnd * cmnd)
2653{
2654 struct initio_host *host;
2655
2656 host = (struct initio_host *) cmnd->device->host->hostdata;
2657
2658 spin_lock_irq(cmnd->device->host->host_lock);
2659 initio_reset_scsi(host, 0);
2660 spin_unlock_irq(cmnd->device->host->host_lock);
2661
2662 return SUCCESS;
2663}
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678static int i91u_biosparam(struct scsi_device *sdev, struct block_device *dev,
2679 sector_t capacity, int *info_array)
2680{
2681 struct initio_host *host;
2682 struct target_control *tc;
2683
2684 host = (struct initio_host *) sdev->host->hostdata;
2685 tc = &host->targets[sdev->id];
2686
2687 if (tc->heads) {
2688 info_array[0] = tc->heads;
2689 info_array[1] = tc->sectors;
2690 info_array[2] = (unsigned long)capacity / tc->heads / tc->sectors;
2691 } else {
2692 if (tc->drv_flags & TCF_DRV_255_63) {
2693 info_array[0] = 255;
2694 info_array[1] = 63;
2695 info_array[2] = (unsigned long)capacity / 255 / 63;
2696 } else {
2697 info_array[0] = 64;
2698 info_array[1] = 32;
2699 info_array[2] = (unsigned long)capacity >> 11;
2700 }
2701 }
2702
2703#if defined(DEBUG_BIOSPARAM)
2704 if (i91u_debug & debug_biosparam) {
2705 printk("bios geometry: head=%d, sec=%d, cyl=%d\n",
2706 info_array[0], info_array[1], info_array[2]);
2707 printk("WARNING: check, if the bios geometry is correct.\n");
2708 }
2709#endif
2710
2711 return 0;
2712}
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723static void i91u_unmap_scb(struct pci_dev *pci_dev, struct scsi_cmnd *cmnd)
2724{
2725
2726 if (cmnd->SCp.ptr) {
2727 dma_unmap_single(&pci_dev->dev,
2728 (dma_addr_t)((unsigned long)cmnd->SCp.ptr),
2729 SENSE_SIZE, DMA_FROM_DEVICE);
2730 cmnd->SCp.ptr = NULL;
2731 }
2732
2733
2734 if (scsi_sg_count(cmnd)) {
2735 dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle,
2736 sizeof(struct sg_entry) * TOTAL_SG_ENTRY,
2737 DMA_BIDIRECTIONAL);
2738
2739 scsi_dma_unmap(cmnd);
2740 }
2741}
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752static void i91uSCBPost(u8 * host_mem, u8 * cblk_mem)
2753{
2754 struct scsi_cmnd *cmnd;
2755 struct initio_host *host;
2756 struct scsi_ctrl_blk *cblk;
2757
2758 host = (struct initio_host *) host_mem;
2759 cblk = (struct scsi_ctrl_blk *) cblk_mem;
2760 if ((cmnd = cblk->srb) == NULL) {
2761 printk(KERN_ERR "i91uSCBPost: SRB pointer is empty\n");
2762 WARN_ON(1);
2763 initio_release_scb(host, cblk);
2764 return;
2765 }
2766
2767
2768
2769
2770 switch (cblk->hastat) {
2771 case 0x0:
2772 case 0xa:
2773 case 0xb:
2774 cblk->hastat = 0;
2775 break;
2776
2777 case 0x11:
2778
2779 cblk->hastat = DID_TIME_OUT;
2780 break;
2781
2782 case 0x14:
2783
2784
2785
2786 cblk->hastat = DID_RESET;
2787 break;
2788
2789 case 0x1a:
2790 cblk->hastat = DID_ABORT;
2791 break;
2792
2793 case 0x12:
2794
2795
2796 case 0x13:
2797 case 0x16:
2798
2799 default:
2800 printk("ini9100u: %x %x\n", cblk->hastat, cblk->tastat);
2801 cblk->hastat = DID_ERROR;
2802 break;
2803 }
2804
2805 cmnd->result = cblk->tastat | (cblk->hastat << 16);
2806 i91u_unmap_scb(host->pci_dev, cmnd);
2807 cmnd->scsi_done(cmnd);
2808 initio_release_scb(host, cblk);
2809}
2810
2811static struct scsi_host_template initio_template = {
2812 .proc_name = "INI9100U",
2813 .name = "Initio INI-9X00U/UW SCSI device driver",
2814 .queuecommand = i91u_queuecommand,
2815 .eh_bus_reset_handler = i91u_bus_reset,
2816 .bios_param = i91u_biosparam,
2817 .can_queue = MAX_TARGETS * i91u_MAXQUEUE,
2818 .this_id = 1,
2819 .sg_tablesize = SG_ALL,
2820 .use_clustering = ENABLE_CLUSTERING,
2821};
2822
2823static int initio_probe_one(struct pci_dev *pdev,
2824 const struct pci_device_id *id)
2825{
2826 struct Scsi_Host *shost;
2827 struct initio_host *host;
2828 u32 reg;
2829 u16 bios_seg;
2830 struct scsi_ctrl_blk *scb, *tmp, *prev = NULL ;
2831 int num_scb, i, error;
2832
2833 error = pci_enable_device(pdev);
2834 if (error)
2835 return error;
2836
2837 pci_read_config_dword(pdev, 0x44, (u32 *) & reg);
2838 bios_seg = (u16) (reg & 0xFF);
2839 if (((reg & 0xFF00) >> 8) == 0xFF)
2840 reg = 0;
2841 bios_seg = (bios_seg << 8) + ((u16) ((reg & 0xFF00) >> 8));
2842
2843 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
2844 printk(KERN_WARNING "i91u: Could not set 32 bit DMA mask\n");
2845 error = -ENODEV;
2846 goto out_disable_device;
2847 }
2848 shost = scsi_host_alloc(&initio_template, sizeof(struct initio_host));
2849 if (!shost) {
2850 printk(KERN_WARNING "initio: Could not allocate host structure.\n");
2851 error = -ENOMEM;
2852 goto out_disable_device;
2853 }
2854 host = (struct initio_host *)shost->hostdata;
2855 memset(host, 0, sizeof(struct initio_host));
2856 host->addr = pci_resource_start(pdev, 0);
2857 host->bios_addr = bios_seg;
2858
2859 if (!request_region(host->addr, 256, "i91u")) {
2860 printk(KERN_WARNING "initio: I/O port range 0x%x is busy.\n", host->addr);
2861 error = -ENODEV;
2862 goto out_host_put;
2863 }
2864
2865 if (initio_tag_enable)
2866 num_scb = MAX_TARGETS * i91u_MAXQUEUE;
2867 else
2868 num_scb = MAX_TARGETS + 3;
2869
2870 for (; num_scb >= MAX_TARGETS + 3; num_scb--) {
2871 i = num_scb * sizeof(struct scsi_ctrl_blk);
2872 if ((scb = kzalloc(i, GFP_DMA)) != NULL)
2873 break;
2874 }
2875
2876 if (!scb) {
2877 printk(KERN_WARNING "initio: Cannot allocate SCB array.\n");
2878 error = -ENOMEM;
2879 goto out_release_region;
2880 }
2881
2882 host->pci_dev = pdev;
2883
2884 host->semaph = 1;
2885 spin_lock_init(&host->semaph_lock);
2886 host->num_scbs = num_scb;
2887 host->scb = scb;
2888 host->next_pending = scb;
2889 host->next_avail = scb;
2890 for (i = 0, tmp = scb; i < num_scb; i++, tmp++) {
2891 tmp->tagid = i;
2892 if (i != 0)
2893 prev->next = tmp;
2894 prev = tmp;
2895 }
2896 prev->next = NULL;
2897 host->scb_end = tmp;
2898 host->first_avail = scb;
2899 host->last_avail = prev;
2900 spin_lock_init(&host->avail_lock);
2901
2902 initio_init(host, phys_to_virt(((u32)bios_seg << 4)));
2903
2904 host->jsstatus0 = 0;
2905
2906 shost->io_port = host->addr;
2907 shost->n_io_port = 0xff;
2908 shost->can_queue = num_scb;
2909 shost->unique_id = host->addr;
2910 shost->max_id = host->max_tar;
2911 shost->max_lun = 32;
2912 shost->irq = pdev->irq;
2913 shost->this_id = host->scsi_id;
2914 shost->base = host->addr;
2915 shost->sg_tablesize = TOTAL_SG_ENTRY;
2916
2917 error = request_irq(pdev->irq, i91u_intr, IRQF_SHARED, "i91u", shost);
2918 if (error < 0) {
2919 printk(KERN_WARNING "initio: Unable to request IRQ %d\n", pdev->irq);
2920 goto out_free_scbs;
2921 }
2922
2923 pci_set_drvdata(pdev, shost);
2924
2925 error = scsi_add_host(shost, &pdev->dev);
2926 if (error)
2927 goto out_free_irq;
2928 scsi_scan_host(shost);
2929 return 0;
2930out_free_irq:
2931 free_irq(pdev->irq, shost);
2932out_free_scbs:
2933 kfree(host->scb);
2934out_release_region:
2935 release_region(host->addr, 256);
2936out_host_put:
2937 scsi_host_put(shost);
2938out_disable_device:
2939 pci_disable_device(pdev);
2940 return error;
2941}
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951static void initio_remove_one(struct pci_dev *pdev)
2952{
2953 struct Scsi_Host *host = pci_get_drvdata(pdev);
2954 struct initio_host *s = (struct initio_host *)host->hostdata;
2955 scsi_remove_host(host);
2956 free_irq(pdev->irq, host);
2957 release_region(s->addr, 256);
2958 scsi_host_put(host);
2959 pci_disable_device(pdev);
2960}
2961
2962MODULE_LICENSE("GPL");
2963
2964static struct pci_device_id initio_pci_tbl[] = {
2965 {PCI_VENDOR_ID_INIT, 0x9500, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2966 {PCI_VENDOR_ID_INIT, 0x9400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2967 {PCI_VENDOR_ID_INIT, 0x9401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2968 {PCI_VENDOR_ID_INIT, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2969 {PCI_VENDOR_ID_DOMEX, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2970 {0,}
2971};
2972MODULE_DEVICE_TABLE(pci, initio_pci_tbl);
2973
2974static struct pci_driver initio_pci_driver = {
2975 .name = "initio",
2976 .id_table = initio_pci_tbl,
2977 .probe = initio_probe_one,
2978 .remove = initio_remove_one,
2979};
2980
2981static int __init initio_init_driver(void)
2982{
2983 return pci_register_driver(&initio_pci_driver);
2984}
2985
2986static void __exit initio_exit_driver(void)
2987{
2988 pci_unregister_driver(&initio_pci_driver);
2989}
2990
2991MODULE_DESCRIPTION("Initio INI-9X00U/UW SCSI device driver");
2992MODULE_AUTHOR("Initio Corporation");
2993MODULE_LICENSE("GPL");
2994
2995module_init(initio_init_driver);
2996module_exit(initio_exit_driver);
2997