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