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#undef SCSI2_TAG
81
82#undef DEBUG_CONNECT
83#undef DEBUG_MESSAGES
84
85#undef CHECK_STRUCTURE
86
87#define LOG_CONNECT (1 << 0)
88#define LOG_BUSSERVICE (1 << 1)
89#define LOG_FUNCTIONDONE (1 << 2)
90#define LOG_MESSAGES (1 << 3)
91#define LOG_BUFFER (1 << 4)
92#define LOG_ERROR (1 << 8)
93
94static int level_mask = LOG_ERROR;
95
96module_param(level_mask, int, 0644);
97
98#ifndef MODULE
99static int __init fas216_log_setup(char *str)
100{
101 char *s;
102
103 level_mask = 0;
104
105 while ((s = strsep(&str, ",")) != NULL) {
106 switch (s[0]) {
107 case 'a':
108 if (strcmp(s, "all") == 0)
109 level_mask |= -1;
110 break;
111 case 'b':
112 if (strncmp(s, "bus", 3) == 0)
113 level_mask |= LOG_BUSSERVICE;
114 if (strncmp(s, "buf", 3) == 0)
115 level_mask |= LOG_BUFFER;
116 break;
117 case 'c':
118 level_mask |= LOG_CONNECT;
119 break;
120 case 'e':
121 level_mask |= LOG_ERROR;
122 break;
123 case 'm':
124 level_mask |= LOG_MESSAGES;
125 break;
126 case 'n':
127 if (strcmp(s, "none") == 0)
128 level_mask = 0;
129 break;
130 case 's':
131 level_mask |= LOG_FUNCTIONDONE;
132 break;
133 }
134 }
135 return 1;
136}
137
138__setup("fas216_logging=", fas216_log_setup);
139#endif
140
141static inline unsigned char fas216_readb(FAS216_Info *info, unsigned int reg)
142{
143 unsigned int off = reg << info->scsi.io_shift;
144 return readb(info->scsi.io_base + off);
145}
146
147static inline void fas216_writeb(FAS216_Info *info, unsigned int reg, unsigned int val)
148{
149 unsigned int off = reg << info->scsi.io_shift;
150 writeb(val, info->scsi.io_base + off);
151}
152
153static void fas216_dumpstate(FAS216_Info *info)
154{
155 unsigned char is, stat, inst;
156
157 is = fas216_readb(info, REG_IS);
158 stat = fas216_readb(info, REG_STAT);
159 inst = fas216_readb(info, REG_INST);
160
161 printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
162 " INST=%02X IS=%02X CFIS=%02X",
163 fas216_readb(info, REG_CTCL),
164 fas216_readb(info, REG_CTCM),
165 fas216_readb(info, REG_CMD), stat, inst, is,
166 fas216_readb(info, REG_CFIS));
167 printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n",
168 fas216_readb(info, REG_CNTL1),
169 fas216_readb(info, REG_CNTL2),
170 fas216_readb(info, REG_CNTL3),
171 fas216_readb(info, REG_CTCH));
172}
173
174static void print_SCp(struct scsi_pointer *SCp, const char *prefix, const char *suffix)
175{
176 printk("%sptr %p this_residual 0x%x buffer %p buffers_residual 0x%x%s",
177 prefix, SCp->ptr, SCp->this_residual, SCp->buffer,
178 SCp->buffers_residual, suffix);
179}
180
181#ifdef CHECK_STRUCTURE
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
226static void __fas216_checkmagic(FAS216_Info *info, const char *func)
227{
228 int corruption = 0;
229 if (info->magic_start != MAGIC) {
230 printk(KERN_CRIT "FAS216 Error: magic at start corrupted\n");
231 corruption++;
232 }
233 if (info->magic_end != MAGIC) {
234 printk(KERN_CRIT "FAS216 Error: magic at end corrupted\n");
235 corruption++;
236 }
237 if (corruption) {
238 fas216_dumpinfo(info);
239 panic("scsi memory space corrupted in %s", func);
240 }
241}
242#define fas216_checkmagic(info) __fas216_checkmagic((info), __func__)
243#else
244#define fas216_checkmagic(info)
245#endif
246
247static const char *fas216_bus_phase(int stat)
248{
249 static const char *phases[] = {
250 "DATA OUT", "DATA IN",
251 "COMMAND", "STATUS",
252 "MISC OUT", "MISC IN",
253 "MESG OUT", "MESG IN"
254 };
255
256 return phases[stat & STAT_BUSMASK];
257}
258
259static const char *fas216_drv_phase(FAS216_Info *info)
260{
261 static const char *phases[] = {
262 [PHASE_IDLE] = "idle",
263 [PHASE_SELECTION] = "selection",
264 [PHASE_COMMAND] = "command",
265 [PHASE_DATAOUT] = "data out",
266 [PHASE_DATAIN] = "data in",
267 [PHASE_MSGIN] = "message in",
268 [PHASE_MSGIN_DISCONNECT]= "disconnect",
269 [PHASE_MSGOUT_EXPECT] = "expect message out",
270 [PHASE_MSGOUT] = "message out",
271 [PHASE_STATUS] = "status",
272 [PHASE_DONE] = "done",
273 };
274
275 if (info->scsi.phase < ARRAY_SIZE(phases) &&
276 phases[info->scsi.phase])
277 return phases[info->scsi.phase];
278 return "???";
279}
280
281static char fas216_target(FAS216_Info *info)
282{
283 if (info->SCpnt)
284 return '0' + info->SCpnt->device->id;
285 else
286 return 'H';
287}
288
289static void
290fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap)
291{
292 static char buf[1024];
293
294 vsnprintf(buf, sizeof(buf), fmt, ap);
295 printk("scsi%d.%c: %s", info->host->host_no, target, buf);
296}
297
298static void fas216_log_command(FAS216_Info *info, int level,
299 struct scsi_cmnd *SCpnt, char *fmt, ...)
300{
301 va_list args;
302
303 if (level != 0 && !(level & level_mask))
304 return;
305
306 va_start(args, fmt);
307 fas216_do_log(info, '0' + SCpnt->device->id, fmt, args);
308 va_end(args);
309
310 scsi_print_command(SCpnt);
311}
312
313static void
314fas216_log_target(FAS216_Info *info, int level, int target, char *fmt, ...)
315{
316 va_list args;
317
318 if (level != 0 && !(level & level_mask))
319 return;
320
321 if (target < 0)
322 target = 'H';
323 else
324 target += '0';
325
326 va_start(args, fmt);
327 fas216_do_log(info, target, fmt, args);
328 va_end(args);
329
330 printk("\n");
331}
332
333static void fas216_log(FAS216_Info *info, int level, char *fmt, ...)
334{
335 va_list args;
336
337 if (level != 0 && !(level & level_mask))
338 return;
339
340 va_start(args, fmt);
341 fas216_do_log(info, fas216_target(info), fmt, args);
342 va_end(args);
343
344 printk("\n");
345}
346
347#define PH_SIZE 32
348
349static struct { int stat, ssr, isr, ph; } ph_list[PH_SIZE];
350static int ph_ptr;
351
352static void add_debug_list(int stat, int ssr, int isr, int ph)
353{
354 ph_list[ph_ptr].stat = stat;
355 ph_list[ph_ptr].ssr = ssr;
356 ph_list[ph_ptr].isr = isr;
357 ph_list[ph_ptr].ph = ph;
358
359 ph_ptr = (ph_ptr + 1) & (PH_SIZE-1);
360}
361
362static struct { int command; void *from; } cmd_list[8];
363static int cmd_ptr;
364
365static void fas216_cmd(FAS216_Info *info, unsigned int command)
366{
367 cmd_list[cmd_ptr].command = command;
368 cmd_list[cmd_ptr].from = __builtin_return_address(0);
369
370 cmd_ptr = (cmd_ptr + 1) & 7;
371
372 fas216_writeb(info, REG_CMD, command);
373}
374
375static void print_debug_list(void)
376{
377 int i;
378
379 i = ph_ptr;
380
381 printk(KERN_ERR "SCSI IRQ trail\n");
382 do {
383 printk(" %02x:%02x:%02x:%1x",
384 ph_list[i].stat, ph_list[i].ssr,
385 ph_list[i].isr, ph_list[i].ph);
386 i = (i + 1) & (PH_SIZE - 1);
387 if (((i ^ ph_ptr) & 7) == 0)
388 printk("\n");
389 } while (i != ph_ptr);
390 if ((i ^ ph_ptr) & 7)
391 printk("\n");
392
393 i = cmd_ptr;
394 printk(KERN_ERR "FAS216 commands: ");
395 do {
396 printk("%02x:%p ", cmd_list[i].command, cmd_list[i].from);
397 i = (i + 1) & 7;
398 } while (i != cmd_ptr);
399 printk("\n");
400}
401
402static void fas216_done(FAS216_Info *info, unsigned int result);
403
404
405
406
407
408
409
410
411static inline unsigned short
412fas216_get_last_msg(FAS216_Info *info, int pos)
413{
414 unsigned short packed_msg = NOP;
415 struct message *msg;
416 int msgnr = 0;
417
418 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
419 if (pos >= msg->fifo)
420 break;
421 }
422
423 if (msg) {
424 if (msg->msg[0] == EXTENDED_MESSAGE)
425 packed_msg = EXTENDED_MESSAGE | msg->msg[2] << 8;
426 else
427 packed_msg = msg->msg[0];
428 }
429
430 fas216_log(info, LOG_MESSAGES,
431 "Message: %04x found at position %02x\n", packed_msg, pos);
432
433 return packed_msg;
434}
435
436
437
438
439
440
441
442
443
444static int fas216_syncperiod(FAS216_Info *info, int ns)
445{
446 int value = (info->ifcfg.clockrate * ns) / 1000;
447
448 fas216_checkmagic(info);
449
450 if (value < 4)
451 value = 4;
452 else if (value > 35)
453 value = 35;
454
455 return value & 31;
456}
457
458
459
460
461
462
463
464
465
466
467
468static void fas216_set_sync(FAS216_Info *info, int target)
469{
470 unsigned int cntl3;
471
472 fas216_writeb(info, REG_SOF, info->device[target].sof);
473 fas216_writeb(info, REG_STP, info->device[target].stp);
474
475 cntl3 = info->scsi.cfg[2];
476 if (info->device[target].period >= (200 / 4))
477 cntl3 = cntl3 & ~CNTL3_FASTSCSI;
478
479 fas216_writeb(info, REG_CNTL3, cntl3);
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
512
513static void fas216_handlesync(FAS216_Info *info, char *msg)
514{
515 struct fas216_device *dev = &info->device[info->SCpnt->device->id];
516 enum { sync, async, none, reject } res = none;
517
518#ifdef SCSI2_SYNC
519 switch (msg[0]) {
520 case MESSAGE_REJECT:
521
522
523
524
525
526
527
528
529
530
531 if (dev->sync_state == neg_inprogress) {
532 dev->sync_state = neg_invalid;
533 res = async;
534 }
535 break;
536
537 case EXTENDED_MESSAGE:
538 switch (dev->sync_state) {
539
540
541
542
543 case neg_invalid:
544 res = reject;
545 break;
546
547
548
549
550
551
552
553 default:
554 fas216_cmd(info, CMD_SETATN);
555 if (msg[4] > info->ifcfg.sync_max_depth)
556 msg[4] = info->ifcfg.sync_max_depth;
557 if (msg[3] < 1000 / info->ifcfg.clockrate)
558 msg[3] = 1000 / info->ifcfg.clockrate;
559
560 msgqueue_flush(&info->scsi.msgs);
561 msgqueue_addmsg(&info->scsi.msgs, 5,
562 EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
563 msg[3], msg[4]);
564 info->scsi.phase = PHASE_MSGOUT_EXPECT;
565
566
567
568
569 dev->sync_state = neg_targcomplete;
570 res = sync;
571 break;
572
573
574
575
576
577
578
579 case neg_inprogress:
580 res = reject;
581 if (msg[4] <= info->ifcfg.sync_max_depth &&
582 msg[3] >= 1000 / info->ifcfg.clockrate) {
583 dev->sync_state = neg_complete;
584 res = sync;
585 }
586 break;
587 }
588 }
589#else
590 res = reject;
591#endif
592
593 switch (res) {
594 case sync:
595 dev->period = msg[3];
596 dev->sof = msg[4];
597 dev->stp = fas216_syncperiod(info, msg[3] * 4);
598 fas216_set_sync(info, info->SCpnt->device->id);
599 break;
600
601 case reject:
602 fas216_cmd(info, CMD_SETATN);
603 msgqueue_flush(&info->scsi.msgs);
604 msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
605 info->scsi.phase = PHASE_MSGOUT_EXPECT;
606
607
608 case async:
609 dev->period = info->ifcfg.asyncperiod / 4;
610 dev->sof = 0;
611 dev->stp = info->scsi.async_stp;
612 fas216_set_sync(info, info->SCpnt->device->id);
613 break;
614
615 case none:
616 break;
617 }
618}
619
620
621
622
623
624
625
626
627static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
628{
629 struct scsi_pointer *SCp = &info->scsi.SCp;
630
631 fas216_checkmagic(info);
632
633 BUG_ON(bytes_transferred < 0);
634
635 SCp->phase -= bytes_transferred;
636
637 while (bytes_transferred != 0) {
638 if (SCp->this_residual > bytes_transferred)
639 break;
640
641
642
643
644 bytes_transferred -= SCp->this_residual;
645 if (!next_SCp(SCp) && bytes_transferred) {
646 printk(KERN_WARNING "scsi%d.%c: out of buffers\n",
647 info->host->host_no, '0' + info->SCpnt->device->id);
648 return;
649 }
650 }
651
652 SCp->this_residual -= bytes_transferred;
653 if (SCp->this_residual)
654 SCp->ptr += bytes_transferred;
655 else
656 SCp->ptr = NULL;
657}
658
659
660
661
662
663
664
665
666
667static void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
668{
669 struct scsi_pointer *SCp = &info->scsi.SCp;
670
671 fas216_checkmagic(info);
672
673 if (direction == DMA_OUT)
674 fas216_writeb(info, REG_FF, get_next_SCp_byte(SCp));
675 else
676 put_next_SCp_byte(SCp, fas216_readb(info, REG_FF));
677
678 if (SCp->this_residual == 0)
679 next_SCp(SCp);
680}
681
682static void fas216_set_stc(FAS216_Info *info, unsigned int length)
683{
684 fas216_writeb(info, REG_STCL, length);
685 fas216_writeb(info, REG_STCM, length >> 8);
686 fas216_writeb(info, REG_STCH, length >> 16);
687}
688
689static unsigned int fas216_get_ctc(FAS216_Info *info)
690{
691 return fas216_readb(info, REG_CTCL) +
692 (fas216_readb(info, REG_CTCM) << 8) +
693 (fas216_readb(info, REG_CTCH) << 16);
694}
695
696
697
698
699
700
701
702
703static void fas216_cleanuptransfer(FAS216_Info *info)
704{
705 unsigned long total, residual, fifo;
706 fasdmatype_t dmatype = info->dma.transfer_type;
707
708 info->dma.transfer_type = fasdma_none;
709
710
711
712
713 if (dmatype == fasdma_pio || dmatype == fasdma_none)
714 return;
715
716 if (dmatype == fasdma_real_all)
717 total = info->scsi.SCp.phase;
718 else
719 total = info->scsi.SCp.this_residual;
720
721 residual = fas216_get_ctc(info);
722
723 fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
724
725 fas216_log(info, LOG_BUFFER, "cleaning up from previous "
726 "transfer: length 0x%06x, residual 0x%x, fifo %d",
727 total, residual, fifo);
728
729
730
731
732
733
734
735 if (info->scsi.phase == PHASE_DATAOUT)
736 residual += fifo;
737
738 fas216_updateptrs(info, total - residual);
739}
740
741
742
743
744
745
746
747static void fas216_transfer(FAS216_Info *info)
748{
749 fasdmadir_t direction;
750 fasdmatype_t dmatype;
751
752 fas216_log(info, LOG_BUFFER,
753 "starttransfer: buffer %p length 0x%06x reqlen 0x%06x",
754 info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
755 info->scsi.SCp.phase);
756
757 if (!info->scsi.SCp.ptr) {
758 fas216_log(info, LOG_ERROR, "null buffer passed to "
759 "fas216_starttransfer");
760 print_SCp(&info->scsi.SCp, "SCp: ", "\n");
761 print_SCp(&info->SCpnt->SCp, "Cmnd SCp: ", "\n");
762 return;
763 }
764
765
766
767
768
769
770 if (info->device[info->SCpnt->device->id].sof)
771 dmatype = fasdma_real_all;
772 else
773 dmatype = fasdma_pio;
774
775 if (info->scsi.phase == PHASE_DATAOUT)
776 direction = DMA_OUT;
777 else
778 direction = DMA_IN;
779
780 if (info->dma.setup)
781 dmatype = info->dma.setup(info->host, &info->scsi.SCp,
782 direction, dmatype);
783 info->dma.transfer_type = dmatype;
784
785 if (dmatype == fasdma_real_all)
786 fas216_set_stc(info, info->scsi.SCp.phase);
787 else
788 fas216_set_stc(info, info->scsi.SCp.this_residual);
789
790 switch (dmatype) {
791 case fasdma_pio:
792 fas216_log(info, LOG_BUFFER, "PIO transfer");
793 fas216_writeb(info, REG_SOF, 0);
794 fas216_writeb(info, REG_STP, info->scsi.async_stp);
795 fas216_cmd(info, CMD_TRANSFERINFO);
796 fas216_pio(info, direction);
797 break;
798
799 case fasdma_pseudo:
800 fas216_log(info, LOG_BUFFER, "pseudo transfer");
801 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
802 info->dma.pseudo(info->host, &info->scsi.SCp,
803 direction, info->SCpnt->transfersize);
804 break;
805
806 case fasdma_real_block:
807 fas216_log(info, LOG_BUFFER, "block dma transfer");
808 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
809 break;
810
811 case fasdma_real_all:
812 fas216_log(info, LOG_BUFFER, "total dma transfer");
813 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
814 break;
815
816 default:
817 fas216_log(info, LOG_BUFFER | LOG_ERROR,
818 "invalid FAS216 DMA type");
819 break;
820 }
821}
822
823
824
825
826
827
828
829static void fas216_stoptransfer(FAS216_Info *info)
830{
831 fas216_checkmagic(info);
832
833 if (info->dma.transfer_type == fasdma_real_all ||
834 info->dma.transfer_type == fasdma_real_block)
835 info->dma.stop(info->host, &info->scsi.SCp);
836
837 fas216_cleanuptransfer(info);
838
839 if (info->scsi.phase == PHASE_DATAIN) {
840 unsigned int fifo;
841
842
843
844
845
846
847 fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
848 while (fifo && info->scsi.SCp.ptr) {
849 *info->scsi.SCp.ptr = fas216_readb(info, REG_FF);
850 fas216_updateptrs(info, 1);
851 fifo--;
852 }
853 } else {
854
855
856
857
858 fas216_cmd(info, CMD_FLUSHFIFO);
859 }
860}
861
862static void fas216_aborttransfer(FAS216_Info *info)
863{
864 fas216_checkmagic(info);
865
866 if (info->dma.transfer_type == fasdma_real_all ||
867 info->dma.transfer_type == fasdma_real_block)
868 info->dma.stop(info->host, &info->scsi.SCp);
869
870 info->dma.transfer_type = fasdma_none;
871 fas216_cmd(info, CMD_FLUSHFIFO);
872}
873
874static void fas216_kick(FAS216_Info *info);
875
876
877
878
879
880
881
882static void fas216_disconnect_intr(FAS216_Info *info)
883{
884 unsigned long flags;
885
886 fas216_checkmagic(info);
887
888 fas216_log(info, LOG_CONNECT, "disconnect phase=%02x",
889 info->scsi.phase);
890
891 msgqueue_flush(&info->scsi.msgs);
892
893 switch (info->scsi.phase) {
894 case PHASE_SELECTION:
895 case PHASE_SELSTEPS:
896 fas216_done(info, DID_NO_CONNECT);
897 break;
898
899 case PHASE_MSGIN_DISCONNECT:
900 info->scsi.disconnectable = 1;
901 info->scsi.phase = PHASE_IDLE;
902 info->stats.disconnects += 1;
903 spin_lock_irqsave(&info->host_lock, flags);
904 if (info->scsi.phase == PHASE_IDLE)
905 fas216_kick(info);
906 spin_unlock_irqrestore(&info->host_lock, flags);
907 break;
908
909 case PHASE_DONE:
910 fas216_done(info, DID_OK);
911 break;
912
913 case PHASE_MSGOUT:
914 if (fas216_get_last_msg(info, info->scsi.msgin_fifo) == ABORT) {
915 info->scsi.aborting = 0;
916 fas216_done(info, DID_ABORT);
917 break;
918 }
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
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
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
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
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->tag)
1794 msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, SCpnt->tag);
1795
1796 do {
1797#ifdef SCSI2_SYNC
1798 if ((info->device[SCpnt->device->id].sync_state == neg_wait ||
1799 info->device[SCpnt->device->id].sync_state == neg_complete) &&
1800 (SCpnt->cmnd[0] == REQUEST_SENSE ||
1801 SCpnt->cmnd[0] == INQUIRY)) {
1802 info->device[SCpnt->device->id].sync_state = neg_inprogress;
1803 msgqueue_addmsg(&info->scsi.msgs, 5,
1804 EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
1805 1000 / info->ifcfg.clockrate,
1806 info->ifcfg.sync_max_depth);
1807 break;
1808 }
1809#endif
1810 } while (0);
1811
1812 __fas216_start_command(info, SCpnt);
1813}
1814
1815static void fas216_allocate_tag(FAS216_Info *info, struct scsi_cmnd *SCpnt)
1816{
1817#ifdef SCSI2_TAG
1818
1819
1820
1821 if (SCpnt->device->simple_tags && SCpnt->cmnd[0] != REQUEST_SENSE &&
1822 SCpnt->cmnd[0] != INQUIRY) {
1823 SCpnt->device->current_tag += 1;
1824 if (SCpnt->device->current_tag == 0)
1825 SCpnt->device->current_tag = 1;
1826 SCpnt->tag = SCpnt->device->current_tag;
1827 } else
1828#endif
1829 set_bit(SCpnt->device->id * 8 +
1830 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
1831
1832 info->stats.removes += 1;
1833 switch (SCpnt->cmnd[0]) {
1834 case WRITE_6:
1835 case WRITE_10:
1836 case WRITE_12:
1837 info->stats.writes += 1;
1838 break;
1839 case READ_6:
1840 case READ_10:
1841 case READ_12:
1842 info->stats.reads += 1;
1843 break;
1844 default:
1845 info->stats.miscs += 1;
1846 break;
1847 }
1848}
1849
1850static void fas216_do_bus_device_reset(FAS216_Info *info,
1851 struct scsi_cmnd *SCpnt)
1852{
1853 struct message *msg;
1854
1855
1856
1857
1858 info->scsi.phase = PHASE_SELECTION;
1859 info->scsi.SCp = SCpnt->SCp;
1860 info->SCpnt = SCpnt;
1861 info->dma.transfer_type = fasdma_none;
1862
1863 fas216_log(info, LOG_ERROR, "sending bus device reset");
1864
1865 msgqueue_flush(&info->scsi.msgs);
1866 msgqueue_addmsg(&info->scsi.msgs, 1, BUS_DEVICE_RESET);
1867
1868
1869 fas216_set_stc(info, 0);
1870 fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
1871
1872
1873 fas216_cmd(info, CMD_FLUSHFIFO);
1874
1875
1876 fas216_writeb(info, REG_SDID, BUSID(SCpnt->device->id));
1877 fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
1878
1879
1880 fas216_set_sync(info, SCpnt->device->id);
1881
1882 msg = msgqueue_getmsg(&info->scsi.msgs, 0);
1883
1884 fas216_writeb(info, REG_FF, BUS_DEVICE_RESET);
1885 msg->fifo = 1;
1886
1887 fas216_cmd(info, CMD_SELECTATNSTOP);
1888}
1889
1890
1891
1892
1893
1894
1895
1896
1897static void fas216_kick(FAS216_Info *info)
1898{
1899 struct scsi_cmnd *SCpnt = NULL;
1900#define TYPE_OTHER 0
1901#define TYPE_RESET 1
1902#define TYPE_QUEUE 2
1903 int where_from = TYPE_OTHER;
1904
1905 fas216_checkmagic(info);
1906
1907
1908
1909
1910 do {
1911 if (info->rstSCpnt) {
1912 SCpnt = info->rstSCpnt;
1913
1914 where_from = TYPE_RESET;
1915 break;
1916 }
1917
1918 if (info->reqSCpnt) {
1919 SCpnt = info->reqSCpnt;
1920 info->reqSCpnt = NULL;
1921 break;
1922 }
1923
1924 if (info->origSCpnt) {
1925 SCpnt = info->origSCpnt;
1926 info->origSCpnt = NULL;
1927 break;
1928 }
1929
1930
1931 if (!SCpnt) {
1932 SCpnt = queue_remove_exclude(&info->queues.issue,
1933 info->busyluns);
1934 where_from = TYPE_QUEUE;
1935 break;
1936 }
1937 } while (0);
1938
1939 if (!SCpnt) {
1940
1941
1942
1943 fas216_cmd(info, CMD_ENABLESEL);
1944 return;
1945 }
1946
1947
1948
1949
1950 fas216_cmd(info, CMD_DISABLESEL);
1951
1952 if (info->scsi.disconnectable && info->SCpnt) {
1953 fas216_log(info, LOG_CONNECT,
1954 "moved command for %d to disconnected queue",
1955 info->SCpnt->device->id);
1956 queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
1957 info->scsi.disconnectable = 0;
1958 info->SCpnt = NULL;
1959 }
1960
1961 fas216_log_command(info, LOG_CONNECT | LOG_MESSAGES, SCpnt,
1962 "starting");
1963
1964 switch (where_from) {
1965 case TYPE_QUEUE:
1966 fas216_allocate_tag(info, SCpnt);
1967
1968 case TYPE_OTHER:
1969 fas216_start_command(info, SCpnt);
1970 break;
1971 case TYPE_RESET:
1972 fas216_do_bus_device_reset(info, SCpnt);
1973 break;
1974 }
1975
1976 fas216_log(info, LOG_CONNECT, "select: data pointers [%p, %X]",
1977 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1978
1979
1980
1981
1982
1983}
1984
1985
1986
1987
1988static void fas216_devicereset_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
1989 unsigned int result)
1990{
1991 fas216_log(info, LOG_ERROR, "fas216 device reset complete");
1992
1993 info->rstSCpnt = NULL;
1994 info->rst_dev_status = 1;
1995 wake_up(&info->eh_wait);
1996}
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
2007 unsigned int result)
2008{
2009 fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
2010 "request sense complete, result=0x%04x%02x%02x",
2011 result, SCpnt->SCp.Message, SCpnt->SCp.Status);
2012
2013 if (result != DID_OK || SCpnt->SCp.Status != GOOD)
2014
2015
2016
2017
2018
2019 memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
2020
2021
2022
2023
2024
2025
2026
2027
2028 scsi_eh_restore_cmnd(SCpnt, &info->ses);
2029 SCpnt->scsi_done(SCpnt);
2030}
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040static void
2041fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result)
2042{
2043 info->stats.fins += 1;
2044
2045 SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 |
2046 info->scsi.SCp.Status;
2047
2048 fas216_log_command(info, LOG_CONNECT, SCpnt,
2049 "command complete, result=0x%08x", SCpnt->result);
2050
2051
2052
2053
2054 if (host_byte(SCpnt->result) != DID_OK ||
2055 msg_byte(SCpnt->result) != COMMAND_COMPLETE)
2056 goto done;
2057
2058
2059
2060
2061
2062 if (status_byte(SCpnt->result) == CHECK_CONDITION ||
2063 status_byte(SCpnt->result) == COMMAND_TERMINATED)
2064 goto request_sense;
2065
2066
2067
2068
2069
2070 if (status_byte(SCpnt->result) != GOOD)
2071 goto done;
2072
2073
2074
2075
2076
2077
2078
2079
2080 if (info->scsi.SCp.ptr) {
2081 switch (SCpnt->cmnd[0]) {
2082 case INQUIRY:
2083 case START_STOP:
2084 case MODE_SENSE:
2085 break;
2086
2087 default:
2088 scmd_printk(KERN_ERR, SCpnt,
2089 "incomplete data transfer detected: res=%08X ptr=%p len=%X\n",
2090 SCpnt->result, info->scsi.SCp.ptr,
2091 info->scsi.SCp.this_residual);
2092 scsi_print_command(SCpnt);
2093 set_host_byte(SCpnt, DID_ERROR);
2094 goto request_sense;
2095 }
2096 }
2097
2098done:
2099 if (SCpnt->scsi_done) {
2100 SCpnt->scsi_done(SCpnt);
2101 return;
2102 }
2103
2104 panic("scsi%d.H: null scsi_done function in fas216_done",
2105 info->host->host_no);
2106
2107
2108request_sense:
2109 if (SCpnt->cmnd[0] == REQUEST_SENSE)
2110 goto done;
2111
2112 scsi_eh_prep_cmnd(SCpnt, &info->ses, NULL, 0, ~0);
2113 fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
2114 "requesting sense");
2115 init_SCp(SCpnt);
2116 SCpnt->SCp.Message = 0;
2117 SCpnt->SCp.Status = 0;
2118 SCpnt->tag = 0;
2119 SCpnt->host_scribble = (void *)fas216_rq_sns_done;
2120
2121
2122
2123
2124
2125
2126 if (info->reqSCpnt)
2127 printk(KERN_WARNING "scsi%d.%c: losing request command\n",
2128 info->host->host_no, '0' + SCpnt->device->id);
2129 info->reqSCpnt = SCpnt;
2130}
2131
2132
2133
2134
2135
2136
2137
2138
2139static void fas216_done(FAS216_Info *info, unsigned int result)
2140{
2141 void (*fn)(FAS216_Info *, struct scsi_cmnd *, unsigned int);
2142 struct scsi_cmnd *SCpnt;
2143 unsigned long flags;
2144
2145 fas216_checkmagic(info);
2146
2147 if (!info->SCpnt)
2148 goto no_command;
2149
2150 SCpnt = info->SCpnt;
2151 info->SCpnt = NULL;
2152 info->scsi.phase = PHASE_IDLE;
2153
2154 if (info->scsi.aborting) {
2155 fas216_log(info, 0, "uncaught abort - returning DID_ABORT");
2156 result = DID_ABORT;
2157 info->scsi.aborting = 0;
2158 }
2159
2160
2161
2162
2163
2164 if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
2165 scmd_printk(KERN_INFO, SCpnt,
2166 "zero bytes left to transfer, but buffer pointer still valid: ptr=%p len=%08x\n",
2167 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
2168 info->scsi.SCp.ptr = NULL;
2169 scsi_print_command(SCpnt);
2170 }
2171
2172
2173
2174
2175
2176
2177 info->device[SCpnt->device->id].parity_check = 0;
2178 clear_bit(SCpnt->device->id * 8 +
2179 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
2180
2181 fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble;
2182 fn(info, SCpnt, result);
2183
2184 if (info->scsi.irq) {
2185 spin_lock_irqsave(&info->host_lock, flags);
2186 if (info->scsi.phase == PHASE_IDLE)
2187 fas216_kick(info);
2188 spin_unlock_irqrestore(&info->host_lock, flags);
2189 }
2190 return;
2191
2192no_command:
2193 panic("scsi%d.H: null command in fas216_done",
2194 info->host->host_no);
2195}
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt,
2207 void (*done)(struct scsi_cmnd *))
2208{
2209 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2210 int result;
2211
2212 fas216_checkmagic(info);
2213
2214 fas216_log_command(info, LOG_CONNECT, SCpnt,
2215 "received command (%p)", SCpnt);
2216
2217 SCpnt->scsi_done = done;
2218 SCpnt->host_scribble = (void *)fas216_std_done;
2219 SCpnt->result = 0;
2220
2221 init_SCp(SCpnt);
2222
2223 info->stats.queues += 1;
2224 SCpnt->tag = 0;
2225
2226 spin_lock(&info->host_lock);
2227
2228
2229
2230
2231
2232 result = !queue_add_cmd_ordered(&info->queues.issue, SCpnt);
2233
2234
2235
2236
2237
2238 if (result == 0 && info->scsi.phase == PHASE_IDLE)
2239 fas216_kick(info);
2240 spin_unlock(&info->host_lock);
2241
2242 fas216_log_target(info, LOG_CONNECT, -1, "queue %s",
2243 result ? "failure" : "success");
2244
2245 return result;
2246}
2247
2248DEF_SCSI_QCMD(fas216_queue_command)
2249
2250
2251
2252
2253
2254
2255
2256static void fas216_internal_done(struct scsi_cmnd *SCpnt)
2257{
2258 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2259
2260 fas216_checkmagic(info);
2261
2262 info->internal_done = 1;
2263}
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt,
2274 void (*done)(struct scsi_cmnd *))
2275{
2276 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2277
2278 fas216_checkmagic(info);
2279
2280
2281
2282
2283
2284 BUG_ON(info->scsi.irq);
2285
2286 info->internal_done = 0;
2287 fas216_queue_command_lck(SCpnt, fas216_internal_done);
2288
2289
2290
2291
2292
2293
2294
2295 spin_unlock_irq(info->host->host_lock);
2296
2297 while (!info->internal_done) {
2298
2299
2300
2301
2302
2303
2304
2305
2306 if (fas216_readb(info, REG_STAT) & STAT_INT) {
2307 spin_lock_irq(info->host->host_lock);
2308 fas216_intr(info);
2309 spin_unlock_irq(info->host->host_lock);
2310 }
2311 }
2312
2313 spin_lock_irq(info->host->host_lock);
2314
2315 done(SCpnt);
2316
2317 return 0;
2318}
2319
2320DEF_SCSI_QCMD(fas216_noqueue_command)
2321
2322
2323
2324
2325
2326static void fas216_eh_timer(struct timer_list *t)
2327{
2328 FAS216_Info *info = from_timer(info, t, eh_timer);
2329
2330 fas216_log(info, LOG_ERROR, "error handling timed out\n");
2331
2332 del_timer(&info->eh_timer);
2333
2334 if (info->rst_bus_status == 0)
2335 info->rst_bus_status = -1;
2336 if (info->rst_dev_status == 0)
2337 info->rst_dev_status = -1;
2338
2339 wake_up(&info->eh_wait);
2340}
2341
2342enum res_find {
2343 res_failed,
2344 res_success,
2345 res_hw_abort
2346};
2347
2348
2349
2350
2351
2352
2353
2354
2355static enum res_find fas216_find_command(FAS216_Info *info,
2356 struct scsi_cmnd *SCpnt)
2357{
2358 enum res_find res = res_failed;
2359
2360 if (queue_remove_cmd(&info->queues.issue, SCpnt)) {
2361
2362
2363
2364
2365
2366
2367 printk("on issue queue ");
2368
2369 res = res_success;
2370 } else if (queue_remove_cmd(&info->queues.disconnected, SCpnt)) {
2371
2372
2373
2374
2375
2376 printk("on disconnected queue ");
2377
2378 res = res_hw_abort;
2379 } else if (info->SCpnt == SCpnt) {
2380 printk("executing ");
2381
2382 switch (info->scsi.phase) {
2383
2384
2385
2386
2387 case PHASE_IDLE:
2388 if (info->scsi.disconnectable) {
2389 info->scsi.disconnectable = 0;
2390 info->SCpnt = NULL;
2391 res = res_hw_abort;
2392 }
2393 break;
2394
2395 default:
2396 break;
2397 }
2398 } else if (info->origSCpnt == SCpnt) {
2399
2400
2401
2402
2403
2404
2405 info->origSCpnt = NULL;
2406 clear_bit(SCpnt->device->id * 8 +
2407 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
2408 printk("waiting for execution ");
2409 res = res_success;
2410 } else
2411 printk("unknown ");
2412
2413 return res;
2414}
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424int fas216_eh_abort(struct scsi_cmnd *SCpnt)
2425{
2426 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2427 int result = FAILED;
2428
2429 fas216_checkmagic(info);
2430
2431 info->stats.aborts += 1;
2432
2433 scmd_printk(KERN_WARNING, SCpnt, "abort command\n");
2434
2435 print_debug_list();
2436 fas216_dumpstate(info);
2437
2438 switch (fas216_find_command(info, SCpnt)) {
2439
2440
2441
2442
2443
2444 case res_success:
2445 scmd_printk(KERN_WARNING, SCpnt, "abort %p success\n", SCpnt);
2446 result = SUCCESS;
2447 break;
2448
2449
2450
2451
2452
2453
2454 case res_hw_abort:
2455
2456
2457
2458
2459 default:
2460 case res_failed:
2461 scmd_printk(KERN_WARNING, SCpnt, "abort %p failed\n", SCpnt);
2462 break;
2463 }
2464
2465 return result;
2466}
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
2478{
2479 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2480 unsigned long flags;
2481 int i, res = FAILED, target = SCpnt->device->id;
2482
2483 fas216_log(info, LOG_ERROR, "device reset for target %d", target);
2484
2485 spin_lock_irqsave(&info->host_lock, flags);
2486
2487 do {
2488
2489
2490
2491
2492
2493
2494 if (info->SCpnt && !info->scsi.disconnectable &&
2495 info->SCpnt->device->id == SCpnt->device->id)
2496 break;
2497
2498
2499
2500
2501
2502
2503
2504 queue_remove_all_target(&info->queues.issue, target);
2505 queue_remove_all_target(&info->queues.disconnected, target);
2506 if (info->origSCpnt && info->origSCpnt->device->id == target)
2507 info->origSCpnt = NULL;
2508 if (info->reqSCpnt && info->reqSCpnt->device->id == target)
2509 info->reqSCpnt = NULL;
2510 for (i = 0; i < 8; i++)
2511 clear_bit(target * 8 + i, info->busyluns);
2512
2513
2514
2515
2516
2517 SCpnt->host_scribble = (void *)fas216_devicereset_done;
2518
2519 info->rst_dev_status = 0;
2520 info->rstSCpnt = SCpnt;
2521
2522 if (info->scsi.phase == PHASE_IDLE)
2523 fas216_kick(info);
2524
2525 mod_timer(&info->eh_timer, jiffies + 30 * HZ);
2526 spin_unlock_irqrestore(&info->host_lock, flags);
2527
2528
2529
2530
2531 wait_event(info->eh_wait, info->rst_dev_status);
2532
2533 del_timer_sync(&info->eh_timer);
2534 spin_lock_irqsave(&info->host_lock, flags);
2535 info->rstSCpnt = NULL;
2536
2537 if (info->rst_dev_status == 1)
2538 res = SUCCESS;
2539 } while (0);
2540
2541 SCpnt->host_scribble = NULL;
2542 spin_unlock_irqrestore(&info->host_lock, flags);
2543
2544 fas216_log(info, LOG_ERROR, "device reset complete: %s\n",
2545 res == SUCCESS ? "success" : "failed");
2546
2547 return res;
2548}
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt)
2559{
2560 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2561 unsigned long flags;
2562 struct scsi_device *SDpnt;
2563
2564 fas216_checkmagic(info);
2565 fas216_log(info, LOG_ERROR, "resetting bus");
2566
2567 info->stats.bus_resets += 1;
2568
2569 spin_lock_irqsave(&info->host_lock, flags);
2570
2571
2572
2573
2574 fas216_aborttransfer(info);
2575 fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
2576
2577
2578
2579
2580 while (fas216_readb(info, REG_STAT) & STAT_INT)
2581 fas216_readb(info, REG_INST);
2582
2583 info->rst_bus_status = 0;
2584
2585
2586
2587
2588
2589
2590 shost_for_each_device(SDpnt, info->host) {
2591 int i;
2592
2593 if (SDpnt->soft_reset)
2594 continue;
2595
2596 queue_remove_all_target(&info->queues.issue, SDpnt->id);
2597 queue_remove_all_target(&info->queues.disconnected, SDpnt->id);
2598 if (info->origSCpnt && info->origSCpnt->device->id == SDpnt->id)
2599 info->origSCpnt = NULL;
2600 if (info->reqSCpnt && info->reqSCpnt->device->id == SDpnt->id)
2601 info->reqSCpnt = NULL;
2602 info->SCpnt = NULL;
2603
2604 for (i = 0; i < 8; i++)
2605 clear_bit(SDpnt->id * 8 + i, info->busyluns);
2606 }
2607
2608 info->scsi.phase = PHASE_IDLE;
2609
2610
2611
2612
2613
2614 fas216_cmd(info, CMD_RESETSCSI);
2615
2616 mod_timer(&info->eh_timer, jiffies + HZ);
2617 spin_unlock_irqrestore(&info->host_lock, flags);
2618
2619
2620
2621
2622 wait_event(info->eh_wait, info->rst_bus_status);
2623 del_timer_sync(&info->eh_timer);
2624
2625 fas216_log(info, LOG_ERROR, "bus reset complete: %s\n",
2626 info->rst_bus_status == 1 ? "success" : "failed");
2627
2628 return info->rst_bus_status == 1 ? SUCCESS : FAILED;
2629}
2630
2631
2632
2633
2634
2635
2636
2637static void fas216_init_chip(FAS216_Info *info)
2638{
2639 unsigned int clock = ((info->ifcfg.clockrate - 1) / 5 + 1) & 7;
2640 fas216_writeb(info, REG_CLKF, clock);
2641 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2642 fas216_writeb(info, REG_CNTL2, info->scsi.cfg[1]);
2643 fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
2644 fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
2645 fas216_writeb(info, REG_SOF, 0);
2646 fas216_writeb(info, REG_STP, info->scsi.async_stp);
2647 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2648}
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658int fas216_eh_host_reset(struct scsi_cmnd *SCpnt)
2659{
2660 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2661
2662 spin_lock_irq(info->host->host_lock);
2663
2664 fas216_checkmagic(info);
2665
2666 fas216_log(info, LOG_ERROR, "resetting host");
2667
2668
2669
2670
2671 fas216_cmd(info, CMD_RESETCHIP);
2672
2673
2674
2675
2676
2677
2678
2679 spin_unlock_irq(info->host->host_lock);
2680 msleep(50 * 1000/100);
2681 spin_lock_irq(info->host->host_lock);
2682
2683
2684
2685
2686 fas216_cmd(info, CMD_NOP);
2687
2688 fas216_init_chip(info);
2689
2690 spin_unlock_irq(info->host->host_lock);
2691 return SUCCESS;
2692}
2693
2694#define TYPE_UNKNOWN 0
2695#define TYPE_NCR53C90 1
2696#define TYPE_NCR53C90A 2
2697#define TYPE_NCR53C9x 3
2698#define TYPE_Am53CF94 4
2699#define TYPE_EmFAS216 5
2700#define TYPE_QLFAS216 6
2701
2702static char *chip_types[] = {
2703 "unknown",
2704 "NS NCR53C90",
2705 "NS NCR53C90A",
2706 "NS NCR53C9x",
2707 "AMD Am53CF94",
2708 "Emulex FAS216",
2709 "QLogic FAS216"
2710};
2711
2712static int fas216_detect_type(FAS216_Info *info)
2713{
2714 int family, rev;
2715
2716
2717
2718
2719 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2720 udelay(50);
2721 fas216_writeb(info, REG_CMD, CMD_NOP);
2722
2723
2724
2725
2726 fas216_writeb(info, REG_CNTL3, 0);
2727 fas216_writeb(info, REG_CNTL2, CNTL2_S2FE);
2728
2729
2730
2731
2732
2733
2734 if ((fas216_readb(info, REG_CNTL2) & (~0xe0)) != CNTL2_S2FE)
2735 return TYPE_NCR53C90;
2736
2737
2738
2739
2740 fas216_writeb(info, REG_CNTL2, 0);
2741 fas216_writeb(info, REG_CNTL3, 0);
2742 fas216_writeb(info, REG_CNTL3, 5);
2743
2744
2745
2746
2747
2748 if (fas216_readb(info, REG_CNTL3) != 5)
2749 return TYPE_NCR53C90A;
2750
2751
2752
2753
2754 fas216_writeb(info, REG_CNTL3, 0);
2755
2756 fas216_writeb(info, REG_CNTL3, CNTL3_ADIDCHK);
2757 fas216_writeb(info, REG_CNTL3, 0);
2758
2759 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2760 udelay(50);
2761 fas216_writeb(info, REG_CMD, CMD_WITHDMA | CMD_NOP);
2762
2763 fas216_writeb(info, REG_CNTL2, CNTL2_ENF);
2764 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2765 udelay(50);
2766 fas216_writeb(info, REG_CMD, CMD_NOP);
2767
2768 rev = fas216_readb(info, REG_ID);
2769 family = rev >> 3;
2770 rev &= 7;
2771
2772 switch (family) {
2773 case 0x01:
2774 if (rev == 4)
2775 return TYPE_Am53CF94;
2776 break;
2777
2778 case 0x02:
2779 switch (rev) {
2780 case 2:
2781 return TYPE_EmFAS216;
2782 case 3:
2783 return TYPE_QLFAS216;
2784 }
2785 break;
2786
2787 default:
2788 break;
2789 }
2790 printk("family %x rev %x\n", family, rev);
2791 return TYPE_NCR53C9x;
2792}
2793
2794
2795
2796
2797
2798
2799
2800static void fas216_reset_state(FAS216_Info *info)
2801{
2802 int i;
2803
2804 fas216_checkmagic(info);
2805
2806 fas216_bus_reset(info);
2807
2808
2809
2810
2811 memset(info->busyluns, 0, sizeof(info->busyluns));
2812 info->scsi.disconnectable = 0;
2813 info->scsi.aborting = 0;
2814
2815 for (i = 0; i < 8; i++) {
2816 info->device[i].parity_enabled = 0;
2817 info->device[i].parity_check = 1;
2818 }
2819
2820
2821
2822
2823 while (queue_remove(&info->queues.disconnected) != NULL);
2824
2825
2826
2827
2828 info->SCpnt = NULL;
2829 info->reqSCpnt = NULL;
2830 info->rstSCpnt = NULL;
2831 info->origSCpnt = NULL;
2832}
2833
2834
2835
2836
2837
2838
2839
2840
2841int fas216_init(struct Scsi_Host *host)
2842{
2843 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2844
2845 info->magic_start = MAGIC;
2846 info->magic_end = MAGIC;
2847 info->host = host;
2848 info->scsi.cfg[0] = host->this_id | CNTL1_PERE;
2849 info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE;
2850 info->scsi.cfg[2] = info->ifcfg.cntl3 |
2851 CNTL3_ADIDCHK | CNTL3_QTAG | CNTL3_G2CB | CNTL3_LBTM;
2852 info->scsi.async_stp = fas216_syncperiod(info, info->ifcfg.asyncperiod);
2853
2854 info->rst_dev_status = -1;
2855 info->rst_bus_status = -1;
2856 init_waitqueue_head(&info->eh_wait);
2857 timer_setup(&info->eh_timer, fas216_eh_timer, 0);
2858
2859 spin_lock_init(&info->host_lock);
2860
2861 memset(&info->stats, 0, sizeof(info->stats));
2862
2863 msgqueue_initialise(&info->scsi.msgs);
2864
2865 if (!queue_initialise(&info->queues.issue))
2866 return -ENOMEM;
2867
2868 if (!queue_initialise(&info->queues.disconnected)) {
2869 queue_free(&info->queues.issue);
2870 return -ENOMEM;
2871 }
2872
2873 return 0;
2874}
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884int fas216_add(struct Scsi_Host *host, struct device *dev)
2885{
2886 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2887 int type, ret;
2888
2889 if (info->ifcfg.clockrate <= 10 || info->ifcfg.clockrate > 40) {
2890 printk(KERN_CRIT "fas216: invalid clock rate %u MHz\n",
2891 info->ifcfg.clockrate);
2892 return -EINVAL;
2893 }
2894
2895 fas216_reset_state(info);
2896 type = fas216_detect_type(info);
2897 info->scsi.type = chip_types[type];
2898
2899 udelay(300);
2900
2901
2902
2903
2904 fas216_init_chip(info);
2905
2906
2907
2908
2909
2910
2911 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_DISR);
2912 fas216_writeb(info, REG_CMD, CMD_RESETSCSI);
2913
2914
2915
2916
2917 spin_unlock_irq(info->host->host_lock);
2918 msleep(100*1000/100);
2919 spin_lock_irq(info->host->host_lock);
2920
2921 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2922 fas216_readb(info, REG_INST);
2923
2924 fas216_checkmagic(info);
2925
2926 ret = scsi_add_host(host, dev);
2927 if (ret)
2928 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2929 else
2930 scsi_scan_host(host);
2931
2932 return ret;
2933}
2934
2935void fas216_remove(struct Scsi_Host *host)
2936{
2937 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2938
2939 fas216_checkmagic(info);
2940 scsi_remove_host(host);
2941
2942 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2943 scsi_host_put(host);
2944}
2945
2946
2947
2948
2949
2950
2951
2952void fas216_release(struct Scsi_Host *host)
2953{
2954 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2955
2956 queue_free(&info->queues.disconnected);
2957 queue_free(&info->queues.issue);
2958}
2959
2960void fas216_print_host(FAS216_Info *info, struct seq_file *m)
2961{
2962 seq_printf(m,
2963 "\n"
2964 "Chip : %s\n"
2965 " Address: 0x%p\n"
2966 " IRQ : %d\n"
2967 " DMA : %d\n",
2968 info->scsi.type, info->scsi.io_base,
2969 info->scsi.irq, info->scsi.dma);
2970}
2971
2972void fas216_print_stats(FAS216_Info *info, struct seq_file *m)
2973{
2974 seq_printf(m, "\n"
2975 "Command Statistics:\n"
2976 " Queued : %u\n"
2977 " Issued : %u\n"
2978 " Completed : %u\n"
2979 " Reads : %u\n"
2980 " Writes : %u\n"
2981 " Others : %u\n"
2982 " Disconnects: %u\n"
2983 " Aborts : %u\n"
2984 " Bus resets : %u\n"
2985 " Host resets: %u\n",
2986 info->stats.queues, info->stats.removes,
2987 info->stats.fins, info->stats.reads,
2988 info->stats.writes, info->stats.miscs,
2989 info->stats.disconnects, info->stats.aborts,
2990 info->stats.bus_resets, info->stats.host_resets);
2991}
2992
2993void fas216_print_devices(FAS216_Info *info, struct seq_file *m)
2994{
2995 struct fas216_device *dev;
2996 struct scsi_device *scd;
2997
2998 seq_puts(m, "Device/Lun TaggedQ Parity Sync\n");
2999
3000 shost_for_each_device(scd, info->host) {
3001 dev = &info->device[scd->id];
3002 seq_printf(m, " %d/%llu ", scd->id, scd->lun);
3003 if (scd->tagged_supported)
3004 seq_printf(m, "%3sabled(%3d) ",
3005 scd->simple_tags ? "en" : "dis",
3006 scd->current_tag);
3007 else
3008 seq_puts(m, "unsupported ");
3009
3010 seq_printf(m, "%3sabled ", dev->parity_enabled ? "en" : "dis");
3011
3012 if (dev->sof)
3013 seq_printf(m, "offset %d, %d ns\n",
3014 dev->sof, dev->period * 4);
3015 else
3016 seq_puts(m, "async\n");
3017 }
3018}
3019
3020EXPORT_SYMBOL(fas216_init);
3021EXPORT_SYMBOL(fas216_add);
3022EXPORT_SYMBOL(fas216_queue_command);
3023EXPORT_SYMBOL(fas216_noqueue_command);
3024EXPORT_SYMBOL(fas216_intr);
3025EXPORT_SYMBOL(fas216_remove);
3026EXPORT_SYMBOL(fas216_release);
3027EXPORT_SYMBOL(fas216_eh_abort);
3028EXPORT_SYMBOL(fas216_eh_device_reset);
3029EXPORT_SYMBOL(fas216_eh_bus_reset);
3030EXPORT_SYMBOL(fas216_eh_host_reset);
3031EXPORT_SYMBOL(fas216_print_host);
3032EXPORT_SYMBOL(fas216_print_stats);
3033EXPORT_SYMBOL(fas216_print_devices);
3034
3035MODULE_AUTHOR("Russell King");
3036MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver core");
3037MODULE_LICENSE("GPL");
3038