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#include <linux/module.h>
38#include <linux/blkdev.h>
39#include <linux/kernel.h>
40#include <linux/string.h>
41#include <linux/ioport.h>
42#include <linux/proc_fs.h>
43#include <linux/delay.h>
44#include <linux/bitops.h>
45#include <linux/init.h>
46#include <linux/interrupt.h>
47
48#include <asm/dma.h>
49#include <asm/io.h>
50#include <asm/irq.h>
51#include <asm/ecard.h>
52
53#include "../scsi.h"
54#include <scsi/scsi_dbg.h>
55#include <scsi/scsi_host.h>
56#include "fas216.h"
57#include "scsi.h"
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#define SCSI2_SYNC
83#undef SCSI2_TAG
84
85#undef DEBUG_CONNECT
86#undef DEBUG_MESSAGES
87
88#undef CHECK_STRUCTURE
89
90#define LOG_CONNECT (1 << 0)
91#define LOG_BUSSERVICE (1 << 1)
92#define LOG_FUNCTIONDONE (1 << 2)
93#define LOG_MESSAGES (1 << 3)
94#define LOG_BUFFER (1 << 4)
95#define LOG_ERROR (1 << 8)
96
97static int level_mask = LOG_ERROR;
98
99module_param(level_mask, int, 0644);
100
101#ifndef MODULE
102static int __init fas216_log_setup(char *str)
103{
104 char *s;
105
106 level_mask = 0;
107
108 while ((s = strsep(&str, ",")) != NULL) {
109 switch (s[0]) {
110 case 'a':
111 if (strcmp(s, "all") == 0)
112 level_mask |= -1;
113 break;
114 case 'b':
115 if (strncmp(s, "bus", 3) == 0)
116 level_mask |= LOG_BUSSERVICE;
117 if (strncmp(s, "buf", 3) == 0)
118 level_mask |= LOG_BUFFER;
119 break;
120 case 'c':
121 level_mask |= LOG_CONNECT;
122 break;
123 case 'e':
124 level_mask |= LOG_ERROR;
125 break;
126 case 'm':
127 level_mask |= LOG_MESSAGES;
128 break;
129 case 'n':
130 if (strcmp(s, "none") == 0)
131 level_mask = 0;
132 break;
133 case 's':
134 level_mask |= LOG_FUNCTIONDONE;
135 break;
136 }
137 }
138 return 1;
139}
140
141__setup("fas216_logging=", fas216_log_setup);
142#endif
143
144static inline unsigned char fas216_readb(FAS216_Info *info, unsigned int reg)
145{
146 unsigned int off = reg << info->scsi.io_shift;
147 return readb(info->scsi.io_base + off);
148}
149
150static inline void fas216_writeb(FAS216_Info *info, unsigned int reg, unsigned int val)
151{
152 unsigned int off = reg << info->scsi.io_shift;
153 writeb(val, info->scsi.io_base + off);
154}
155
156static void fas216_dumpstate(FAS216_Info *info)
157{
158 unsigned char is, stat, inst;
159
160 is = fas216_readb(info, REG_IS);
161 stat = fas216_readb(info, REG_STAT);
162 inst = fas216_readb(info, REG_INST);
163
164 printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
165 " INST=%02X IS=%02X CFIS=%02X",
166 fas216_readb(info, REG_CTCL),
167 fas216_readb(info, REG_CTCM),
168 fas216_readb(info, REG_CMD), stat, inst, is,
169 fas216_readb(info, REG_CFIS));
170 printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n",
171 fas216_readb(info, REG_CNTL1),
172 fas216_readb(info, REG_CNTL2),
173 fas216_readb(info, REG_CNTL3),
174 fas216_readb(info, REG_CTCH));
175}
176
177static void print_SCp(struct scsi_pointer *SCp, const char *prefix, const char *suffix)
178{
179 printk("%sptr %p this_residual 0x%x buffer %p buffers_residual 0x%x%s",
180 prefix, SCp->ptr, SCp->this_residual, SCp->buffer,
181 SCp->buffers_residual, suffix);
182}
183
184#ifdef CHECK_STRUCTURE
185static void fas216_dumpinfo(FAS216_Info *info)
186{
187 static int used = 0;
188 int i;
189
190 if (used++)
191 return;
192
193 printk("FAS216_Info=\n");
194 printk(" { magic_start=%lX host=%p SCpnt=%p origSCpnt=%p\n",
195 info->magic_start, info->host, info->SCpnt,
196 info->origSCpnt);
197 printk(" scsi={ io_shift=%X irq=%X cfg={ %X %X %X %X }\n",
198 info->scsi.io_shift, info->scsi.irq,
199 info->scsi.cfg[0], info->scsi.cfg[1], info->scsi.cfg[2],
200 info->scsi.cfg[3]);
201 printk(" type=%p phase=%X\n",
202 info->scsi.type, info->scsi.phase);
203 print_SCp(&info->scsi.SCp, " SCp={ ", " }\n");
204 printk(" msgs async_stp=%X disconnectable=%d aborting=%d }\n",
205 info->scsi.async_stp,
206 info->scsi.disconnectable, info->scsi.aborting);
207 printk(" stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X\n"
208 " disconnects=%X aborts=%X bus_resets=%X host_resets=%X}\n",
209 info->stats.queues, info->stats.removes, info->stats.fins,
210 info->stats.reads, info->stats.writes, info->stats.miscs,
211 info->stats.disconnects, info->stats.aborts, info->stats.bus_resets,
212 info->stats.host_resets);
213 printk(" ifcfg={ clockrate=%X select_timeout=%X asyncperiod=%X sync_max_depth=%X }\n",
214 info->ifcfg.clockrate, info->ifcfg.select_timeout,
215 info->ifcfg.asyncperiod, info->ifcfg.sync_max_depth);
216 for (i = 0; i < 8; i++) {
217 printk(" busyluns[%d]=%08lx dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
218 i, info->busyluns[i], i,
219 info->device[i].disconnect_ok, info->device[i].stp,
220 info->device[i].sof, info->device[i].sync_state);
221 }
222 printk(" dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
223 info->dma.transfer_type, info->dma.setup,
224 info->dma.pseudo, info->dma.stop);
225 printk(" internal_done=%X magic_end=%lX }\n",
226 info->internal_done, info->magic_end);
227}
228
229static void __fas216_checkmagic(FAS216_Info *info, const char *func)
230{
231 int corruption = 0;
232 if (info->magic_start != MAGIC) {
233 printk(KERN_CRIT "FAS216 Error: magic at start corrupted\n");
234 corruption++;
235 }
236 if (info->magic_end != MAGIC) {
237 printk(KERN_CRIT "FAS216 Error: magic at end corrupted\n");
238 corruption++;
239 }
240 if (corruption) {
241 fas216_dumpinfo(info);
242 panic("scsi memory space corrupted in %s", func);
243 }
244}
245#define fas216_checkmagic(info) __fas216_checkmagic((info), __func__)
246#else
247#define fas216_checkmagic(info)
248#endif
249
250static const char *fas216_bus_phase(int stat)
251{
252 static const char *phases[] = {
253 "DATA OUT", "DATA IN",
254 "COMMAND", "STATUS",
255 "MISC OUT", "MISC IN",
256 "MESG OUT", "MESG IN"
257 };
258
259 return phases[stat & STAT_BUSMASK];
260}
261
262static const char *fas216_drv_phase(FAS216_Info *info)
263{
264 static const char *phases[] = {
265 [PHASE_IDLE] = "idle",
266 [PHASE_SELECTION] = "selection",
267 [PHASE_COMMAND] = "command",
268 [PHASE_DATAOUT] = "data out",
269 [PHASE_DATAIN] = "data in",
270 [PHASE_MSGIN] = "message in",
271 [PHASE_MSGIN_DISCONNECT]= "disconnect",
272 [PHASE_MSGOUT_EXPECT] = "expect message out",
273 [PHASE_MSGOUT] = "message out",
274 [PHASE_STATUS] = "status",
275 [PHASE_DONE] = "done",
276 };
277
278 if (info->scsi.phase < ARRAY_SIZE(phases) &&
279 phases[info->scsi.phase])
280 return phases[info->scsi.phase];
281 return "???";
282}
283
284static char fas216_target(FAS216_Info *info)
285{
286 if (info->SCpnt)
287 return '0' + info->SCpnt->device->id;
288 else
289 return 'H';
290}
291
292static void
293fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap)
294{
295 static char buf[1024];
296
297 vsnprintf(buf, sizeof(buf), fmt, ap);
298 printk("scsi%d.%c: %s", info->host->host_no, target, buf);
299}
300
301static void fas216_log_command(FAS216_Info *info, int level,
302 struct scsi_cmnd *SCpnt, char *fmt, ...)
303{
304 va_list args;
305
306 if (level != 0 && !(level & level_mask))
307 return;
308
309 va_start(args, fmt);
310 fas216_do_log(info, '0' + SCpnt->device->id, fmt, args);
311 va_end(args);
312
313 scsi_print_command(SCpnt);
314}
315
316static void
317fas216_log_target(FAS216_Info *info, int level, int target, char *fmt, ...)
318{
319 va_list args;
320
321 if (level != 0 && !(level & level_mask))
322 return;
323
324 if (target < 0)
325 target = 'H';
326 else
327 target += '0';
328
329 va_start(args, fmt);
330 fas216_do_log(info, target, fmt, args);
331 va_end(args);
332
333 printk("\n");
334}
335
336static void fas216_log(FAS216_Info *info, int level, char *fmt, ...)
337{
338 va_list args;
339
340 if (level != 0 && !(level & level_mask))
341 return;
342
343 va_start(args, fmt);
344 fas216_do_log(info, fas216_target(info), fmt, args);
345 va_end(args);
346
347 printk("\n");
348}
349
350#define PH_SIZE 32
351
352static struct { int stat, ssr, isr, ph; } ph_list[PH_SIZE];
353static int ph_ptr;
354
355static void add_debug_list(int stat, int ssr, int isr, int ph)
356{
357 ph_list[ph_ptr].stat = stat;
358 ph_list[ph_ptr].ssr = ssr;
359 ph_list[ph_ptr].isr = isr;
360 ph_list[ph_ptr].ph = ph;
361
362 ph_ptr = (ph_ptr + 1) & (PH_SIZE-1);
363}
364
365static struct { int command; void *from; } cmd_list[8];
366static int cmd_ptr;
367
368static void fas216_cmd(FAS216_Info *info, unsigned int command)
369{
370 cmd_list[cmd_ptr].command = command;
371 cmd_list[cmd_ptr].from = __builtin_return_address(0);
372
373 cmd_ptr = (cmd_ptr + 1) & 7;
374
375 fas216_writeb(info, REG_CMD, command);
376}
377
378static void print_debug_list(void)
379{
380 int i;
381
382 i = ph_ptr;
383
384 printk(KERN_ERR "SCSI IRQ trail\n");
385 do {
386 printk(" %02x:%02x:%02x:%1x",
387 ph_list[i].stat, ph_list[i].ssr,
388 ph_list[i].isr, ph_list[i].ph);
389 i = (i + 1) & (PH_SIZE - 1);
390 if (((i ^ ph_ptr) & 7) == 0)
391 printk("\n");
392 } while (i != ph_ptr);
393 if ((i ^ ph_ptr) & 7)
394 printk("\n");
395
396 i = cmd_ptr;
397 printk(KERN_ERR "FAS216 commands: ");
398 do {
399 printk("%02x:%p ", cmd_list[i].command, cmd_list[i].from);
400 i = (i + 1) & 7;
401 } while (i != cmd_ptr);
402 printk("\n");
403}
404
405static void fas216_done(FAS216_Info *info, unsigned int result);
406
407
408
409
410
411
412
413
414static inline unsigned short
415fas216_get_last_msg(FAS216_Info *info, int pos)
416{
417 unsigned short packed_msg = NOP;
418 struct message *msg;
419 int msgnr = 0;
420
421 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
422 if (pos >= msg->fifo)
423 break;
424 }
425
426 if (msg) {
427 if (msg->msg[0] == EXTENDED_MESSAGE)
428 packed_msg = EXTENDED_MESSAGE | msg->msg[2] << 8;
429 else
430 packed_msg = msg->msg[0];
431 }
432
433 fas216_log(info, LOG_MESSAGES,
434 "Message: %04x found at position %02x\n", packed_msg, pos);
435
436 return packed_msg;
437}
438
439
440
441
442
443
444
445
446
447static int fas216_syncperiod(FAS216_Info *info, int ns)
448{
449 int value = (info->ifcfg.clockrate * ns) / 1000;
450
451 fas216_checkmagic(info);
452
453 if (value < 4)
454 value = 4;
455 else if (value > 35)
456 value = 35;
457
458 return value & 31;
459}
460
461
462
463
464
465
466
467
468
469
470
471static void fas216_set_sync(FAS216_Info *info, int target)
472{
473 unsigned int cntl3;
474
475 fas216_writeb(info, REG_SOF, info->device[target].sof);
476 fas216_writeb(info, REG_STP, info->device[target].stp);
477
478 cntl3 = info->scsi.cfg[2];
479 if (info->device[target].period >= (200 / 4))
480 cntl3 = cntl3 & ~CNTL3_FASTSCSI;
481
482 fas216_writeb(info, REG_CNTL3, cntl3);
483}
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516static void fas216_handlesync(FAS216_Info *info, char *msg)
517{
518 struct fas216_device *dev = &info->device[info->SCpnt->device->id];
519 enum { sync, async, none, reject } res = none;
520
521#ifdef SCSI2_SYNC
522 switch (msg[0]) {
523 case MESSAGE_REJECT:
524
525
526
527
528
529
530
531
532
533
534 if (dev->sync_state == neg_inprogress) {
535 dev->sync_state = neg_invalid;
536 res = async;
537 }
538 break;
539
540 case EXTENDED_MESSAGE:
541 switch (dev->sync_state) {
542
543
544
545
546 case neg_invalid:
547 res = reject;
548 break;
549
550
551
552
553
554
555
556 default:
557 fas216_cmd(info, CMD_SETATN);
558 if (msg[4] > info->ifcfg.sync_max_depth)
559 msg[4] = info->ifcfg.sync_max_depth;
560 if (msg[3] < 1000 / info->ifcfg.clockrate)
561 msg[3] = 1000 / info->ifcfg.clockrate;
562
563 msgqueue_flush(&info->scsi.msgs);
564 msgqueue_addmsg(&info->scsi.msgs, 5,
565 EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
566 msg[3], msg[4]);
567 info->scsi.phase = PHASE_MSGOUT_EXPECT;
568
569
570
571
572 dev->sync_state = neg_targcomplete;
573 res = sync;
574 break;
575
576
577
578
579
580
581
582 case neg_inprogress:
583 res = reject;
584 if (msg[4] <= info->ifcfg.sync_max_depth &&
585 msg[3] >= 1000 / info->ifcfg.clockrate) {
586 dev->sync_state = neg_complete;
587 res = sync;
588 }
589 break;
590 }
591 }
592#else
593 res = reject;
594#endif
595
596 switch (res) {
597 case sync:
598 dev->period = msg[3];
599 dev->sof = msg[4];
600 dev->stp = fas216_syncperiod(info, msg[3] * 4);
601 fas216_set_sync(info, info->SCpnt->device->id);
602 break;
603
604 case reject:
605 fas216_cmd(info, CMD_SETATN);
606 msgqueue_flush(&info->scsi.msgs);
607 msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
608 info->scsi.phase = PHASE_MSGOUT_EXPECT;
609
610 case async:
611 dev->period = info->ifcfg.asyncperiod / 4;
612 dev->sof = 0;
613 dev->stp = info->scsi.async_stp;
614 fas216_set_sync(info, info->SCpnt->device->id);
615 break;
616
617 case none:
618 break;
619 }
620}
621
622
623
624
625
626
627
628
629static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
630{
631 struct scsi_pointer *SCp = &info->scsi.SCp;
632
633 fas216_checkmagic(info);
634
635 BUG_ON(bytes_transferred < 0);
636
637 SCp->phase -= bytes_transferred;
638
639 while (bytes_transferred != 0) {
640 if (SCp->this_residual > bytes_transferred)
641 break;
642
643
644
645
646 bytes_transferred -= SCp->this_residual;
647 if (!next_SCp(SCp) && bytes_transferred) {
648 printk(KERN_WARNING "scsi%d.%c: out of buffers\n",
649 info->host->host_no, '0' + info->SCpnt->device->id);
650 return;
651 }
652 }
653
654 SCp->this_residual -= bytes_transferred;
655 if (SCp->this_residual)
656 SCp->ptr += bytes_transferred;
657 else
658 SCp->ptr = NULL;
659}
660
661
662
663
664
665
666
667
668
669static void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
670{
671 struct scsi_pointer *SCp = &info->scsi.SCp;
672
673 fas216_checkmagic(info);
674
675 if (direction == DMA_OUT)
676 fas216_writeb(info, REG_FF, get_next_SCp_byte(SCp));
677 else
678 put_next_SCp_byte(SCp, fas216_readb(info, REG_FF));
679
680 if (SCp->this_residual == 0)
681 next_SCp(SCp);
682}
683
684static void fas216_set_stc(FAS216_Info *info, unsigned int length)
685{
686 fas216_writeb(info, REG_STCL, length);
687 fas216_writeb(info, REG_STCM, length >> 8);
688 fas216_writeb(info, REG_STCH, length >> 16);
689}
690
691static unsigned int fas216_get_ctc(FAS216_Info *info)
692{
693 return fas216_readb(info, REG_CTCL) +
694 (fas216_readb(info, REG_CTCM) << 8) +
695 (fas216_readb(info, REG_CTCH) << 16);
696}
697
698
699
700
701
702
703
704
705static void fas216_cleanuptransfer(FAS216_Info *info)
706{
707 unsigned long total, residual, fifo;
708 fasdmatype_t dmatype = info->dma.transfer_type;
709
710 info->dma.transfer_type = fasdma_none;
711
712
713
714
715 if (dmatype == fasdma_pio || dmatype == fasdma_none)
716 return;
717
718 if (dmatype == fasdma_real_all)
719 total = info->scsi.SCp.phase;
720 else
721 total = info->scsi.SCp.this_residual;
722
723 residual = fas216_get_ctc(info);
724
725 fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
726
727 fas216_log(info, LOG_BUFFER, "cleaning up from previous "
728 "transfer: length 0x%06x, residual 0x%x, fifo %d",
729 total, residual, fifo);
730
731
732
733
734
735
736
737 if (info->scsi.phase == PHASE_DATAOUT)
738 residual += fifo;
739
740 fas216_updateptrs(info, total - residual);
741}
742
743
744
745
746
747
748
749static void fas216_transfer(FAS216_Info *info)
750{
751 fasdmadir_t direction;
752 fasdmatype_t dmatype;
753
754 fas216_log(info, LOG_BUFFER,
755 "starttransfer: buffer %p length 0x%06x reqlen 0x%06x",
756 info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
757 info->scsi.SCp.phase);
758
759 if (!info->scsi.SCp.ptr) {
760 fas216_log(info, LOG_ERROR, "null buffer passed to "
761 "fas216_starttransfer");
762 print_SCp(&info->scsi.SCp, "SCp: ", "\n");
763 print_SCp(&info->SCpnt->SCp, "Cmnd SCp: ", "\n");
764 return;
765 }
766
767
768
769
770
771
772 if (info->device[info->SCpnt->device->id].sof)
773 dmatype = fasdma_real_all;
774 else
775 dmatype = fasdma_pio;
776
777 if (info->scsi.phase == PHASE_DATAOUT)
778 direction = DMA_OUT;
779 else
780 direction = DMA_IN;
781
782 if (info->dma.setup)
783 dmatype = info->dma.setup(info->host, &info->scsi.SCp,
784 direction, dmatype);
785 info->dma.transfer_type = dmatype;
786
787 if (dmatype == fasdma_real_all)
788 fas216_set_stc(info, info->scsi.SCp.phase);
789 else
790 fas216_set_stc(info, info->scsi.SCp.this_residual);
791
792 switch (dmatype) {
793 case fasdma_pio:
794 fas216_log(info, LOG_BUFFER, "PIO transfer");
795 fas216_writeb(info, REG_SOF, 0);
796 fas216_writeb(info, REG_STP, info->scsi.async_stp);
797 fas216_cmd(info, CMD_TRANSFERINFO);
798 fas216_pio(info, direction);
799 break;
800
801 case fasdma_pseudo:
802 fas216_log(info, LOG_BUFFER, "pseudo transfer");
803 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
804 info->dma.pseudo(info->host, &info->scsi.SCp,
805 direction, info->SCpnt->transfersize);
806 break;
807
808 case fasdma_real_block:
809 fas216_log(info, LOG_BUFFER, "block dma transfer");
810 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
811 break;
812
813 case fasdma_real_all:
814 fas216_log(info, LOG_BUFFER, "total dma transfer");
815 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
816 break;
817
818 default:
819 fas216_log(info, LOG_BUFFER | LOG_ERROR,
820 "invalid FAS216 DMA type");
821 break;
822 }
823}
824
825
826
827
828
829
830
831static void fas216_stoptransfer(FAS216_Info *info)
832{
833 fas216_checkmagic(info);
834
835 if (info->dma.transfer_type == fasdma_real_all ||
836 info->dma.transfer_type == fasdma_real_block)
837 info->dma.stop(info->host, &info->scsi.SCp);
838
839 fas216_cleanuptransfer(info);
840
841 if (info->scsi.phase == PHASE_DATAIN) {
842 unsigned int fifo;
843
844
845
846
847
848
849 fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
850 while (fifo && info->scsi.SCp.ptr) {
851 *info->scsi.SCp.ptr = fas216_readb(info, REG_FF);
852 fas216_updateptrs(info, 1);
853 fifo--;
854 }
855 } else {
856
857
858
859
860 fas216_cmd(info, CMD_FLUSHFIFO);
861 }
862}
863
864static void fas216_aborttransfer(FAS216_Info *info)
865{
866 fas216_checkmagic(info);
867
868 if (info->dma.transfer_type == fasdma_real_all ||
869 info->dma.transfer_type == fasdma_real_block)
870 info->dma.stop(info->host, &info->scsi.SCp);
871
872 info->dma.transfer_type = fasdma_none;
873 fas216_cmd(info, CMD_FLUSHFIFO);
874}
875
876static void fas216_kick(FAS216_Info *info);
877
878
879
880
881
882
883
884static void fas216_disconnect_intr(FAS216_Info *info)
885{
886 unsigned long flags;
887
888 fas216_checkmagic(info);
889
890 fas216_log(info, LOG_CONNECT, "disconnect phase=%02x",
891 info->scsi.phase);
892
893 msgqueue_flush(&info->scsi.msgs);
894
895 switch (info->scsi.phase) {
896 case PHASE_SELECTION:
897 case PHASE_SELSTEPS:
898 fas216_done(info, DID_NO_CONNECT);
899 break;
900
901 case PHASE_MSGIN_DISCONNECT:
902 info->scsi.disconnectable = 1;
903 info->scsi.phase = PHASE_IDLE;
904 info->stats.disconnects += 1;
905 spin_lock_irqsave(&info->host_lock, flags);
906 if (info->scsi.phase == PHASE_IDLE)
907 fas216_kick(info);
908 spin_unlock_irqrestore(&info->host_lock, flags);
909 break;
910
911 case PHASE_DONE:
912 fas216_done(info, DID_OK);
913 break;
914
915 case PHASE_MSGOUT:
916 if (fas216_get_last_msg(info, info->scsi.msgin_fifo) == ABORT) {
917 info->scsi.aborting = 0;
918 fas216_done(info, DID_ABORT);
919 break;
920 }
921
922 default:
923 printk(KERN_ERR "scsi%d.%c: unexpected disconnect in phase %s\n",
924 info->host->host_no, fas216_target(info), fas216_drv_phase(info));
925 print_debug_list();
926 fas216_stoptransfer(info);
927 fas216_done(info, DID_ERROR);
928 break;
929 }
930}
931
932
933
934
935
936
937
938static void
939fas216_reselected_intr(FAS216_Info *info)
940{
941 unsigned int cfis, i;
942 unsigned char msg[4];
943 unsigned char target, lun, tag;
944
945 fas216_checkmagic(info);
946
947 WARN_ON(info->scsi.phase == PHASE_SELECTION ||
948 info->scsi.phase == PHASE_SELSTEPS);
949
950 cfis = fas216_readb(info, REG_CFIS);
951
952 fas216_log(info, LOG_CONNECT, "reconnect phase=%02x cfis=%02x",
953 info->scsi.phase, cfis);
954
955 cfis &= CFIS_CF;
956
957 if (cfis < 2 || cfis > 4) {
958 printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n",
959 info->host->host_no);
960 goto bad_message;
961 }
962
963 for (i = 0; i < cfis; i++)
964 msg[i] = fas216_readb(info, REG_FF);
965
966 if (!(msg[0] & (1 << info->host->this_id)) ||
967 !(msg[1] & 0x80))
968 goto initiator_error;
969
970 target = msg[0] & ~(1 << info->host->this_id);
971 target = ffs(target) - 1;
972 lun = msg[1] & 7;
973 tag = 0;
974
975 if (cfis >= 3) {
976 if (msg[2] != SIMPLE_QUEUE_TAG)
977 goto initiator_error;
978
979 tag = msg[3];
980 }
981
982
983 fas216_writeb(info, REG_SDID, target);
984 fas216_set_sync(info, target);
985 msgqueue_flush(&info->scsi.msgs);
986
987 fas216_log(info, LOG_CONNECT, "Reconnected: target %1x lun %1x tag %02x",
988 target, lun, tag);
989
990 if (info->scsi.disconnectable && info->SCpnt) {
991 info->scsi.disconnectable = 0;
992 if (info->SCpnt->device->id == target &&
993 info->SCpnt->device->lun == lun &&
994 info->SCpnt->tag == tag) {
995 fas216_log(info, LOG_CONNECT, "reconnected previously executing command");
996 } else {
997 queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
998 fas216_log(info, LOG_CONNECT, "had to move command to disconnected queue");
999 info->SCpnt = NULL;
1000 }
1001 }
1002 if (!info->SCpnt) {
1003 info->SCpnt = queue_remove_tgtluntag(&info->queues.disconnected,
1004 target, lun, tag);
1005 fas216_log(info, LOG_CONNECT, "had to get command");
1006 }
1007
1008 if (info->SCpnt) {
1009
1010
1011
1012 info->scsi.SCp = info->SCpnt->SCp;
1013
1014 fas216_log(info, LOG_CONNECT, "data pointers: [%p, %X]",
1015 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1016 info->scsi.phase = PHASE_MSGIN;
1017 } else {
1018
1019
1020
1021
1022
1023
1024 fas216_cmd(info, CMD_SETATN);
1025
1026#if 0
1027 if (tag)
1028 msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, tag);
1029 else
1030#endif
1031 msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
1032 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1033 info->scsi.aborting = 1;
1034 }
1035
1036 fas216_cmd(info, CMD_MSGACCEPTED);
1037 return;
1038
1039 initiator_error:
1040 printk(KERN_ERR "scsi%d.H: error during reselection: bytes",
1041 info->host->host_no);
1042 for (i = 0; i < cfis; i++)
1043 printk(" %02x", msg[i]);
1044 printk("\n");
1045 bad_message:
1046 fas216_cmd(info, CMD_SETATN);
1047 msgqueue_flush(&info->scsi.msgs);
1048 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1049 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1050 fas216_cmd(info, CMD_MSGACCEPTED);
1051}
1052
1053static void fas216_parse_message(FAS216_Info *info, unsigned char *message, int msglen)
1054{
1055 int i;
1056
1057 switch (message[0]) {
1058 case COMMAND_COMPLETE:
1059 if (msglen != 1)
1060 goto unrecognised;
1061
1062 printk(KERN_ERR "scsi%d.%c: command complete with no "
1063 "status in MESSAGE_IN?\n",
1064 info->host->host_no, fas216_target(info));
1065 break;
1066
1067 case SAVE_POINTERS:
1068 if (msglen != 1)
1069 goto unrecognised;
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079 info->SCpnt->SCp = info->scsi.SCp;
1080 info->SCpnt->SCp.sent_command = 0;
1081 fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
1082 "save data pointers: [%p, %X]",
1083 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1084 break;
1085
1086 case RESTORE_POINTERS:
1087 if (msglen != 1)
1088 goto unrecognised;
1089
1090
1091
1092
1093 info->scsi.SCp = info->SCpnt->SCp;
1094 fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
1095 "restore data pointers: [%p, 0x%x]",
1096 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1097 break;
1098
1099 case DISCONNECT:
1100 if (msglen != 1)
1101 goto unrecognised;
1102
1103 info->scsi.phase = PHASE_MSGIN_DISCONNECT;
1104 break;
1105
1106 case MESSAGE_REJECT:
1107 if (msglen != 1)
1108 goto unrecognised;
1109
1110 switch (fas216_get_last_msg(info, info->scsi.msgin_fifo)) {
1111 case EXTENDED_MESSAGE | EXTENDED_SDTR << 8:
1112 fas216_handlesync(info, message);
1113 break;
1114
1115 default:
1116 fas216_log(info, 0, "reject, last message 0x%04x",
1117 fas216_get_last_msg(info, info->scsi.msgin_fifo));
1118 }
1119 break;
1120
1121 case NOP:
1122 break;
1123
1124 case EXTENDED_MESSAGE:
1125 if (msglen < 3)
1126 goto unrecognised;
1127
1128 switch (message[2]) {
1129 case EXTENDED_SDTR:
1130 fas216_handlesync(info, message);
1131 break;
1132
1133 default:
1134 goto unrecognised;
1135 }
1136 break;
1137
1138 default:
1139 goto unrecognised;
1140 }
1141 return;
1142
1143unrecognised:
1144 fas216_log(info, 0, "unrecognised message, rejecting");
1145 printk("scsi%d.%c: message was", info->host->host_no, fas216_target(info));
1146 for (i = 0; i < msglen; i++)
1147 printk("%s%02X", i & 31 ? " " : "\n ", message[i]);
1148 printk("\n");
1149
1150
1151
1152
1153
1154
1155fas216_cmd(info, CMD_NOP);
1156fas216_dumpstate(info);
1157 fas216_cmd(info, CMD_SETATN);
1158 msgqueue_flush(&info->scsi.msgs);
1159 msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
1160 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1161fas216_dumpstate(info);
1162}
1163
1164static int fas216_wait_cmd(FAS216_Info *info, int cmd)
1165{
1166 int tout;
1167 int stat;
1168
1169 fas216_cmd(info, cmd);
1170
1171 for (tout = 1000; tout; tout -= 1) {
1172 stat = fas216_readb(info, REG_STAT);
1173 if (stat & (STAT_INT|STAT_PARITYERROR))
1174 break;
1175 udelay(1);
1176 }
1177
1178 return stat;
1179}
1180
1181static int fas216_get_msg_byte(FAS216_Info *info)
1182{
1183 unsigned int stat = fas216_wait_cmd(info, CMD_MSGACCEPTED);
1184
1185 if ((stat & STAT_INT) == 0)
1186 goto timedout;
1187
1188 if ((stat & STAT_BUSMASK) != STAT_MESGIN)
1189 goto unexpected_phase_change;
1190
1191 fas216_readb(info, REG_INST);
1192
1193 stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);
1194
1195 if ((stat & STAT_INT) == 0)
1196 goto timedout;
1197
1198 if (stat & STAT_PARITYERROR)
1199 goto parity_error;
1200
1201 if ((stat & STAT_BUSMASK) != STAT_MESGIN)
1202 goto unexpected_phase_change;
1203
1204 fas216_readb(info, REG_INST);
1205
1206 return fas216_readb(info, REG_FF);
1207
1208timedout:
1209 fas216_log(info, LOG_ERROR, "timed out waiting for message byte");
1210 return -1;
1211
1212unexpected_phase_change:
1213 fas216_log(info, LOG_ERROR, "unexpected phase change: status = %02x", stat);
1214 return -2;
1215
1216parity_error:
1217 fas216_log(info, LOG_ERROR, "parity error during message in phase");
1218 return -3;
1219}
1220
1221
1222
1223
1224
1225
1226
1227static void fas216_message(FAS216_Info *info)
1228{
1229 unsigned char *message = info->scsi.message;
1230 unsigned int msglen = 1;
1231 int msgbyte = 0;
1232
1233 fas216_checkmagic(info);
1234
1235 message[0] = fas216_readb(info, REG_FF);
1236
1237 if (message[0] == EXTENDED_MESSAGE) {
1238 msgbyte = fas216_get_msg_byte(info);
1239
1240 if (msgbyte >= 0) {
1241 message[1] = msgbyte;
1242
1243 for (msglen = 2; msglen < message[1] + 2; msglen++) {
1244 msgbyte = fas216_get_msg_byte(info);
1245
1246 if (msgbyte >= 0)
1247 message[msglen] = msgbyte;
1248 else
1249 break;
1250 }
1251 }
1252 }
1253
1254 if (msgbyte == -3)
1255 goto parity_error;
1256
1257#ifdef DEBUG_MESSAGES
1258 {
1259 int i;
1260
1261 printk("scsi%d.%c: message in: ",
1262 info->host->host_no, fas216_target(info));
1263 for (i = 0; i < msglen; i++)
1264 printk("%02X ", message[i]);
1265 printk("\n");
1266 }
1267#endif
1268
1269 fas216_parse_message(info, message, msglen);
1270 fas216_cmd(info, CMD_MSGACCEPTED);
1271 return;
1272
1273parity_error:
1274 fas216_cmd(info, CMD_SETATN);
1275 msgqueue_flush(&info->scsi.msgs);
1276 msgqueue_addmsg(&info->scsi.msgs, 1, MSG_PARITY_ERROR);
1277 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1278 fas216_cmd(info, CMD_MSGACCEPTED);
1279 return;
1280}
1281
1282
1283
1284
1285
1286
1287
1288static void fas216_send_command(FAS216_Info *info)
1289{
1290 int i;
1291
1292 fas216_checkmagic(info);
1293
1294 fas216_cmd(info, CMD_NOP|CMD_WITHDMA);
1295 fas216_cmd(info, CMD_FLUSHFIFO);
1296
1297
1298 for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++)
1299 fas216_writeb(info, REG_FF, info->SCpnt->cmnd[i]);
1300
1301 fas216_cmd(info, CMD_TRANSFERINFO);
1302
1303 info->scsi.phase = PHASE_COMMAND;
1304}
1305
1306
1307
1308
1309
1310
1311
1312
1313static void fas216_send_messageout(FAS216_Info *info, int start)
1314{
1315 unsigned int tot_msglen = msgqueue_msglength(&info->scsi.msgs);
1316
1317 fas216_checkmagic(info);
1318
1319 fas216_cmd(info, CMD_FLUSHFIFO);
1320
1321 if (tot_msglen) {
1322 struct message *msg;
1323 int msgnr = 0;
1324
1325 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1326 int i;
1327
1328 for (i = start; i < msg->length; i++)
1329 fas216_writeb(info, REG_FF, msg->msg[i]);
1330
1331 msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
1332 start = 0;
1333 }
1334 } else
1335 fas216_writeb(info, REG_FF, NOP);
1336
1337 fas216_cmd(info, CMD_TRANSFERINFO);
1338
1339 info->scsi.phase = PHASE_MSGOUT;
1340}
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int is)
1351{
1352 fas216_checkmagic(info);
1353
1354 fas216_log(info, LOG_BUSSERVICE,
1355 "bus service: stat=%02x is=%02x phase=%02x",
1356 stat, is, info->scsi.phase);
1357
1358 switch (info->scsi.phase) {
1359 case PHASE_SELECTION:
1360 if ((is & IS_BITS) != IS_MSGBYTESENT)
1361 goto bad_is;
1362 break;
1363
1364 case PHASE_SELSTEPS:
1365 switch (is & IS_BITS) {
1366 case IS_SELARB:
1367 case IS_MSGBYTESENT:
1368 goto bad_is;
1369
1370 case IS_NOTCOMMAND:
1371 case IS_EARLYPHASE:
1372 if ((stat & STAT_BUSMASK) == STAT_MESGIN)
1373 break;
1374 goto bad_is;
1375
1376 case IS_COMPLETE:
1377 break;
1378 }
1379
1380 default:
1381 break;
1382 }
1383
1384 fas216_cmd(info, CMD_NOP);
1385
1386#define STATE(st,ph) ((ph) << 3 | (st))
1387
1388
1389
1390 switch (STATE(stat & STAT_BUSMASK, info->scsi.phase)) {
1391 case STATE(STAT_DATAIN, PHASE_SELSTEPS):
1392 case STATE(STAT_DATAIN, PHASE_MSGOUT):
1393 case STATE(STAT_DATAIN, PHASE_COMMAND):
1394 case STATE(STAT_DATAIN, PHASE_MSGIN):
1395 info->scsi.phase = PHASE_DATAIN;
1396 fas216_transfer(info);
1397 return;
1398
1399 case STATE(STAT_DATAIN, PHASE_DATAIN):
1400 case STATE(STAT_DATAOUT, PHASE_DATAOUT):
1401 fas216_cleanuptransfer(info);
1402 fas216_transfer(info);
1403 return;
1404
1405 case STATE(STAT_DATAOUT, PHASE_SELSTEPS):
1406 case STATE(STAT_DATAOUT, PHASE_MSGOUT):
1407 case STATE(STAT_DATAOUT, PHASE_COMMAND):
1408 case STATE(STAT_DATAOUT, PHASE_MSGIN):
1409 fas216_cmd(info, CMD_FLUSHFIFO);
1410 info->scsi.phase = PHASE_DATAOUT;
1411 fas216_transfer(info);
1412 return;
1413
1414 case STATE(STAT_STATUS, PHASE_DATAOUT):
1415 case STATE(STAT_STATUS, PHASE_DATAIN):
1416 fas216_stoptransfer(info);
1417 case STATE(STAT_STATUS, PHASE_SELSTEPS):
1418 case STATE(STAT_STATUS, PHASE_MSGOUT):
1419 case STATE(STAT_STATUS, PHASE_COMMAND):
1420 case STATE(STAT_STATUS, PHASE_MSGIN):
1421 fas216_cmd(info, CMD_INITCMDCOMPLETE);
1422 info->scsi.phase = PHASE_STATUS;
1423 return;
1424
1425 case STATE(STAT_MESGIN, PHASE_DATAOUT):
1426 case STATE(STAT_MESGIN, PHASE_DATAIN):
1427 fas216_stoptransfer(info);
1428 case STATE(STAT_MESGIN, PHASE_COMMAND):
1429 case STATE(STAT_MESGIN, PHASE_SELSTEPS):
1430 case STATE(STAT_MESGIN, PHASE_MSGOUT):
1431 info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
1432 fas216_cmd(info, CMD_FLUSHFIFO);
1433 fas216_cmd(info, CMD_TRANSFERINFO);
1434 info->scsi.phase = PHASE_MSGIN;
1435 return;
1436
1437 case STATE(STAT_MESGIN, PHASE_MSGIN):
1438 info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
1439 fas216_cmd(info, CMD_TRANSFERINFO);
1440 return;
1441
1442 case STATE(STAT_COMMAND, PHASE_MSGOUT):
1443 case STATE(STAT_COMMAND, PHASE_MSGIN):
1444 fas216_send_command(info);
1445 info->scsi.phase = PHASE_COMMAND;
1446 return;
1447
1448
1449
1450
1451
1452 case STATE(STAT_MESGOUT, PHASE_SELECTION):
1453 fas216_send_messageout(info, 1);
1454 return;
1455
1456
1457
1458
1459 case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
1460 case STATE(STAT_MESGOUT, PHASE_MSGOUT):
1461
1462
1463
1464
1465
1466
1467 if (info->device[info->SCpnt->device->id].parity_check) {
1468
1469
1470
1471
1472 info->device[info->SCpnt->device->id].parity_check = 0;
1473 info->device[info->SCpnt->device->id].parity_enabled = 1;
1474 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
1475 }
1476
1477 if (msgqueue_msglength(&info->scsi.msgs) > 1)
1478 fas216_cmd(info, CMD_SETATN);
1479
1480
1481
1482
1483
1484 case STATE(STAT_MESGOUT, PHASE_MSGOUT_EXPECT):
1485 fas216_send_messageout(info, 0);
1486 return;
1487
1488
1489
1490
1491
1492 case STATE(STAT_COMMAND, PHASE_COMMAND):
1493
1494
1495
1496
1497
1498
1499 printk(KERN_ERR "scsi%d.%c: "
1500 "target trying to receive more command bytes\n",
1501 info->host->host_no, fas216_target(info));
1502 fas216_cmd(info, CMD_SETATN);
1503 fas216_set_stc(info, 15);
1504 fas216_cmd(info, CMD_PADBYTES | CMD_WITHDMA);
1505 msgqueue_flush(&info->scsi.msgs);
1506 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1507 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1508 return;
1509 }
1510
1511 if (info->scsi.phase == PHASE_MSGIN_DISCONNECT) {
1512 printk(KERN_ERR "scsi%d.%c: disconnect message received, but bus service %s?\n",
1513 info->host->host_no, fas216_target(info),
1514 fas216_bus_phase(stat));
1515 msgqueue_flush(&info->scsi.msgs);
1516 fas216_cmd(info, CMD_SETATN);
1517 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1518 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1519 info->scsi.aborting = 1;
1520 fas216_cmd(info, CMD_TRANSFERINFO);
1521 return;
1522 }
1523 printk(KERN_ERR "scsi%d.%c: bus phase %s after %s?\n",
1524 info->host->host_no, fas216_target(info),
1525 fas216_bus_phase(stat),
1526 fas216_drv_phase(info));
1527 print_debug_list();
1528 return;
1529
1530bad_is:
1531 fas216_log(info, 0, "bus service at step %d?", is & IS_BITS);
1532 fas216_dumpstate(info);
1533 print_debug_list();
1534
1535 fas216_done(info, DID_ERROR);
1536}
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int is)
1547{
1548 unsigned int fifo_len = fas216_readb(info, REG_CFIS) & CFIS_CF;
1549
1550 fas216_checkmagic(info);
1551
1552 fas216_log(info, LOG_FUNCTIONDONE,
1553 "function done: stat=%02x is=%02x phase=%02x",
1554 stat, is, info->scsi.phase);
1555
1556 switch (info->scsi.phase) {
1557 case PHASE_STATUS:
1558 if (fifo_len != 2) {
1559 fas216_log(info, 0, "odd number of bytes in FIFO: %d", fifo_len);
1560 }
1561
1562
1563
1564 info->scsi.SCp.Status = fas216_readb(info, REG_FF);
1565 info->scsi.SCp.Message = fas216_readb(info, REG_FF);
1566 info->scsi.phase = PHASE_DONE;
1567 fas216_cmd(info, CMD_MSGACCEPTED);
1568 break;
1569
1570 case PHASE_IDLE:
1571 case PHASE_SELECTION:
1572 case PHASE_SELSTEPS:
1573 break;
1574
1575 case PHASE_MSGIN:
1576 if ((stat & STAT_BUSMASK) == STAT_MESGIN) {
1577 info->scsi.msgin_fifo = fifo_len;
1578 fas216_message(info);
1579 break;
1580 }
1581
1582 default:
1583 fas216_log(info, 0, "internal phase %s for function done?"
1584 " What do I do with this?",
1585 fas216_target(info), fas216_drv_phase(info));
1586 }
1587}
1588
1589static void fas216_bus_reset(FAS216_Info *info)
1590{
1591 neg_t sync_state;
1592 int i;
1593
1594 msgqueue_flush(&info->scsi.msgs);
1595
1596 sync_state = neg_invalid;
1597
1598#ifdef SCSI2_SYNC
1599 if (info->ifcfg.capabilities & (FASCAP_DMA|FASCAP_PSEUDODMA))
1600 sync_state = neg_wait;
1601#endif
1602
1603 info->scsi.phase = PHASE_IDLE;
1604 info->SCpnt = NULL;
1605 memset(&info->scsi.SCp, 0, sizeof(info->scsi.SCp));
1606
1607 for (i = 0; i < 8; i++) {
1608 info->device[i].disconnect_ok = info->ifcfg.disconnect_ok;
1609 info->device[i].sync_state = sync_state;
1610 info->device[i].period = info->ifcfg.asyncperiod / 4;
1611 info->device[i].stp = info->scsi.async_stp;
1612 info->device[i].sof = 0;
1613 info->device[i].wide_xfer = 0;
1614 }
1615
1616 info->rst_bus_status = 1;
1617 wake_up(&info->eh_wait);
1618}
1619
1620
1621
1622
1623
1624
1625
1626irqreturn_t fas216_intr(FAS216_Info *info)
1627{
1628 unsigned char inst, is, stat;
1629 int handled = IRQ_NONE;
1630
1631 fas216_checkmagic(info);
1632
1633 stat = fas216_readb(info, REG_STAT);
1634 is = fas216_readb(info, REG_IS);
1635 inst = fas216_readb(info, REG_INST);
1636
1637 add_debug_list(stat, is, inst, info->scsi.phase);
1638
1639 if (stat & STAT_INT) {
1640 if (inst & INST_BUSRESET) {
1641 fas216_log(info, 0, "bus reset detected");
1642 fas216_bus_reset(info);
1643 scsi_report_bus_reset(info->host, 0);
1644 } else if (inst & INST_ILLEGALCMD) {
1645 fas216_log(info, LOG_ERROR, "illegal command given\n");
1646 fas216_dumpstate(info);
1647 print_debug_list();
1648 } else if (inst & INST_DISCONNECT)
1649 fas216_disconnect_intr(info);
1650 else if (inst & INST_RESELECTED)
1651 fas216_reselected_intr(info);
1652 else if (inst & INST_BUSSERVICE)
1653 fas216_busservice_intr(info, stat, is);
1654 else if (inst & INST_FUNCDONE)
1655 fas216_funcdone_intr(info, stat, is);
1656 else
1657 fas216_log(info, 0, "unknown interrupt received:"
1658 " phase %s inst %02X is %02X stat %02X",
1659 fas216_drv_phase(info), inst, is, stat);
1660 handled = IRQ_HANDLED;
1661 }
1662 return handled;
1663}
1664
1665static void __fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt)
1666{
1667 int tot_msglen;
1668
1669
1670 fas216_set_stc(info, 0);
1671 fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
1672
1673
1674 fas216_cmd(info, CMD_FLUSHFIFO);
1675
1676
1677 fas216_writeb(info, REG_SDID, BUSID(SCpnt->device->id));
1678 fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
1679
1680
1681 fas216_set_sync(info, SCpnt->device->id);
1682
1683 tot_msglen = msgqueue_msglength(&info->scsi.msgs);
1684
1685#ifdef DEBUG_MESSAGES
1686 {
1687 struct message *msg;
1688 int msgnr = 0, i;
1689
1690 printk("scsi%d.%c: message out: ",
1691 info->host->host_no, '0' + SCpnt->device->id);
1692 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1693 printk("{ ");
1694 for (i = 0; i < msg->length; i++)
1695 printk("%02x ", msg->msg[i]);
1696 printk("} ");
1697 }
1698 printk("\n");
1699 }
1700#endif
1701
1702 if (tot_msglen == 1 || tot_msglen == 3) {
1703
1704
1705
1706 struct message *msg;
1707 int msgnr = 0, i;
1708
1709 info->scsi.phase = PHASE_SELSTEPS;
1710
1711
1712 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1713 for (i = 0; i < msg->length; i++)
1714 fas216_writeb(info, REG_FF, msg->msg[i]);
1715 msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
1716 }
1717
1718
1719 for (i = 0; i < SCpnt->cmd_len; i++)
1720 fas216_writeb(info, REG_FF, SCpnt->cmnd[i]);
1721
1722 if (tot_msglen == 1)
1723 fas216_cmd(info, CMD_SELECTATN);
1724 else
1725 fas216_cmd(info, CMD_SELECTATN3);
1726 } else {
1727
1728
1729
1730
1731
1732 struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
1733
1734 fas216_writeb(info, REG_FF, msg->msg[0]);
1735 msg->fifo = 1;
1736
1737 fas216_cmd(info, CMD_SELECTATNSTOP);
1738 }
1739}
1740
1741
1742
1743
1744
1745
1746static int parity_test(FAS216_Info *info, int target)
1747{
1748#if 0
1749 if (target == 3) {
1750 info->device[target].parity_check = 0;
1751 return 1;
1752 }
1753#endif
1754 return info->device[target].parity_check;
1755}
1756
1757static void fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt)
1758{
1759 int disconnect_ok;
1760
1761
1762
1763
1764 info->scsi.phase = PHASE_SELECTION;
1765 info->scsi.SCp = SCpnt->SCp;
1766 info->SCpnt = SCpnt;
1767 info->dma.transfer_type = fasdma_none;
1768
1769 if (parity_test(info, SCpnt->device->id))
1770 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_PTE);
1771 else
1772 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
1773
1774
1775
1776
1777 disconnect_ok = SCpnt->cmnd[0] != REQUEST_SENSE &&
1778 info->device[SCpnt->device->id].disconnect_ok;
1779
1780
1781
1782
1783 msgqueue_flush(&info->scsi.msgs);
1784 msgqueue_addmsg(&info->scsi.msgs, 1, IDENTIFY(disconnect_ok, SCpnt->device->lun));
1785
1786
1787
1788
1789 if (SCpnt->tag)
1790 msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, SCpnt->tag);
1791
1792 do {
1793#ifdef SCSI2_SYNC
1794 if ((info->device[SCpnt->device->id].sync_state == neg_wait ||
1795 info->device[SCpnt->device->id].sync_state == neg_complete) &&
1796 (SCpnt->cmnd[0] == REQUEST_SENSE ||
1797 SCpnt->cmnd[0] == INQUIRY)) {
1798 info->device[SCpnt->device->id].sync_state = neg_inprogress;
1799 msgqueue_addmsg(&info->scsi.msgs, 5,
1800 EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
1801 1000 / info->ifcfg.clockrate,
1802 info->ifcfg.sync_max_depth);
1803 break;
1804 }
1805#endif
1806 } while (0);
1807
1808 __fas216_start_command(info, SCpnt);
1809}
1810
1811static void fas216_allocate_tag(FAS216_Info *info, struct scsi_cmnd *SCpnt)
1812{
1813#ifdef SCSI2_TAG
1814
1815
1816
1817 if (SCpnt->device->simple_tags && SCpnt->cmnd[0] != REQUEST_SENSE &&
1818 SCpnt->cmnd[0] != INQUIRY) {
1819 SCpnt->device->current_tag += 1;
1820 if (SCpnt->device->current_tag == 0)
1821 SCpnt->device->current_tag = 1;
1822 SCpnt->tag = SCpnt->device->current_tag;
1823 } else
1824#endif
1825 set_bit(SCpnt->device->id * 8 +
1826 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
1827
1828 info->stats.removes += 1;
1829 switch (SCpnt->cmnd[0]) {
1830 case WRITE_6:
1831 case WRITE_10:
1832 case WRITE_12:
1833 info->stats.writes += 1;
1834 break;
1835 case READ_6:
1836 case READ_10:
1837 case READ_12:
1838 info->stats.reads += 1;
1839 break;
1840 default:
1841 info->stats.miscs += 1;
1842 break;
1843 }
1844}
1845
1846static void fas216_do_bus_device_reset(FAS216_Info *info,
1847 struct scsi_cmnd *SCpnt)
1848{
1849 struct message *msg;
1850
1851
1852
1853
1854 info->scsi.phase = PHASE_SELECTION;
1855 info->scsi.SCp = SCpnt->SCp;
1856 info->SCpnt = SCpnt;
1857 info->dma.transfer_type = fasdma_none;
1858
1859 fas216_log(info, LOG_ERROR, "sending bus device reset");
1860
1861 msgqueue_flush(&info->scsi.msgs);
1862 msgqueue_addmsg(&info->scsi.msgs, 1, BUS_DEVICE_RESET);
1863
1864
1865 fas216_set_stc(info, 0);
1866 fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
1867
1868
1869 fas216_cmd(info, CMD_FLUSHFIFO);
1870
1871
1872 fas216_writeb(info, REG_SDID, BUSID(SCpnt->device->id));
1873 fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
1874
1875
1876 fas216_set_sync(info, SCpnt->device->id);
1877
1878 msg = msgqueue_getmsg(&info->scsi.msgs, 0);
1879
1880 fas216_writeb(info, REG_FF, BUS_DEVICE_RESET);
1881 msg->fifo = 1;
1882
1883 fas216_cmd(info, CMD_SELECTATNSTOP);
1884}
1885
1886
1887
1888
1889
1890
1891
1892
1893static void fas216_kick(FAS216_Info *info)
1894{
1895 struct scsi_cmnd *SCpnt = NULL;
1896#define TYPE_OTHER 0
1897#define TYPE_RESET 1
1898#define TYPE_QUEUE 2
1899 int where_from = TYPE_OTHER;
1900
1901 fas216_checkmagic(info);
1902
1903
1904
1905
1906 do {
1907 if (info->rstSCpnt) {
1908 SCpnt = info->rstSCpnt;
1909
1910 where_from = TYPE_RESET;
1911 break;
1912 }
1913
1914 if (info->reqSCpnt) {
1915 SCpnt = info->reqSCpnt;
1916 info->reqSCpnt = NULL;
1917 break;
1918 }
1919
1920 if (info->origSCpnt) {
1921 SCpnt = info->origSCpnt;
1922 info->origSCpnt = NULL;
1923 break;
1924 }
1925
1926
1927 if (!SCpnt) {
1928 SCpnt = queue_remove_exclude(&info->queues.issue,
1929 info->busyluns);
1930 where_from = TYPE_QUEUE;
1931 break;
1932 }
1933 } while (0);
1934
1935 if (!SCpnt) {
1936
1937
1938
1939 fas216_cmd(info, CMD_ENABLESEL);
1940 return;
1941 }
1942
1943
1944
1945
1946 fas216_cmd(info, CMD_DISABLESEL);
1947
1948 if (info->scsi.disconnectable && info->SCpnt) {
1949 fas216_log(info, LOG_CONNECT,
1950 "moved command for %d to disconnected queue",
1951 info->SCpnt->device->id);
1952 queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
1953 info->scsi.disconnectable = 0;
1954 info->SCpnt = NULL;
1955 }
1956
1957 fas216_log_command(info, LOG_CONNECT | LOG_MESSAGES, SCpnt,
1958 "starting");
1959
1960 switch (where_from) {
1961 case TYPE_QUEUE:
1962 fas216_allocate_tag(info, SCpnt);
1963 case TYPE_OTHER:
1964 fas216_start_command(info, SCpnt);
1965 break;
1966 case TYPE_RESET:
1967 fas216_do_bus_device_reset(info, SCpnt);
1968 break;
1969 }
1970
1971 fas216_log(info, LOG_CONNECT, "select: data pointers [%p, %X]",
1972 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1973
1974
1975
1976
1977
1978}
1979
1980
1981
1982
1983static void fas216_devicereset_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
1984 unsigned int result)
1985{
1986 fas216_log(info, LOG_ERROR, "fas216 device reset complete");
1987
1988 info->rstSCpnt = NULL;
1989 info->rst_dev_status = 1;
1990 wake_up(&info->eh_wait);
1991}
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
2002 unsigned int result)
2003{
2004 fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
2005 "request sense complete, result=0x%04x%02x%02x",
2006 result, SCpnt->SCp.Message, SCpnt->SCp.Status);
2007
2008 if (result != DID_OK || SCpnt->SCp.Status != GOOD)
2009
2010
2011
2012
2013
2014 memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
2015
2016
2017
2018
2019
2020
2021
2022
2023 scsi_eh_restore_cmnd(SCpnt, &info->ses);
2024 SCpnt->scsi_done(SCpnt);
2025}
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035static void
2036fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result)
2037{
2038 info->stats.fins += 1;
2039
2040 SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 |
2041 info->scsi.SCp.Status;
2042
2043 fas216_log_command(info, LOG_CONNECT, SCpnt,
2044 "command complete, result=0x%08x", SCpnt->result);
2045
2046
2047
2048
2049 if (host_byte(SCpnt->result) != DID_OK ||
2050 msg_byte(SCpnt->result) != COMMAND_COMPLETE)
2051 goto done;
2052
2053
2054
2055
2056
2057 if (status_byte(SCpnt->result) == CHECK_CONDITION ||
2058 status_byte(SCpnt->result) == COMMAND_TERMINATED)
2059 goto request_sense;
2060
2061
2062
2063
2064
2065 if (status_byte(SCpnt->result) != GOOD)
2066 goto done;
2067
2068
2069
2070
2071
2072
2073
2074
2075 if (info->scsi.SCp.ptr) {
2076 switch (SCpnt->cmnd[0]) {
2077 case INQUIRY:
2078 case START_STOP:
2079 case MODE_SENSE:
2080 break;
2081
2082 default:
2083 scmd_printk(KERN_ERR, SCpnt,
2084 "incomplete data transfer detected: res=%08X ptr=%p len=%X\n",
2085 SCpnt->result, info->scsi.SCp.ptr,
2086 info->scsi.SCp.this_residual);
2087 scsi_print_command(SCpnt);
2088 set_host_byte(SCpnt, DID_ERROR);
2089 goto request_sense;
2090 }
2091 }
2092
2093done:
2094 if (SCpnt->scsi_done) {
2095 SCpnt->scsi_done(SCpnt);
2096 return;
2097 }
2098
2099 panic("scsi%d.H: null scsi_done function in fas216_done",
2100 info->host->host_no);
2101
2102
2103request_sense:
2104 if (SCpnt->cmnd[0] == REQUEST_SENSE)
2105 goto done;
2106
2107 scsi_eh_prep_cmnd(SCpnt, &info->ses, NULL, 0, ~0);
2108 fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
2109 "requesting sense");
2110 init_SCp(SCpnt);
2111 SCpnt->SCp.Message = 0;
2112 SCpnt->SCp.Status = 0;
2113 SCpnt->tag = 0;
2114 SCpnt->host_scribble = (void *)fas216_rq_sns_done;
2115
2116
2117
2118
2119
2120
2121 if (info->reqSCpnt)
2122 printk(KERN_WARNING "scsi%d.%c: losing request command\n",
2123 info->host->host_no, '0' + SCpnt->device->id);
2124 info->reqSCpnt = SCpnt;
2125}
2126
2127
2128
2129
2130
2131
2132
2133
2134static void fas216_done(FAS216_Info *info, unsigned int result)
2135{
2136 void (*fn)(FAS216_Info *, struct scsi_cmnd *, unsigned int);
2137 struct scsi_cmnd *SCpnt;
2138 unsigned long flags;
2139
2140 fas216_checkmagic(info);
2141
2142 if (!info->SCpnt)
2143 goto no_command;
2144
2145 SCpnt = info->SCpnt;
2146 info->SCpnt = NULL;
2147 info->scsi.phase = PHASE_IDLE;
2148
2149 if (info->scsi.aborting) {
2150 fas216_log(info, 0, "uncaught abort - returning DID_ABORT");
2151 result = DID_ABORT;
2152 info->scsi.aborting = 0;
2153 }
2154
2155
2156
2157
2158
2159 if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
2160 scmd_printk(KERN_INFO, SCpnt,
2161 "zero bytes left to transfer, but buffer pointer still valid: ptr=%p len=%08x\n",
2162 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
2163 info->scsi.SCp.ptr = NULL;
2164 scsi_print_command(SCpnt);
2165 }
2166
2167
2168
2169
2170
2171
2172 info->device[SCpnt->device->id].parity_check = 0;
2173 clear_bit(SCpnt->device->id * 8 +
2174 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
2175
2176 fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble;
2177 fn(info, SCpnt, result);
2178
2179 if (info->scsi.irq) {
2180 spin_lock_irqsave(&info->host_lock, flags);
2181 if (info->scsi.phase == PHASE_IDLE)
2182 fas216_kick(info);
2183 spin_unlock_irqrestore(&info->host_lock, flags);
2184 }
2185 return;
2186
2187no_command:
2188 panic("scsi%d.H: null command in fas216_done",
2189 info->host->host_no);
2190}
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt,
2202 void (*done)(struct scsi_cmnd *))
2203{
2204 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2205 int result;
2206
2207 fas216_checkmagic(info);
2208
2209 fas216_log_command(info, LOG_CONNECT, SCpnt,
2210 "received command (%p)", SCpnt);
2211
2212 SCpnt->scsi_done = done;
2213 SCpnt->host_scribble = (void *)fas216_std_done;
2214 SCpnt->result = 0;
2215
2216 init_SCp(SCpnt);
2217
2218 info->stats.queues += 1;
2219 SCpnt->tag = 0;
2220
2221 spin_lock(&info->host_lock);
2222
2223
2224
2225
2226
2227 result = !queue_add_cmd_ordered(&info->queues.issue, SCpnt);
2228
2229
2230
2231
2232
2233 if (result == 0 && info->scsi.phase == PHASE_IDLE)
2234 fas216_kick(info);
2235 spin_unlock(&info->host_lock);
2236
2237 fas216_log_target(info, LOG_CONNECT, -1, "queue %s",
2238 result ? "failure" : "success");
2239
2240 return result;
2241}
2242
2243DEF_SCSI_QCMD(fas216_queue_command)
2244
2245
2246
2247
2248
2249
2250
2251static void fas216_internal_done(struct scsi_cmnd *SCpnt)
2252{
2253 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2254
2255 fas216_checkmagic(info);
2256
2257 info->internal_done = 1;
2258}
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt,
2269 void (*done)(struct scsi_cmnd *))
2270{
2271 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2272
2273 fas216_checkmagic(info);
2274
2275
2276
2277
2278
2279 BUG_ON(info->scsi.irq);
2280
2281 info->internal_done = 0;
2282 fas216_queue_command_lck(SCpnt, fas216_internal_done);
2283
2284
2285
2286
2287
2288
2289
2290 spin_unlock_irq(info->host->host_lock);
2291
2292 while (!info->internal_done) {
2293
2294
2295
2296
2297
2298
2299
2300
2301 if (fas216_readb(info, REG_STAT) & STAT_INT) {
2302 spin_lock_irq(info->host->host_lock);
2303 fas216_intr(info);
2304 spin_unlock_irq(info->host->host_lock);
2305 }
2306 }
2307
2308 spin_lock_irq(info->host->host_lock);
2309
2310 done(SCpnt);
2311
2312 return 0;
2313}
2314
2315DEF_SCSI_QCMD(fas216_noqueue_command)
2316
2317
2318
2319
2320
2321static void fas216_eh_timer(unsigned long data)
2322{
2323 FAS216_Info *info = (FAS216_Info *)data;
2324
2325 fas216_log(info, LOG_ERROR, "error handling timed out\n");
2326
2327 del_timer(&info->eh_timer);
2328
2329 if (info->rst_bus_status == 0)
2330 info->rst_bus_status = -1;
2331 if (info->rst_dev_status == 0)
2332 info->rst_dev_status = -1;
2333
2334 wake_up(&info->eh_wait);
2335}
2336
2337enum res_find {
2338 res_failed,
2339 res_success,
2340 res_hw_abort
2341};
2342
2343
2344
2345
2346
2347
2348
2349
2350static enum res_find fas216_find_command(FAS216_Info *info,
2351 struct scsi_cmnd *SCpnt)
2352{
2353 enum res_find res = res_failed;
2354
2355 if (queue_remove_cmd(&info->queues.issue, SCpnt)) {
2356
2357
2358
2359
2360
2361
2362 printk("on issue queue ");
2363
2364 res = res_success;
2365 } else if (queue_remove_cmd(&info->queues.disconnected, SCpnt)) {
2366
2367
2368
2369
2370
2371 printk("on disconnected queue ");
2372
2373 res = res_hw_abort;
2374 } else if (info->SCpnt == SCpnt) {
2375 printk("executing ");
2376
2377 switch (info->scsi.phase) {
2378
2379
2380
2381
2382 case PHASE_IDLE:
2383 if (info->scsi.disconnectable) {
2384 info->scsi.disconnectable = 0;
2385 info->SCpnt = NULL;
2386 res = res_hw_abort;
2387 }
2388 break;
2389
2390 default:
2391 break;
2392 }
2393 } else if (info->origSCpnt == SCpnt) {
2394
2395
2396
2397
2398
2399
2400 info->origSCpnt = NULL;
2401 clear_bit(SCpnt->device->id * 8 +
2402 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
2403 printk("waiting for execution ");
2404 res = res_success;
2405 } else
2406 printk("unknown ");
2407
2408 return res;
2409}
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419int fas216_eh_abort(struct scsi_cmnd *SCpnt)
2420{
2421 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2422 int result = FAILED;
2423
2424 fas216_checkmagic(info);
2425
2426 info->stats.aborts += 1;
2427
2428 scmd_printk(KERN_WARNING, SCpnt, "abort command\n");
2429
2430 print_debug_list();
2431 fas216_dumpstate(info);
2432
2433 switch (fas216_find_command(info, SCpnt)) {
2434
2435
2436
2437
2438
2439 case res_success:
2440 scmd_printk(KERN_WARNING, SCpnt, "abort %p success\n", SCpnt);
2441 result = SUCCESS;
2442 break;
2443
2444
2445
2446
2447
2448
2449 case res_hw_abort:
2450
2451
2452
2453
2454 default:
2455 case res_failed:
2456 scmd_printk(KERN_WARNING, SCpnt, "abort %p failed\n", SCpnt);
2457 break;
2458 }
2459
2460 return result;
2461}
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
2473{
2474 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2475 unsigned long flags;
2476 int i, res = FAILED, target = SCpnt->device->id;
2477
2478 fas216_log(info, LOG_ERROR, "device reset for target %d", target);
2479
2480 spin_lock_irqsave(&info->host_lock, flags);
2481
2482 do {
2483
2484
2485
2486
2487
2488
2489 if (info->SCpnt && !info->scsi.disconnectable &&
2490 info->SCpnt->device->id == SCpnt->device->id)
2491 break;
2492
2493
2494
2495
2496
2497
2498
2499 queue_remove_all_target(&info->queues.issue, target);
2500 queue_remove_all_target(&info->queues.disconnected, target);
2501 if (info->origSCpnt && info->origSCpnt->device->id == target)
2502 info->origSCpnt = NULL;
2503 if (info->reqSCpnt && info->reqSCpnt->device->id == target)
2504 info->reqSCpnt = NULL;
2505 for (i = 0; i < 8; i++)
2506 clear_bit(target * 8 + i, info->busyluns);
2507
2508
2509
2510
2511
2512 SCpnt->host_scribble = (void *)fas216_devicereset_done;
2513
2514 info->rst_dev_status = 0;
2515 info->rstSCpnt = SCpnt;
2516
2517 if (info->scsi.phase == PHASE_IDLE)
2518 fas216_kick(info);
2519
2520 mod_timer(&info->eh_timer, jiffies + 30 * HZ);
2521 spin_unlock_irqrestore(&info->host_lock, flags);
2522
2523
2524
2525
2526 wait_event(info->eh_wait, info->rst_dev_status);
2527
2528 del_timer_sync(&info->eh_timer);
2529 spin_lock_irqsave(&info->host_lock, flags);
2530 info->rstSCpnt = NULL;
2531
2532 if (info->rst_dev_status == 1)
2533 res = SUCCESS;
2534 } while (0);
2535
2536 SCpnt->host_scribble = NULL;
2537 spin_unlock_irqrestore(&info->host_lock, flags);
2538
2539 fas216_log(info, LOG_ERROR, "device reset complete: %s\n",
2540 res == SUCCESS ? "success" : "failed");
2541
2542 return res;
2543}
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt)
2554{
2555 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2556 unsigned long flags;
2557 struct scsi_device *SDpnt;
2558
2559 fas216_checkmagic(info);
2560 fas216_log(info, LOG_ERROR, "resetting bus");
2561
2562 info->stats.bus_resets += 1;
2563
2564 spin_lock_irqsave(&info->host_lock, flags);
2565
2566
2567
2568
2569 fas216_aborttransfer(info);
2570 fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
2571
2572
2573
2574
2575 while (fas216_readb(info, REG_STAT) & STAT_INT)
2576 fas216_readb(info, REG_INST);
2577
2578 info->rst_bus_status = 0;
2579
2580
2581
2582
2583
2584
2585 shost_for_each_device(SDpnt, info->host) {
2586 int i;
2587
2588 if (SDpnt->soft_reset)
2589 continue;
2590
2591 queue_remove_all_target(&info->queues.issue, SDpnt->id);
2592 queue_remove_all_target(&info->queues.disconnected, SDpnt->id);
2593 if (info->origSCpnt && info->origSCpnt->device->id == SDpnt->id)
2594 info->origSCpnt = NULL;
2595 if (info->reqSCpnt && info->reqSCpnt->device->id == SDpnt->id)
2596 info->reqSCpnt = NULL;
2597 info->SCpnt = NULL;
2598
2599 for (i = 0; i < 8; i++)
2600 clear_bit(SDpnt->id * 8 + i, info->busyluns);
2601 }
2602
2603 info->scsi.phase = PHASE_IDLE;
2604
2605
2606
2607
2608
2609 fas216_cmd(info, CMD_RESETSCSI);
2610
2611 mod_timer(&info->eh_timer, jiffies + HZ);
2612 spin_unlock_irqrestore(&info->host_lock, flags);
2613
2614
2615
2616
2617 wait_event(info->eh_wait, info->rst_bus_status);
2618 del_timer_sync(&info->eh_timer);
2619
2620 fas216_log(info, LOG_ERROR, "bus reset complete: %s\n",
2621 info->rst_bus_status == 1 ? "success" : "failed");
2622
2623 return info->rst_bus_status == 1 ? SUCCESS : FAILED;
2624}
2625
2626
2627
2628
2629
2630
2631
2632static void fas216_init_chip(FAS216_Info *info)
2633{
2634 unsigned int clock = ((info->ifcfg.clockrate - 1) / 5 + 1) & 7;
2635 fas216_writeb(info, REG_CLKF, clock);
2636 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2637 fas216_writeb(info, REG_CNTL2, info->scsi.cfg[1]);
2638 fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
2639 fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
2640 fas216_writeb(info, REG_SOF, 0);
2641 fas216_writeb(info, REG_STP, info->scsi.async_stp);
2642 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2643}
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653int fas216_eh_host_reset(struct scsi_cmnd *SCpnt)
2654{
2655 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2656
2657 spin_lock_irq(info->host->host_lock);
2658
2659 fas216_checkmagic(info);
2660
2661 fas216_log(info, LOG_ERROR, "resetting host");
2662
2663
2664
2665
2666 fas216_cmd(info, CMD_RESETCHIP);
2667
2668
2669
2670
2671
2672
2673
2674 spin_unlock_irq(info->host->host_lock);
2675 msleep(50 * 1000/100);
2676 spin_lock_irq(info->host->host_lock);
2677
2678
2679
2680
2681 fas216_cmd(info, CMD_NOP);
2682
2683 fas216_init_chip(info);
2684
2685 spin_unlock_irq(info->host->host_lock);
2686 return SUCCESS;
2687}
2688
2689#define TYPE_UNKNOWN 0
2690#define TYPE_NCR53C90 1
2691#define TYPE_NCR53C90A 2
2692#define TYPE_NCR53C9x 3
2693#define TYPE_Am53CF94 4
2694#define TYPE_EmFAS216 5
2695#define TYPE_QLFAS216 6
2696
2697static char *chip_types[] = {
2698 "unknown",
2699 "NS NCR53C90",
2700 "NS NCR53C90A",
2701 "NS NCR53C9x",
2702 "AMD Am53CF94",
2703 "Emulex FAS216",
2704 "QLogic FAS216"
2705};
2706
2707static int fas216_detect_type(FAS216_Info *info)
2708{
2709 int family, rev;
2710
2711
2712
2713
2714 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2715 udelay(50);
2716 fas216_writeb(info, REG_CMD, CMD_NOP);
2717
2718
2719
2720
2721 fas216_writeb(info, REG_CNTL3, 0);
2722 fas216_writeb(info, REG_CNTL2, CNTL2_S2FE);
2723
2724
2725
2726
2727
2728
2729 if ((fas216_readb(info, REG_CNTL2) & (~0xe0)) != CNTL2_S2FE)
2730 return TYPE_NCR53C90;
2731
2732
2733
2734
2735 fas216_writeb(info, REG_CNTL2, 0);
2736 fas216_writeb(info, REG_CNTL3, 0);
2737 fas216_writeb(info, REG_CNTL3, 5);
2738
2739
2740
2741
2742
2743 if (fas216_readb(info, REG_CNTL3) != 5)
2744 return TYPE_NCR53C90A;
2745
2746
2747
2748
2749 fas216_writeb(info, REG_CNTL3, 0);
2750
2751 fas216_writeb(info, REG_CNTL3, CNTL3_ADIDCHK);
2752 fas216_writeb(info, REG_CNTL3, 0);
2753
2754 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2755 udelay(50);
2756 fas216_writeb(info, REG_CMD, CMD_WITHDMA | CMD_NOP);
2757
2758 fas216_writeb(info, REG_CNTL2, CNTL2_ENF);
2759 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2760 udelay(50);
2761 fas216_writeb(info, REG_CMD, CMD_NOP);
2762
2763 rev = fas216_readb(info, REG_ID);
2764 family = rev >> 3;
2765 rev &= 7;
2766
2767 switch (family) {
2768 case 0x01:
2769 if (rev == 4)
2770 return TYPE_Am53CF94;
2771 break;
2772
2773 case 0x02:
2774 switch (rev) {
2775 case 2:
2776 return TYPE_EmFAS216;
2777 case 3:
2778 return TYPE_QLFAS216;
2779 }
2780 break;
2781
2782 default:
2783 break;
2784 }
2785 printk("family %x rev %x\n", family, rev);
2786 return TYPE_NCR53C9x;
2787}
2788
2789
2790
2791
2792
2793
2794
2795static void fas216_reset_state(FAS216_Info *info)
2796{
2797 int i;
2798
2799 fas216_checkmagic(info);
2800
2801 fas216_bus_reset(info);
2802
2803
2804
2805
2806 memset(info->busyluns, 0, sizeof(info->busyluns));
2807 info->scsi.disconnectable = 0;
2808 info->scsi.aborting = 0;
2809
2810 for (i = 0; i < 8; i++) {
2811 info->device[i].parity_enabled = 0;
2812 info->device[i].parity_check = 1;
2813 }
2814
2815
2816
2817
2818 while (queue_remove(&info->queues.disconnected) != NULL);
2819
2820
2821
2822
2823 info->SCpnt = NULL;
2824 info->reqSCpnt = NULL;
2825 info->rstSCpnt = NULL;
2826 info->origSCpnt = NULL;
2827}
2828
2829
2830
2831
2832
2833
2834
2835
2836int fas216_init(struct Scsi_Host *host)
2837{
2838 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2839
2840 info->magic_start = MAGIC;
2841 info->magic_end = MAGIC;
2842 info->host = host;
2843 info->scsi.cfg[0] = host->this_id | CNTL1_PERE;
2844 info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE;
2845 info->scsi.cfg[2] = info->ifcfg.cntl3 |
2846 CNTL3_ADIDCHK | CNTL3_QTAG | CNTL3_G2CB | CNTL3_LBTM;
2847 info->scsi.async_stp = fas216_syncperiod(info, info->ifcfg.asyncperiod);
2848
2849 info->rst_dev_status = -1;
2850 info->rst_bus_status = -1;
2851 init_waitqueue_head(&info->eh_wait);
2852 init_timer(&info->eh_timer);
2853 info->eh_timer.data = (unsigned long)info;
2854 info->eh_timer.function = fas216_eh_timer;
2855
2856 spin_lock_init(&info->host_lock);
2857
2858 memset(&info->stats, 0, sizeof(info->stats));
2859
2860 msgqueue_initialise(&info->scsi.msgs);
2861
2862 if (!queue_initialise(&info->queues.issue))
2863 return -ENOMEM;
2864
2865 if (!queue_initialise(&info->queues.disconnected)) {
2866 queue_free(&info->queues.issue);
2867 return -ENOMEM;
2868 }
2869
2870 return 0;
2871}
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881int fas216_add(struct Scsi_Host *host, struct device *dev)
2882{
2883 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2884 int type, ret;
2885
2886 if (info->ifcfg.clockrate <= 10 || info->ifcfg.clockrate > 40) {
2887 printk(KERN_CRIT "fas216: invalid clock rate %u MHz\n",
2888 info->ifcfg.clockrate);
2889 return -EINVAL;
2890 }
2891
2892 fas216_reset_state(info);
2893 type = fas216_detect_type(info);
2894 info->scsi.type = chip_types[type];
2895
2896 udelay(300);
2897
2898
2899
2900
2901 fas216_init_chip(info);
2902
2903
2904
2905
2906
2907
2908 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_DISR);
2909 fas216_writeb(info, REG_CMD, CMD_RESETSCSI);
2910
2911
2912
2913
2914 spin_unlock_irq(info->host->host_lock);
2915 msleep(100*1000/100);
2916 spin_lock_irq(info->host->host_lock);
2917
2918 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2919 fas216_readb(info, REG_INST);
2920
2921 fas216_checkmagic(info);
2922
2923 ret = scsi_add_host(host, dev);
2924 if (ret)
2925 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2926 else
2927 scsi_scan_host(host);
2928
2929 return ret;
2930}
2931
2932void fas216_remove(struct Scsi_Host *host)
2933{
2934 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2935
2936 fas216_checkmagic(info);
2937 scsi_remove_host(host);
2938
2939 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2940 scsi_host_put(host);
2941}
2942
2943
2944
2945
2946
2947
2948
2949void fas216_release(struct Scsi_Host *host)
2950{
2951 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2952
2953 queue_free(&info->queues.disconnected);
2954 queue_free(&info->queues.issue);
2955}
2956
2957void fas216_print_host(FAS216_Info *info, struct seq_file *m)
2958{
2959 seq_printf(m,
2960 "\n"
2961 "Chip : %s\n"
2962 " Address: 0x%p\n"
2963 " IRQ : %d\n"
2964 " DMA : %d\n",
2965 info->scsi.type, info->scsi.io_base,
2966 info->scsi.irq, info->scsi.dma);
2967}
2968
2969void fas216_print_stats(FAS216_Info *info, struct seq_file *m)
2970{
2971 seq_printf(m, "\n"
2972 "Command Statistics:\n"
2973 " Queued : %u\n"
2974 " Issued : %u\n"
2975 " Completed : %u\n"
2976 " Reads : %u\n"
2977 " Writes : %u\n"
2978 " Others : %u\n"
2979 " Disconnects: %u\n"
2980 " Aborts : %u\n"
2981 " Bus resets : %u\n"
2982 " Host resets: %u\n",
2983 info->stats.queues, info->stats.removes,
2984 info->stats.fins, info->stats.reads,
2985 info->stats.writes, info->stats.miscs,
2986 info->stats.disconnects, info->stats.aborts,
2987 info->stats.bus_resets, info->stats.host_resets);
2988}
2989
2990void fas216_print_devices(FAS216_Info *info, struct seq_file *m)
2991{
2992 struct fas216_device *dev;
2993 struct scsi_device *scd;
2994
2995 seq_puts(m, "Device/Lun TaggedQ Parity Sync\n");
2996
2997 shost_for_each_device(scd, info->host) {
2998 dev = &info->device[scd->id];
2999 seq_printf(m, " %d/%llu ", scd->id, scd->lun);
3000 if (scd->tagged_supported)
3001 seq_printf(m, "%3sabled(%3d) ",
3002 scd->simple_tags ? "en" : "dis",
3003 scd->current_tag);
3004 else
3005 seq_puts(m, "unsupported ");
3006
3007 seq_printf(m, "%3sabled ", dev->parity_enabled ? "en" : "dis");
3008
3009 if (dev->sof)
3010 seq_printf(m, "offset %d, %d ns\n",
3011 dev->sof, dev->period * 4);
3012 else
3013 seq_puts(m, "async\n");
3014 }
3015}
3016
3017EXPORT_SYMBOL(fas216_init);
3018EXPORT_SYMBOL(fas216_add);
3019EXPORT_SYMBOL(fas216_queue_command);
3020EXPORT_SYMBOL(fas216_noqueue_command);
3021EXPORT_SYMBOL(fas216_intr);
3022EXPORT_SYMBOL(fas216_remove);
3023EXPORT_SYMBOL(fas216_release);
3024EXPORT_SYMBOL(fas216_eh_abort);
3025EXPORT_SYMBOL(fas216_eh_device_reset);
3026EXPORT_SYMBOL(fas216_eh_bus_reset);
3027EXPORT_SYMBOL(fas216_eh_host_reset);
3028EXPORT_SYMBOL(fas216_print_host);
3029EXPORT_SYMBOL(fas216_print_stats);
3030EXPORT_SYMBOL(fas216_print_devices);
3031
3032MODULE_AUTHOR("Russell King");
3033MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver core");
3034MODULE_LICENSE("GPL");
3035