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