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