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