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