2 * linux/arch/arm/drivers/scsi/fas216.c
4 * Copyright (C) 1997 Russell King
6 * Based on information in qlogicfas.c by Tom Zerucha, Michael Griffith, and
7 * other sources, including:
8 * the AMD Am53CF94 data sheet
10 * This is a generic driver. To use it, have a look at cumana_2.c. You
11 * should define your own structure that overlays FAS216_Info, eg:
12 * struct my_host_data {
14 * ... my host specific data ...
18 * 30-08-1997 RMK Created
19 * 14-09-1997 RMK Started disconnect support
20 * 08-02-1998 RMK Corrected real DMA support
21 * 15-02-1998 RMK Started sync xfer support
22 * 06-04-1998 RMK Tightened conditions for printing incomplete
24 * 02-05-1998 RMK Added extra checks in fas216_reset
25 * 24-05-1998 RMK Fixed synchronous transfers with period >= 200ns
26 * 27-06-1998 RMK Changed asm/delay.h to linux/delay.h
27 * 26-08-1998 RMK Improved message support wrt MESSAGE_REJECT
30 * - allow individual devices to enable sync xfers.
33 #include <linux/module.h>
34 #include <linux/blk.h>
35 #include <linux/kernel.h>
36 #include <linux/string.h>
37 #include <linux/ioport.h>
38 #include <linux/sched.h>
39 #include <linux/proc_fs.h>
40 #include <linux/unistd.h>
41 #include <linux/stat.h>
42 #include <linux/delay.h>
47 #include <asm/ecard.h>
51 #include "../../scsi/scsi.h"
52 #include "../../scsi/hosts.h"
55 MODULE_AUTHOR("Russell King");
56 MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver");
64 /* NOTE: SCSI2 Synchronous transfers *require* DMA according to
65 * the data sheet. This restriction is crazy, especially when
66 * you only want to send 16 bytes! What were the guys who
67 * designed this chip on at that time? Did they read the SCSI2
68 * spec at all? The following sections are taken from the SCSI2
69 * standard (s2r10) concerning this:
71 * > IMPLEMENTORS NOTES:
72 * > (1) Re-negotiation at every selection is not recommended, since a
73 * > significant performance impact is likely.
75 * > The implied synchronous agreement shall remain in effect until a BUS DEVICE
76 * > RESET message is received, until a hard reset condition occurs, or until one
77 * > of the two SCSI devices elects to modify the agreement. The default data
78 * > transfer mode is asynchronous data transfer mode. The default data transfer
79 * > mode is entered at power on, after a BUS DEVICE RESET message, or after a hard
82 * In total, this means that once you have elected to use synchronous
83 * transfers, you must always use DMA.
85 * I was thinking that this was a good chip until I found this restriction ;(
92 #undef DEBUG_BUSSERVICE
93 #undef DEBUG_FUNCTIONDONE
96 #undef CHECK_STRUCTURE
98 static struct { int stat
, ssr
, isr
, ph
; } list
[8];
101 static void fas216_dumpstate(FAS216_Info
*info
)
103 unsigned char is
, stat
, inst
;
105 is
= inb(REG_IS(info
));
106 stat
= inb(REG_STAT(info
));
107 inst
= inb(REG_INST(info
));
109 printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
110 " INST=%02X IS=%02X CFIS=%02X",
111 inb(REG_CTCL(info
)), inb(REG_CTCM(info
)),
112 inb(REG_CMD(info
)), stat
, inst
, is
,
113 inb(REG_CFIS(info
)));
114 printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n",
115 inb(REG_CNTL1(info
)), inb(REG_CNTL2(info
)),
116 inb(REG_CNTL3(info
)), inb(REG_CTCH(info
)));
119 static void fas216_dumpinfo(FAS216_Info
*info
)
127 printk("FAS216_Info=\n");
128 printk(" { magic_start=%lX host=%p SCpnt=%p origSCpnt=%p\n",
129 info
->magic_start
, info
->host
, info
->SCpnt
,
131 printk(" scsi={ io_port=%X io_shift=%X irq=%X cfg={ %X %X %X %X }\n",
132 info
->scsi
.io_port
, info
->scsi
.io_shift
, info
->scsi
.irq
,
133 info
->scsi
.cfg
[0], info
->scsi
.cfg
[1], info
->scsi
.cfg
[2],
135 printk(" type=%p phase=%X reconnected={ target=%d lun=%d tag=%d }\n",
136 info
->scsi
.type
, info
->scsi
.phase
,
137 info
->scsi
.reconnected
.target
,
138 info
->scsi
.reconnected
.lun
, info
->scsi
.reconnected
.tag
);
139 printk(" SCp={ ptr=%p this_residual=%X buffer=%p buffers_residual=%X }\n",
140 info
->scsi
.SCp
.ptr
, info
->scsi
.SCp
.this_residual
,
141 info
->scsi
.SCp
.buffer
, info
->scsi
.SCp
.buffers_residual
);
142 printk(" msgs async_stp=%X disconnectable=%d aborting=%d }\n",
143 info
->scsi
.async_stp
,
144 info
->scsi
.disconnectable
, info
->scsi
.aborting
);
145 printk(" stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X\n"
146 " disconnects=%X aborts=%X resets=%X }\n",
147 info
->stats
.queues
, info
->stats
.removes
, info
->stats
.fins
,
148 info
->stats
.reads
, info
->stats
.writes
, info
->stats
.miscs
,
149 info
->stats
.disconnects
, info
->stats
.aborts
, info
->stats
.resets
);
150 printk(" ifcfg={ clockrate=%X select_timeout=%X asyncperiod=%X sync_max_depth=%X }\n",
151 info
->ifcfg
.clockrate
, info
->ifcfg
.select_timeout
,
152 info
->ifcfg
.asyncperiod
, info
->ifcfg
.sync_max_depth
);
153 for (i
= 0; i
< 8; i
++) {
154 printk(" busyluns[%d]=%X dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
155 i
, info
->busyluns
[i
], i
,
156 info
->device
[i
].disconnect_ok
, info
->device
[i
].stp
,
157 info
->device
[i
].sof
, info
->device
[i
].sync_state
);
159 printk(" dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
160 info
->dma
.transfer_type
, info
->dma
.setup
,
161 info
->dma
.pseudo
, info
->dma
.stop
);
162 printk(" internal_done=%X magic_end=%lX }\n",
163 info
->internal_done
, info
->magic_end
);
166 #ifdef CHECK_STRUCTURE
167 static void fas216_checkmagic(FAS216_Info
*info
, const char *func
)
170 if (info
->magic_start
!= MAGIC
) {
171 printk(KERN_CRIT
"FAS216 Error: magic at start corrupted\n");
174 if (info
->magic_end
!= MAGIC
) {
175 printk(KERN_CRIT
"FAS216 Error: magic at end corrupted\n");
179 fas216_dumpinfo(info
);
180 panic("scsi memory space corrupted in %s", func
);
184 #define fas216_checkmagic(info,func)
187 static const char *fas216_bus_phase(int stat
)
189 static const char *phases
[] = {
190 "DATA OUT", "DATA IN",
192 "MISC OUT", "MISC IN",
193 "MESG OUT", "MESG IN"
196 return phases
[stat
& STAT_BUSMASK
];
199 static const char *fas216_drv_phase(FAS216_Info
*info
)
201 switch (info
->scsi
.phase
) {
202 case PHASE_IDLE
: return "idle";
203 case PHASE_SELECTION
: return "selection";
204 case PHASE_COMMAND
: return "command";
205 case PHASE_RECONNECTED
: return "reconnected";
206 case PHASE_DATAOUT
: return "data out";
207 case PHASE_DATAIN
: return "data in";
208 case PHASE_MSGIN
: return "message in";
209 case PHASE_MSGIN_DISCONNECT
: return "disconnect";
210 case PHASE_MSGOUT_EXPECT
: return "expect message out";
211 case PHASE_MSGOUT
: return "message out";
212 case PHASE_STATUS
: return "status";
213 case PHASE_DONE
: return "done";
214 default: return "???";
218 static char fas216_target(FAS216_Info
*info
)
221 return '0' + info
->SCpnt
->target
;
226 static void add_debug_list(int stat
, int ssr
, int isr
, int ph
)
228 list
[ptr
].stat
= stat
;
236 static void print_debug_list(void)
242 printk(KERN_ERR
"SCSI IRQ trail: ");
244 printk("%02X:%02X:%02X:%1X ",
245 list
[i
].stat
, list
[i
].ssr
,
246 list
[i
].isr
, list
[i
].ph
);
252 static void fas216_done(FAS216_Info
*info
, unsigned int result
);
254 /* Function: int fas216_clockrate(unsigned int clock)
255 * Purpose : calculate correct value to be written into clock conversion
257 * Params : clock - clock speed in MHz
258 * Returns : CLKF_ value
260 static int fas216_clockrate(int clock
)
262 if (clock
<= 10 || clock
> 40) {
264 "fas216: invalid clock rate: check your driver!\n");
267 clock
= ((clock
- 1) / 5 + 1) & 7;
272 /* Function: unsigned short fas216_get_last_msg(FAS216_Info *info, int pos)
273 * Purpose : retrieve a last message from the list, using position in fifo
274 * Params : info - interface to search
275 * : pos - current fifo position
277 static inline unsigned short
278 fas216_get_last_msg(FAS216_Info
*info
, int pos
)
280 unsigned short packed_msg
= NOP
;
284 while ((msg
= msgqueue_getmsg(&info
->scsi
.msgs
, msgnr
++)) != NULL
) {
285 if (pos
>= msg
->fifo
)
290 if (msg
->msg
[0] == EXTENDED_MESSAGE
)
291 packed_msg
= EXTENDED_MESSAGE
| msg
->msg
[2] << 8;
293 packed_msg
= msg
->msg
[0];
296 #ifdef DEBUG_MESSAGES
297 printk("Message: %04X found at position %02X\n",
303 /* Function: int fas216_syncperiod(FAS216_Info *info, int ns)
304 * Purpose : Calculate value to be loaded into the STP register
305 * for a given period in ns
306 * Params : info - state structure for interface connected to device
307 * : ns - period in ns (between subsequent bytes)
308 * Returns : Value suitable for REG_STP
311 fas216_syncperiod(FAS216_Info
*info
, int ns
)
313 int value
= (info
->ifcfg
.clockrate
* ns
) / 1000;
315 fas216_checkmagic(info
, "fas216_syncperiod");
325 /* Function: void fas216_set_sync(FAS216_Info *info, int target)
326 * Purpose : Correctly setup FAS216 chip for specified transfer period.
327 * Params : info - state structure for interface
329 * Notes : we need to switch the chip out of FASTSCSI mode if we have
330 * a transfer period >= 200ns - otherwise the chip will violate
334 fas216_set_sync(FAS216_Info
*info
, int target
)
336 outb(info
->device
[target
].sof
, REG_SOF(info
));
337 outb(info
->device
[target
].stp
, REG_STP(info
));
338 if (info
->device
[target
].period
>= (200 / 4))
339 outb(info
->scsi
.cfg
[2] & ~CNTL3_FASTSCSI
, REG_CNTL3(info
));
341 outb(info
->scsi
.cfg
[2], REG_CNTL3(info
));
344 /* Synchronous transfer support
346 * Note: The SCSI II r10 spec says (5.6.12):
348 * (2) Due to historical problems with early host adapters that could
349 * not accept an SDTR message, some targets may not initiate synchronous
350 * negotiation after a power cycle as required by this standard. Host
351 * adapters that support synchronous mode may avoid the ensuing failure
352 * modes when the target is independently power cycled by initiating a
353 * synchronous negotiation on each REQUEST SENSE and INQUIRY command.
354 * This approach increases the SCSI bus overhead and is not recommended
355 * for new implementations. The correct method is to respond to an
356 * SDTR message with a MESSAGE REJECT message if the either the
357 * initiator or target devices does not support synchronous transfers
358 * or does not want to negotiate for synchronous transfers at the time.
359 * Using the correct method assures compatibility with wide data
360 * transfers and future enhancements.
362 * We will always initiate a synchronous transfer negociation request on
363 * every INQUIRY or REQUEST SENSE message, unless the target itself has
364 * at some point performed a synchronous transfer negociation request, or
365 * we have synchronous transfers disabled for this device.
368 /* Function: void fas216_handlesync(FAS216_Info *info, char *msg)
369 * Purpose : Handle a synchronous transfer message from the target
370 * Params : info - state structure for interface
371 * : msg - message from target
374 fas216_handlesync(FAS216_Info
*info
, char *msg
)
376 struct fas216_device
*dev
= &info
->device
[info
->SCpnt
->target
];
377 enum { sync
, async
, none
, reject
} res
= none
;
382 /* Synchronous transfer request failed.
385 * SCSI devices that are capable of synchronous
386 * data transfers shall not respond to an SDTR
387 * message with a MESSAGE REJECT message.
389 * Hence, if we get this condition, we disable
390 * negociation for this device.
392 if (dev
->sync_state
== neg_inprogress
) {
393 dev
->sync_state
= neg_invalid
;
398 case EXTENDED_MESSAGE
:
399 switch (dev
->sync_state
) {
400 /* We don't accept synchronous transfer requests.
401 * Respond with a MESSAGE_REJECT to prevent a
402 * synchronous transfer agreement from being reached.
408 /* We were not negociating a synchronous transfer,
409 * but the device sent us a negociation request.
410 * Honour the request by sending back a SDTR
411 * message containing our capability, limited by
412 * the targets capability.
415 outb(CMD_SETATN
, REG_CMD(info
));
416 if (msg
[4] > info
->ifcfg
.sync_max_depth
)
417 msg
[4] = info
->ifcfg
.sync_max_depth
;
418 if (msg
[3] < 1000 / info
->ifcfg
.clockrate
)
419 msg
[3] = 1000 / info
->ifcfg
.clockrate
;
421 msgqueue_flush(&info
->scsi
.msgs
);
422 msgqueue_addmsg(&info
->scsi
.msgs
, 5,
423 EXTENDED_MESSAGE
, 3, EXTENDED_SDTR
,
425 info
->scsi
.phase
= PHASE_MSGOUT_EXPECT
;
427 /* This is wrong. The agreement is not in effect
428 * until this message is accepted by the device
430 dev
->sync_state
= neg_targcomplete
;
434 /* We initiated the synchronous transfer negociation,
435 * and have successfully received a response from the
436 * target. The synchronous transfer agreement has been
437 * reached. Note: if the values returned are out of our
438 * bounds, we must reject the message.
442 if (msg
[4] <= info
->ifcfg
.sync_max_depth
&&
443 msg
[3] >= 1000 / info
->ifcfg
.clockrate
) {
444 dev
->sync_state
= neg_complete
;
456 dev
->period
= msg
[3];
458 dev
->stp
= fas216_syncperiod(info
, msg
[3] * 4);
459 fas216_set_sync(info
, info
->SCpnt
->target
);
463 outb(CMD_SETATN
, REG_CMD(info
));
464 msgqueue_flush(&info
->scsi
.msgs
);
465 msgqueue_addmsg(&info
->scsi
.msgs
, 1, MESSAGE_REJECT
);
466 info
->scsi
.phase
= PHASE_MSGOUT_EXPECT
;
469 dev
->period
= info
->ifcfg
.asyncperiod
/ 4;
471 dev
->stp
= info
->scsi
.async_stp
;
472 fas216_set_sync(info
, info
->SCpnt
->target
);
480 /* Function: void fas216_handlewide(FAS216_Info *info, char *msg)
481 * Purpose : Handle a wide transfer message from the target
482 * Params : info - state structure for interface
483 * : msg - message from target
486 fas216_handlewide(FAS216_Info
*info
, char *msg
)
488 struct fas216_device
*dev
= &info
->device
[info
->SCpnt
->target
];
489 enum { wide
, bit8
, none
, reject
} res
= none
;
494 /* Wide transfer request failed.
497 * SCSI devices that are capable of wide
498 * data transfers shall not respond to a
499 * WDTR message with a MESSAGE REJECT message.
501 * Hence, if we get this condition, we never
502 * reattempt negociation for this device.
504 if (dev
->wide_state
== neg_inprogress
) {
505 dev
->wide_state
= neg_invalid
;
510 case EXTENDED_MESSAGE
:
511 switch (dev
->wide_state
) {
512 /* We don't accept wide data transfer requests.
513 * Respond with a MESSAGE REJECT to prevent a
514 * wide data transfer agreement from being reached.
520 /* We were not negociating a wide data transfer,
521 * but the device sent is a negociation request.
522 * Honour the request by sending back a WDTR
523 * message containing our capability, limited by
524 * the targets capability.
527 outb(CMD_SETATN
, REG_CMD(info
));
528 if (msg
[3] > info
->ifcfg
.wide_max_size
)
529 msg
[3] = info
->ifcfg
.wide_max_size
;
531 msgqueue_flush(&info
->scsi
.msgs
);
532 msgqueue_addmsg(&info
->scsi
.msgs
, 4,
533 EXTENDED_MESSAGE
, 2, EXTENDED_WDTR
,
535 info
->scsi
.phase
= PHASE_MSGOUT_EXPECT
;
539 /* We initiated the wide data transfer negociation,
540 * and have successfully received a response from the
541 * target. The synchronous transfer agreement has been
542 * reached. Note: if the values returned are out of our
543 * bounds, we must reject the message.
547 if (msg
[3] <= info
->ifcfg
.wide_max_size
) {
548 dev
->wide_state
= neg_complete
;
560 dev
->wide_xfer
= msg
[3];
564 outb(CMD_SETATN
, REG_CMD(info
));
565 msgqueue_flush(&info
->scsi
.msgs
);
566 msgqueue_addmsg(&info
->scsi
.msgs
, 1, MESSAGE_REJECT
);
567 info
->scsi
.phase
= PHASE_MSGOUT_EXPECT
;
578 /* Function: void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
579 * Purpose : update data pointers after transfer suspended/paused
580 * Params : info - interface's local pointer to update
581 * bytes_transferred - number of bytes transferred
584 fas216_updateptrs(FAS216_Info
*info
, int bytes_transferred
)
587 unsigned int residual
;
589 fas216_checkmagic(info
, "fas216_updateptrs");
591 ptr
= info
->scsi
.SCp
.ptr
;
592 residual
= info
->scsi
.SCp
.this_residual
;
594 info
->SCpnt
->request_bufflen
-= bytes_transferred
;
596 while (residual
<= bytes_transferred
&& bytes_transferred
) {
597 /* We have used up this buffer */
598 bytes_transferred
-= residual
;
599 if (info
->scsi
.SCp
.buffers_residual
) {
600 info
->scsi
.SCp
.buffer
++;
601 info
->scsi
.SCp
.buffers_residual
--;
602 ptr
= (unsigned char *)info
->scsi
.SCp
.buffer
->address
;
603 residual
= info
->scsi
.SCp
.buffer
->length
;
610 residual
-= bytes_transferred
;
611 ptr
+= bytes_transferred
;
616 info
->scsi
.SCp
.ptr
= ptr
;
617 info
->scsi
.SCp
.this_residual
= residual
;
620 /* Function: void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
621 * Purpose : transfer data off of/on to card using programmed IO
622 * Params : info - interface to transfer data to/from
623 * direction - direction to transfer data (DMA_OUT/DMA_IN)
624 * Notes : this is incredibly slow
627 fas216_pio(FAS216_Info
*info
, fasdmadir_t direction
)
629 unsigned int residual
;
632 fas216_checkmagic(info
, "fas216_pio");
634 residual
= info
->scsi
.SCp
.this_residual
;
635 ptr
= info
->scsi
.SCp
.ptr
;
637 if (direction
== DMA_OUT
)
638 outb(*ptr
++, REG_FF(info
));
640 *ptr
++ = inb(REG_FF(info
));
645 if (info
->scsi
.SCp
.buffers_residual
) {
646 info
->scsi
.SCp
.buffer
++;
647 info
->scsi
.SCp
.buffers_residual
--;
648 ptr
= (unsigned char *)info
->scsi
.SCp
.buffer
->address
;
649 residual
= info
->scsi
.SCp
.buffer
->length
;
656 info
->scsi
.SCp
.ptr
= ptr
;
657 info
->scsi
.SCp
.this_residual
= residual
;
660 /* Function: void fas216_starttransfer(FAS216_Info *info,
661 * fasdmadir_t direction)
662 * Purpose : Start a DMA/PIO transfer off of/on to card
663 * Params : info - interface from which device disconnected from
664 * direction - transfer direction (DMA_OUT/DMA_IN)
667 fas216_starttransfer(FAS216_Info
*info
, fasdmadir_t direction
, int flush_fifo
)
669 fasdmatype_t dmatype
;
671 fas216_checkmagic(info
, "fas216_starttransfer");
673 info
->scsi
.phase
= (direction
== DMA_OUT
) ?
674 PHASE_DATAOUT
: PHASE_DATAIN
;
676 if (info
->dma
.transfer_type
!= fasdma_none
&&
677 info
->dma
.transfer_type
!= fasdma_pio
) {
678 unsigned long total
, residual
;
680 if (info
->dma
.transfer_type
== fasdma_real_all
)
681 total
= info
->SCpnt
->request_bufflen
;
683 total
= info
->scsi
.SCp
.this_residual
;
685 residual
= (inb(REG_CFIS(info
)) & CFIS_CF
) +
686 inb(REG_CTCL(info
)) +
687 (inb(REG_CTCM(info
)) << 8) +
688 (inb(REG_CTCH(info
)) << 16);
689 fas216_updateptrs(info
, total
- residual
);
691 info
->dma
.transfer_type
= fasdma_none
;
693 if (!info
->scsi
.SCp
.ptr
) {
694 printk("scsi%d.%c: null buffer passed to "
695 "fas216_starttransfer\n", info
->host
->host_no
,
696 fas216_target(info
));
702 outb(CMD_FLUSHFIFO
, REG_CMD(info
));
705 * Default to PIO mode or DMA mode if we have a synchronous
706 * transfer agreement.
708 if (info
->device
[info
->SCpnt
->target
].sof
&& info
->dma
.setup
)
709 dmatype
= fasdma_real_all
;
711 dmatype
= fasdma_pio
;
714 dmatype
= info
->dma
.setup(info
->host
, &info
->scsi
.SCp
,
716 info
->dma
.transfer_type
= dmatype
;
720 outb(0, REG_SOF(info
));
721 outb(info
->scsi
.async_stp
, REG_STP(info
));
722 outb(info
->scsi
.SCp
.this_residual
, REG_STCL(info
));
723 outb(info
->scsi
.SCp
.this_residual
>> 8, REG_STCM(info
));
724 outb(info
->scsi
.SCp
.this_residual
>> 16, REG_STCH(info
));
725 outb(CMD_TRANSFERINFO
, REG_CMD(info
));
726 fas216_pio(info
, direction
);
730 outb(info
->scsi
.SCp
.this_residual
, REG_STCL(info
));
731 outb(info
->scsi
.SCp
.this_residual
>> 8, REG_STCM(info
));
732 outb(info
->scsi
.SCp
.this_residual
>> 16, REG_STCH(info
));
733 outb(CMD_TRANSFERINFO
| CMD_WITHDMA
, REG_CMD(info
));
734 info
->dma
.pseudo(info
->host
, &info
->scsi
.SCp
,
735 direction
, info
->SCpnt
->transfersize
);
738 case fasdma_real_block
:
739 outb(info
->scsi
.SCp
.this_residual
, REG_STCL(info
));
740 outb(info
->scsi
.SCp
.this_residual
>> 8, REG_STCM(info
));
741 outb(info
->scsi
.SCp
.this_residual
>> 16, REG_STCH(info
));
742 outb(CMD_TRANSFERINFO
| CMD_WITHDMA
, REG_CMD(info
));
745 case fasdma_real_all
:
746 outb(info
->SCpnt
->request_bufflen
, REG_STCL(info
));
747 outb(info
->SCpnt
->request_bufflen
>> 8, REG_STCM(info
));
748 outb(info
->SCpnt
->request_bufflen
>> 16, REG_STCH(info
));
749 outb(CMD_TRANSFERINFO
| CMD_WITHDMA
, REG_CMD(info
));
753 printk(KERN_ERR
"scsi%d.%d: invalid FAS216 DMA type\n",
754 info
->host
->host_no
, fas216_target(info
));
759 /* Function: void fas216_stoptransfer(FAS216_Info *info)
760 * Purpose : Stop a DMA transfer onto / off of the card
761 * Params : info - interface from which device disconnected from
764 fas216_stoptransfer(FAS216_Info
*info
)
766 fas216_checkmagic(info
, "fas216_stoptransfer");
768 if (info
->dma
.transfer_type
!= fasdma_none
&&
769 info
->dma
.transfer_type
!= fasdma_pio
) {
770 unsigned long total
, residual
;
772 if ((info
->dma
.transfer_type
== fasdma_real_all
||
773 info
->dma
.transfer_type
== fasdma_real_block
) &&
775 info
->dma
.stop(info
->host
, &info
->scsi
.SCp
);
777 if (info
->dma
.transfer_type
== fasdma_real_all
)
778 total
= info
->SCpnt
->request_bufflen
;
780 total
= info
->scsi
.SCp
.this_residual
;
782 residual
= (inb(REG_CFIS(info
)) & CFIS_CF
) +
783 inb(REG_CTCL(info
)) +
784 (inb(REG_CTCM(info
)) << 8) +
785 (inb(REG_CTCH(info
)) << 16);
786 fas216_updateptrs(info
, total
- residual
);
787 info
->dma
.transfer_type
= fasdma_none
;
789 if (info
->scsi
.phase
== PHASE_DATAOUT
)
790 outb(CMD_FLUSHFIFO
, REG_CMD(info
));
793 /* Function: void fas216_disconnected_intr(FAS216_Info *info)
794 * Purpose : handle device disconnection
795 * Params : info - interface from which device disconnected from
798 fas216_disconnect_intr(FAS216_Info
*info
)
800 fas216_checkmagic(info
, "fas216_disconnected_intr");
803 printk("scsi%d.%c: disconnect phase=%02X\n", info
->host
->host_no
,
804 fas216_target(info
), info
->scsi
.phase
);
806 msgqueue_flush(&info
->scsi
.msgs
);
808 switch (info
->scsi
.phase
) {
809 case PHASE_SELECTION
: /* while selecting - no target */
811 fas216_done(info
, DID_NO_CONNECT
);
814 case PHASE_MSGIN_DISCONNECT
: /* message in - disconnecting */
815 outb(CMD_ENABLESEL
, REG_CMD(info
));
816 info
->scsi
.disconnectable
= 1;
817 info
->scsi
.reconnected
.tag
= 0;
818 info
->scsi
.phase
= PHASE_IDLE
;
819 info
->stats
.disconnects
+= 1;
822 case PHASE_DONE
: /* at end of command - complete */
823 fas216_done(info
, DID_OK
);
826 case PHASE_MSGOUT
: /* message out - possible ABORT message */
827 if (fas216_get_last_msg(info
, info
->scsi
.msgin_fifo
) == ABORT
) {
828 info
->scsi
.aborting
= 0;
829 fas216_done(info
, DID_ABORT
);
834 printk(KERN_ERR
"scsi%d.%c: unexpected disconnect in phase %s\n",
835 info
->host
->host_no
, fas216_target(info
), fas216_drv_phase(info
));
837 fas216_stoptransfer(info
);
838 fas216_done(info
, DID_ERROR
);
843 /* Function: void fas216_reselected_intr(FAS216_Info *info)
844 * Purpose : Start reconnection of a device
845 * Params : info - interface which was reselected
848 fas216_reselected_intr(FAS216_Info
*info
)
850 unsigned char target
, identify_msg
, ok
;
852 fas216_checkmagic(info
, "fas216_reselected_intr");
854 if ((info
->scsi
.phase
== PHASE_SELECTION
||
855 info
->scsi
.phase
== PHASE_SELSTEPS
) && info
->SCpnt
) {
856 Scsi_Cmnd
*SCpnt
= info
->SCpnt
;
858 info
->origSCpnt
= SCpnt
;
861 if (info
->device
[SCpnt
->target
].wide_state
== neg_inprogress
)
862 info
->device
[SCpnt
->target
].wide_state
= neg_wait
;
863 if (info
->device
[SCpnt
->target
].sync_state
== neg_inprogress
)
864 info
->device
[SCpnt
->target
].sync_state
= neg_wait
;
868 printk("scsi%d.%c: reconnect phase=%02X\n", info
->host
->host_no
,
869 fas216_target(info
), info
->scsi
.phase
);
872 if ((inb(REG_CFIS(info
)) & CFIS_CF
) != 2) {
873 printk(KERN_ERR
"scsi%d.H: incorrect number of bytes after reselect\n",
874 info
->host
->host_no
);
875 outb(CMD_SETATN
, REG_CMD(info
));
876 outb(CMD_MSGACCEPTED
, REG_CMD(info
));
877 msgqueue_flush(&info
->scsi
.msgs
);
878 msgqueue_addmsg(&info
->scsi
.msgs
, 1, INITIATOR_ERROR
);
879 info
->scsi
.phase
= PHASE_MSGOUT_EXPECT
;
883 target
= inb(REG_FF(info
));
884 identify_msg
= inb(REG_FF(info
));
887 if (!(target
& (1 << info
->host
->this_id
))) {
888 printk(KERN_ERR
"scsi%d.H: invalid host id on reselect\n", info
->host
->host_no
);
892 if (!(identify_msg
& 0x80)) {
893 printk(KERN_ERR
"scsi%d.H: no IDENTIFY message on reselect, got msg %02X\n",
894 info
->host
->host_no
, identify_msg
);
900 * Something went wrong - send an initiator error to
903 outb(CMD_SETATN
, REG_CMD(info
));
904 outb(CMD_MSGACCEPTED
, REG_CMD(info
));
905 msgqueue_flush(&info
->scsi
.msgs
);
906 msgqueue_addmsg(&info
->scsi
.msgs
, 1, INITIATOR_ERROR
);
907 info
->scsi
.phase
= PHASE_MSGOUT_EXPECT
;
911 target
&= ~(1 << info
->host
->this_id
);
913 case 1: target
= 0; break;
914 case 2: target
= 1; break;
915 case 4: target
= 2; break;
916 case 8: target
= 3; break;
917 case 16: target
= 4; break;
918 case 32: target
= 5; break;
919 case 64: target
= 6; break;
920 case 128: target
= 7; break;
921 default: target
= info
->host
->this_id
; break;
925 info
->scsi
.reconnected
.target
= target
;
926 info
->scsi
.reconnected
.lun
= identify_msg
;
927 info
->scsi
.reconnected
.tag
= 0;
930 if (info
->scsi
.disconnectable
&& info
->SCpnt
&&
931 info
->SCpnt
->target
== target
&& info
->SCpnt
->lun
== identify_msg
)
934 if (!ok
&& queue_probetgtlun(&info
->queues
.disconnected
, target
, identify_msg
))
937 msgqueue_flush(&info
->scsi
.msgs
);
939 info
->scsi
.phase
= PHASE_RECONNECTED
;
940 outb(target
, REG_SDID(info
));
943 * Our command structure not found - abort the
944 * command on the target. Since we have no
945 * record of this command, we can't send
946 * an INITIATOR DETECTED ERROR message.
948 outb(CMD_SETATN
, REG_CMD(info
));
949 msgqueue_addmsg(&info
->scsi
.msgs
, 1, ABORT
);
950 info
->scsi
.phase
= PHASE_MSGOUT_EXPECT
;
952 outb(CMD_MSGACCEPTED
, REG_CMD(info
));
955 /* Function: void fas216_finish_reconnect(FAS216_Info *info)
956 * Purpose : finish reconnection sequence for device
957 * Params : info - interface which caused function done interrupt
960 fas216_finish_reconnect(FAS216_Info
*info
)
962 fas216_checkmagic(info
, "fas216_reconnect");
965 printk("Connected: %1X %1X %02X, reconnected: %1X %1X %02X\n",
966 info
->SCpnt
->target
, info
->SCpnt
->lun
, info
->SCpnt
->tag
,
967 info
->scsi
.reconnected
.target
, info
->scsi
.reconnected
.lun
,
968 info
->scsi
.reconnected
.tag
);
971 if (info
->scsi
.disconnectable
&& info
->SCpnt
) {
972 info
->scsi
.disconnectable
= 0;
973 if (info
->SCpnt
->target
== info
->scsi
.reconnected
.target
&&
974 info
->SCpnt
->lun
== info
->scsi
.reconnected
.lun
&&
975 info
->SCpnt
->tag
== info
->scsi
.reconnected
.tag
) {
977 printk("scsi%d.%c: reconnected",
978 info
->host
->host_no
, fas216_target(info
));
981 queue_add_cmd_tail(&info
->queues
.disconnected
, info
->SCpnt
);
983 printk("scsi%d.%c: had to move command to disconnected queue\n",
984 info
->host
->host_no
, fas216_target(info
));
990 info
->SCpnt
= queue_remove_tgtluntag(&info
->queues
.disconnected
,
991 info
->scsi
.reconnected
.target
,
992 info
->scsi
.reconnected
.lun
,
993 info
->scsi
.reconnected
.tag
);
995 printk("scsi%d.%c: had to get command",
996 info
->host
->host_no
, fas216_target(info
));
1000 outb(CMD_SETATN
, REG_CMD(info
));
1001 msgqueue_flush(&info
->scsi
.msgs
);
1003 if (info
->scsi
.reconnected
.tag
)
1004 msgqueue_addmsg(&info
->scsi
.msgs
, 2, ABORT_TAG
, info
->scsi
.reconnected
.tag
);
1007 msgqueue_addmsg(&info
->scsi
.msgs
, 1, ABORT
);
1008 info
->scsi
.phase
= PHASE_MSGOUT_EXPECT
;
1009 info
->scsi
.aborting
= 1;
1012 * Restore data pointer from SAVED data pointer
1014 info
->scsi
.SCp
= info
->SCpnt
->SCp
;
1015 #ifdef DEBUG_CONNECT
1016 printk(", data pointers: [%p, %X]",
1017 info
->scsi
.SCp
.ptr
, info
->scsi
.SCp
.this_residual
);
1020 #ifdef DEBUG_CONNECT
1025 static int fas216_wait_cmd(FAS216_Info
*info
, int cmd
)
1030 outb(cmd
, REG_CMD(info
));
1032 for (tout
= 1000; tout
; tout
-= 1) {
1033 stat
= inb(REG_STAT(info
));
1034 if (stat
& STAT_INT
)
1042 static int fas216_get_msg_byte(FAS216_Info
*info
)
1046 stat
= fas216_wait_cmd(info
, CMD_MSGACCEPTED
);
1048 if ((stat
& STAT_INT
) == 0)
1051 if ((stat
& STAT_BUSMASK
) != STAT_MESGIN
)
1052 goto unexpected_phase_change
;
1054 inb(REG_INST(info
));
1056 stat
= fas216_wait_cmd(info
, CMD_TRANSFERINFO
);
1058 if ((stat
& STAT_INT
) == 0)
1061 if ((stat
& STAT_BUSMASK
) != STAT_MESGIN
)
1062 goto unexpected_phase_change
;
1064 inb(REG_INST(info
));
1066 return inb(REG_FF(info
));
1069 printk("scsi%d.%c: timed out waiting for message byte\n",
1070 info
->host
->host_no
, fas216_target(info
));
1073 unexpected_phase_change
:
1074 printk("scsi%d.%c: unexpected phase change: status = %02X\n",
1075 info
->host
->host_no
, fas216_target(info
), stat
);
1080 /* Function: void fas216_message(FAS216_Info *info)
1081 * Purpose : handle a function done interrupt from FAS216 chip
1082 * Params : info - interface which caused function done interrupt
1084 static void fas216_message(FAS216_Info
*info
)
1086 unsigned char *message
= info
->scsi
.message
;
1087 unsigned int msglen
= 1, i
;
1090 fas216_checkmagic(info
, "fas216_message");
1092 message
[0] = inb(REG_FF(info
));
1094 if (message
[0] == EXTENDED_MESSAGE
) {
1095 msgbyte
= fas216_get_msg_byte(info
);
1098 message
[1] = msgbyte
;
1100 for (msglen
= 2; msglen
< message
[1] + 2; msglen
++) {
1101 msgbyte
= fas216_get_msg_byte(info
);
1104 message
[msglen
] = msgbyte
;
1111 info
->scsi
.msglen
= msglen
;
1113 #ifdef DEBUG_MESSAGES
1117 printk("scsi%d.%c: message in: ",
1118 info
->host
->host_no
, fas216_target(info
));
1119 for (i
= 0; i
< msglen
; i
++)
1120 printk("%02X ", message
[i
]);
1125 if (info
->scsi
.phase
== PHASE_RECONNECTED
) {
1126 if (message
[0] == SIMPLE_QUEUE_TAG
)
1127 info
->scsi
.reconnected
.tag
= message
[1];
1128 fas216_finish_reconnect(info
);
1129 info
->scsi
.phase
= PHASE_MSGIN
;
1132 switch (message
[0]) {
1133 case COMMAND_COMPLETE
:
1137 printk(KERN_ERR
"scsi%d.%c: command complete with no "
1138 "status in MESSAGE_IN?\n",
1139 info
->host
->host_no
, fas216_target(info
));
1147 * Save current data pointer to SAVED data pointer
1148 * SCSI II standard says that we must not acknowledge
1149 * this until we have really saved pointers.
1150 * NOTE: we DO NOT save the command nor status pointers
1151 * as required by the SCSI II standard. These always
1152 * point to the start of their respective areas.
1154 info
->SCpnt
->SCp
= info
->scsi
.SCp
;
1155 info
->SCpnt
->SCp
.sent_command
= 0;
1156 #if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
1157 printk("scsi%d.%c: save data pointers: [%p, %X]\n",
1158 info
->host
->host_no
, fas216_target(info
),
1159 info
->scsi
.SCp
.ptr
, info
->scsi
.SCp
.this_residual
);
1163 case RESTORE_POINTERS
:
1168 * Restore current data pointer from SAVED data pointer
1170 info
->scsi
.SCp
= info
->SCpnt
->SCp
;
1171 #if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
1172 printk("scsi%d.%c: restore data pointers: [%p, %X]\n",
1173 info
->host
->host_no
, fas216_target(info
),
1174 info
->scsi
.SCp
.ptr
, info
->scsi
.SCp
.this_residual
);
1182 info
->scsi
.phase
= PHASE_MSGIN_DISCONNECT
;
1185 case MESSAGE_REJECT
:
1189 switch (fas216_get_last_msg(info
, info
->scsi
.msgin_fifo
)) {
1190 case EXTENDED_MESSAGE
| EXTENDED_SDTR
<< 8:
1191 fas216_handlesync(info
, message
);
1194 case EXTENDED_MESSAGE
| EXTENDED_WDTR
<< 8:
1195 fas216_handlewide(info
, message
);
1199 printk("scsi%d.%c: reject, last message %04X\n",
1200 info
->host
->host_no
, fas216_target(info
),
1201 fas216_get_last_msg(info
, info
->scsi
.msgin_fifo
));
1208 case SIMPLE_QUEUE_TAG
:
1212 /* handled above - print a warning since this is untested */
1213 printk("scsi%d.%c: reconnect queue tag %02X\n",
1214 info
->host
->host_no
, fas216_target(info
),
1218 case EXTENDED_MESSAGE
:
1222 switch (message
[2]) {
1223 case EXTENDED_SDTR
: /* Sync transfer negociation request/reply */
1224 fas216_handlesync(info
, message
);
1227 case EXTENDED_WDTR
: /* Wide transfer negociation request/reply */
1228 fas216_handlewide(info
, message
);
1239 outb(CMD_MSGACCEPTED
, REG_CMD(info
));
1243 printk("scsi%d.%c: unrecognised message, rejecting\n",
1244 info
->host
->host_no
, fas216_target(info
));
1245 printk("scsi%d.%c: message was", info
->host
->host_no
, fas216_target(info
));
1246 for (i
= 0; i
< msglen
; i
++)
1247 printk("%s%02X", i
& 31 ? " " : "\n ", message
[i
]);
1252 * Something strange seems to be happening here -
1253 * I can't use SETATN since the chip gives me an
1254 * invalid command interrupt when I do. Weird.
1256 outb(CMD_NOP
, REG_CMD(info
));
1257 fas216_dumpstate(info
);
1258 outb(CMD_SETATN
, REG_CMD(info
));
1259 msgqueue_flush(&info
->scsi
.msgs
);
1260 msgqueue_addmsg(&info
->scsi
.msgs
, 1, MESSAGE_REJECT
);
1261 info
->scsi
.phase
= PHASE_MSGOUT_EXPECT
;
1262 fas216_dumpstate(info
);
1263 outb(CMD_MSGACCEPTED
, REG_CMD(info
));
1266 /* Function: void fas216_send_command(FAS216_Info *info)
1267 * Purpose : send a command to a target after all message bytes have been sent
1268 * Params : info - interface which caused bus service
1270 static void fas216_send_command(FAS216_Info
*info
)
1274 fas216_checkmagic(info
, "fas216_send_command");
1276 outb(CMD_NOP
|CMD_WITHDMA
, REG_CMD(info
));
1277 outb(CMD_FLUSHFIFO
, REG_CMD(info
));
1280 for (i
= info
->scsi
.SCp
.sent_command
; i
< info
->SCpnt
->cmd_len
; i
++)
1281 outb(info
->SCpnt
->cmnd
[i
], REG_FF(info
));
1283 outb(CMD_TRANSFERINFO
, REG_CMD(info
));
1285 info
->scsi
.phase
= PHASE_COMMAND
;
1288 /* Function: void fas216_send_messageout(FAS216_Info *info, int start)
1289 * Purpose : handle bus service to send a message
1290 * Params : info - interface which caused bus service
1291 * Note : We do not allow the device to change the data direction!
1293 static void fas216_send_messageout(FAS216_Info
*info
, int start
)
1295 unsigned int tot_msglen
= msgqueue_msglength(&info
->scsi
.msgs
);
1297 fas216_checkmagic(info
, "fas216_send_messageout");
1299 outb(CMD_FLUSHFIFO
, REG_CMD(info
));
1302 struct message
*msg
;
1305 while ((msg
= msgqueue_getmsg(&info
->scsi
.msgs
, msgnr
++)) != NULL
) {
1308 for (i
= start
; i
< msg
->length
; i
++)
1309 outb(msg
->msg
[i
], REG_FF(info
));
1311 msg
->fifo
= tot_msglen
- (inb(REG_CFIS(info
)) & CFIS_CF
);
1315 outb(NOP
, REG_FF(info
));
1317 outb(CMD_TRANSFERINFO
, REG_CMD(info
));
1319 info
->scsi
.phase
= PHASE_MSGOUT
;
1322 /* Function: void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
1323 * Purpose : handle a bus service interrupt from FAS216 chip
1324 * Params : info - interface which caused bus service interrupt
1325 * stat - Status register contents
1326 * ssr - SCSI Status register contents
1328 static void fas216_busservice_intr(FAS216_Info
*info
, unsigned int stat
, unsigned int ssr
)
1330 fas216_checkmagic(info
, "fas216_busservice_intr");
1332 #ifdef DEBUG_BUSSERVICE
1333 printk("scsi%d.%c: bus service: stat=%02X ssr=%02X phase=%02X\n",
1334 info
->host
->host_no
, fas216_target(info
), stat
, ssr
, info
->scsi
.phase
);
1337 switch (info
->scsi
.phase
) {
1338 case PHASE_SELECTION
:
1339 if ((ssr
& IS_BITS
) != 1)
1343 case PHASE_SELSTEPS
:
1344 switch (ssr
& IS_BITS
) {
1346 case IS_MSGBYTESENT
:
1351 if ((stat
& STAT_BUSMASK
) == STAT_MESGIN
)
1363 outb(CMD_NOP
, REG_CMD(info
));
1365 #define STATE(st,ph) ((ph) << 3 | (st))
1366 /* This table describes the legal SCSI state transitions,
1367 * as described by the SCSI II spec.
1369 switch (STATE(stat
& STAT_BUSMASK
, info
->scsi
.phase
)) {
1370 /* Reselmsgin -> Data In */
1371 case STATE(STAT_DATAIN
, PHASE_RECONNECTED
):
1372 fas216_finish_reconnect(info
);
1373 case STATE(STAT_DATAIN
, PHASE_SELSTEPS
):/* Sel w/ steps -> Data In */
1374 case STATE(STAT_DATAIN
, PHASE_DATAIN
): /* Data In -> Data In */
1375 case STATE(STAT_DATAIN
, PHASE_MSGOUT
): /* Message Out -> Data In */
1376 case STATE(STAT_DATAIN
, PHASE_COMMAND
): /* Command -> Data In */
1377 case STATE(STAT_DATAIN
, PHASE_MSGIN
): /* Message In -> Data In */
1378 fas216_starttransfer(info
, DMA_IN
, 0);
1381 case STATE(STAT_DATAOUT
, PHASE_DATAOUT
):/* Data Out -> Data Out */
1382 fas216_starttransfer(info
, DMA_OUT
, 0);
1385 /* Reselmsgin -> Data Out */
1386 case STATE(STAT_DATAOUT
, PHASE_RECONNECTED
):
1387 fas216_finish_reconnect(info
);
1388 case STATE(STAT_DATAOUT
, PHASE_SELSTEPS
):/* Sel w/ steps-> Data Out */
1389 case STATE(STAT_DATAOUT
, PHASE_MSGOUT
): /* Message Out -> Data Out */
1390 case STATE(STAT_DATAOUT
, PHASE_COMMAND
):/* Command -> Data Out */
1391 case STATE(STAT_DATAOUT
, PHASE_MSGIN
): /* Message In -> Data Out */
1392 fas216_starttransfer(info
, DMA_OUT
, 1);
1395 /* Reselmsgin -> Status */
1396 case STATE(STAT_STATUS
, PHASE_RECONNECTED
):
1397 fas216_finish_reconnect(info
);
1399 case STATE(STAT_STATUS
, PHASE_DATAOUT
): /* Data Out -> Status */
1400 case STATE(STAT_STATUS
, PHASE_DATAIN
): /* Data In -> Status */
1401 fas216_stoptransfer(info
);
1402 case STATE(STAT_STATUS
, PHASE_SELSTEPS
):/* Sel w/ steps -> Status */
1403 case STATE(STAT_STATUS
, PHASE_MSGOUT
): /* Message Out -> Status */
1404 case STATE(STAT_STATUS
, PHASE_COMMAND
): /* Command -> Status */
1405 case STATE(STAT_STATUS
, PHASE_MSGIN
): /* Message In -> Status */
1407 outb(CMD_INITCMDCOMPLETE
, REG_CMD(info
));
1408 info
->scsi
.phase
= PHASE_STATUS
;
1411 case STATE(STAT_MESGIN
, PHASE_DATAOUT
): /* Data Out -> Message In */
1412 case STATE(STAT_MESGIN
, PHASE_DATAIN
): /* Data In -> Message In */
1413 fas216_stoptransfer(info
);
1414 case STATE(STAT_MESGIN
, PHASE_SELSTEPS
):/* Sel w/ steps -> Message In */
1415 case STATE(STAT_MESGIN
, PHASE_MSGOUT
): /* Message Out -> Message In */
1416 info
->scsi
.msgin_fifo
= inb(REG_CFIS(info
)) & CFIS_CF
;
1417 outb(CMD_FLUSHFIFO
, REG_CMD(info
));
1418 outb(CMD_TRANSFERINFO
, REG_CMD(info
));
1419 info
->scsi
.phase
= PHASE_MSGIN
;
1422 /* Reselmsgin -> Message In */
1423 case STATE(STAT_MESGIN
, PHASE_RECONNECTED
):
1424 case STATE(STAT_MESGIN
, PHASE_MSGIN
):
1425 info
->scsi
.msgin_fifo
= inb(REG_CFIS(info
)) & CFIS_CF
;
1426 outb(CMD_TRANSFERINFO
, REG_CMD(info
));
1429 /* Reselmsgin -> Command */
1430 case STATE(STAT_COMMAND
, PHASE_RECONNECTED
):
1431 fas216_finish_reconnect(info
);
1432 case STATE(STAT_COMMAND
, PHASE_MSGOUT
): /* Message Out -> Command */
1433 case STATE(STAT_COMMAND
, PHASE_MSGIN
): /* Message In -> Command */
1434 fas216_send_command(info
);
1435 info
->scsi
.phase
= PHASE_COMMAND
;
1437 /* Selection -> Message Out */
1438 case STATE(STAT_MESGOUT
, PHASE_SELECTION
):
1439 fas216_send_messageout(info
, 1);
1441 /* Any -> Message Out */
1442 case STATE(STAT_MESGOUT
, PHASE_MSGOUT_EXPECT
):
1443 fas216_send_messageout(info
, 0);
1446 /* Error recovery rules.
1447 * These either attempt to abort or retry the operation.
1448 * TODO: we need more of these
1450 case STATE(STAT_COMMAND
, PHASE_COMMAND
):/* Command -> Command */
1451 /* error - we've sent out all the command bytes
1453 * NOTE: we need SAVE DATA POINTERS/RESTORE DATA POINTERS
1454 * to include the command bytes sent for this to work
1457 printk(KERN_ERR
"scsi%d.%c: "
1458 "target trying to receive more command bytes\n",
1459 info
->host
->host_no
, fas216_target(info
));
1460 outb(CMD_SETATN
, REG_CMD(info
));
1461 outb(15, REG_STCL(info
));
1462 outb(0, REG_STCM(info
));
1463 outb(0, REG_STCH(info
));
1464 outb(CMD_PADBYTES
| CMD_WITHDMA
, REG_CMD(info
));
1465 msgqueue_flush(&info
->scsi
.msgs
);
1466 msgqueue_addmsg(&info
->scsi
.msgs
, 1, INITIATOR_ERROR
);
1467 info
->scsi
.phase
= PHASE_MSGOUT_EXPECT
;
1470 /* Selection -> Message Out */
1471 case STATE(STAT_MESGOUT
, PHASE_SELSTEPS
):
1472 case STATE(STAT_MESGOUT
, PHASE_MSGOUT
): /* Message Out -> Message Out */
1473 /* If we get another message out phase, this
1474 * usually means some parity error occurred.
1475 * Resend complete set of messages. If we have
1476 * more than 1 byte to send, we need to assert
1479 if (msgqueue_msglength(&info
->scsi
.msgs
) > 1)
1480 outb(CMD_SETATN
, REG_CMD(info
));
1482 fas216_send_messageout(info
, 0);
1486 if (info
->scsi
.phase
== PHASE_MSGIN_DISCONNECT
) {
1487 printk(KERN_ERR
"scsi%d.%c: disconnect message received, but bus service %s?\n",
1488 info
->host
->host_no
, fas216_target(info
),
1489 fas216_bus_phase(stat
));
1490 msgqueue_flush(&info
->scsi
.msgs
);
1491 outb(CMD_SETATN
, REG_CMD(info
));
1492 msgqueue_addmsg(&info
->scsi
.msgs
, 1, INITIATOR_ERROR
);
1493 info
->scsi
.phase
= PHASE_MSGOUT_EXPECT
;
1494 info
->scsi
.aborting
= 1;
1495 outb(CMD_TRANSFERINFO
, REG_CMD(info
));
1498 printk(KERN_ERR
"scsi%d.%c: bus phase %s after %s?\n",
1499 info
->host
->host_no
, fas216_target(info
),
1500 fas216_bus_phase(stat
),
1501 fas216_drv_phase(info
));
1506 printk("scsi%d.%c: bus service at step %d?\n",
1507 info
->host
->host_no
, fas216_target(info
),
1511 fas216_done(info
, DID_ERROR
);
1514 /* Function: void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
1515 * Purpose : handle a function done interrupt from FAS216 chip
1516 * Params : info - interface which caused function done interrupt
1517 * stat - Status register contents
1518 * ssr - SCSI Status register contents
1520 static void fas216_funcdone_intr(FAS216_Info
*info
, unsigned int stat
, unsigned int ssr
)
1522 int status
, message
;
1524 fas216_checkmagic(info
, "fas216_funcdone_intr");
1526 #ifdef DEBUG_FUNCTIONDONE
1527 printk("scsi%d.%c: function done: stat=%X ssr=%X phase=%02X\n",
1528 info
->host
->host_no
, fas216_target(info
), stat
, ssr
, info
->scsi
.phase
);
1530 switch (info
->scsi
.phase
) {
1531 case PHASE_STATUS
: /* status phase - read status and msg */
1532 status
= inb(REG_FF(info
));
1533 message
= inb(REG_FF(info
));
1534 info
->scsi
.SCp
.Message
= message
;
1535 info
->scsi
.SCp
.Status
= status
;
1536 info
->scsi
.phase
= PHASE_DONE
;
1537 outb(CMD_MSGACCEPTED
, REG_CMD(info
));
1540 case PHASE_IDLE
: /* reselected? */
1541 case PHASE_MSGIN
: /* message in phase */
1542 case PHASE_RECONNECTED
: /* reconnected command */
1543 if ((stat
& STAT_BUSMASK
) == STAT_MESGIN
) {
1544 info
->scsi
.msgin_fifo
= inb(REG_CFIS(info
)) & CFIS_CF
;
1545 fas216_message(info
);
1550 printk("scsi%d.%c: internal phase %s for function done?"
1551 " What do I do with this?\n",
1552 info
->host
->host_no
, fas216_target(info
),
1553 fas216_drv_phase(info
));
1557 /* Function: void fas216_intr(struct Scsi_Host *instance)
1558 * Purpose : handle interrupts from the interface to progress a command
1559 * Params : instance - interface to service
1561 void fas216_intr(struct Scsi_Host
*instance
)
1563 FAS216_Info
*info
= (FAS216_Info
*)instance
->hostdata
;
1564 unsigned char isr
, ssr
, stat
;
1566 fas216_checkmagic(info
, "fas216_intr");
1568 stat
= inb(REG_STAT(info
));
1569 ssr
= inb(REG_IS(info
));
1570 isr
= inb(REG_INST(info
));
1572 add_debug_list(stat
, ssr
, isr
, info
->scsi
.phase
);
1574 if (stat
& STAT_INT
) {
1575 if (isr
& INST_BUSRESET
)
1576 printk(KERN_DEBUG
"scsi%d.H: bus reset detected\n", instance
->host_no
);
1577 else if (isr
& INST_ILLEGALCMD
) {
1578 printk(KERN_CRIT
"scsi%d.H: illegal command given\n", instance
->host_no
);
1579 fas216_dumpstate(info
);
1580 } else if (isr
& INST_DISCONNECT
)
1581 fas216_disconnect_intr(info
);
1582 else if (isr
& INST_RESELECTED
) /* reselected */
1583 fas216_reselected_intr(info
);
1584 else if (isr
& INST_BUSSERVICE
) /* bus service request */
1585 fas216_busservice_intr(info
, stat
, ssr
);
1586 else if (isr
& INST_FUNCDONE
) /* function done */
1587 fas216_funcdone_intr(info
, stat
, ssr
);
1589 printk("scsi%d.%c: unknown interrupt received:"
1590 " phase %s isr %02X ssr %02X stat %02X\n",
1591 instance
->host_no
, fas216_target(info
),
1592 fas216_drv_phase(info
), isr
, ssr
, stat
);
1596 /* Function: void fas216_kick(FAS216_Info *info)
1597 * Purpose : kick a command to the interface - interface should be idle
1598 * Params : info - our host interface to kick
1599 * Notes : Interrupts are always disabled!
1601 static void fas216_kick(FAS216_Info
*info
)
1604 int tot_msglen
, from_queue
= 0;
1606 fas216_checkmagic(info
, "fas216_kick");
1608 if (info
->origSCpnt
) {
1609 SCpnt
= info
->origSCpnt
;
1610 info
->origSCpnt
= NULL
;
1614 /* retrieve next command */
1616 SCpnt
= queue_remove_exclude(&info
->queues
.issue
, info
->busyluns
);
1620 if (!SCpnt
) /* no command pending - just exit */
1623 if (info
->scsi
.disconnectable
&& info
->SCpnt
) {
1624 queue_add_cmd_tail(&info
->queues
.disconnected
, info
->SCpnt
);
1625 info
->scsi
.disconnectable
= 0;
1627 printk("scsi%d.%c: moved command to disconnected queue\n",
1628 info
->host
->host_no
, fas216_target(info
));
1632 * tagged queuing - allocate a new tag to this command
1634 if (SCpnt
->device
->tagged_queue
&& SCpnt
->cmnd
[0] != REQUEST_SENSE
) {
1635 SCpnt
->device
->current_tag
+= 1;
1636 if (SCpnt
->device
->current_tag
== 0)
1637 SCpnt
->device
->current_tag
= 1;
1638 SCpnt
->tag
= SCpnt
->device
->current_tag
;
1644 info
->scsi
.phase
= PHASE_SELECTION
;
1645 info
->SCpnt
= SCpnt
;
1646 info
->scsi
.SCp
= SCpnt
->SCp
;
1647 info
->dma
.transfer_type
= fasdma_none
;
1649 #ifdef DEBUG_CONNECT
1650 printk("scsi%d.%c: starting cmd %02X",
1651 info
->host
->host_no
, '0' + SCpnt
->target
,
1657 if (SCpnt
->device
->tagged_queue
&& SCpnt
->cmnd
[0] != REQUEST_SENSE
&&
1658 SCpnt
->cmnd
[0] != INQUIRY
) {
1659 SCpnt
->device
->current_tag
+= 1;
1660 if (SCpnt
->device
->current_tag
== 0)
1661 SCpnt
->device
->current_tag
= 1;
1662 SCpnt
->tag
= SCpnt
->device
->current_tag
;
1665 set_bit(SCpnt
->target
* 8 + SCpnt
->lun
, info
->busyluns
);
1667 info
->stats
.removes
+= 1;
1668 switch (SCpnt
->cmnd
[0]) {
1672 info
->stats
.writes
+= 1;
1677 info
->stats
.reads
+= 1;
1680 info
->stats
.miscs
+= 1;
1685 /* build outgoing message bytes */
1686 msgqueue_flush(&info
->scsi
.msgs
);
1688 if (info
->device
[SCpnt
->target
].disconnect_ok
)
1689 msgqueue_addmsg(&info
->scsi
.msgs
, 1, IDENTIFY(1, SCpnt
->lun
));
1691 msgqueue_addmsg(&info
->scsi
.msgs
, 1, IDENTIFY(0, SCpnt
->lun
));
1693 /* add tag message if required */
1695 msgqueue_addmsg(&info
->scsi
.msgs
, 2, SIMPLE_QUEUE_TAG
, SCpnt
->tag
);
1698 if (info
->device
[SCpnt
->target
].wide_state
== neg_wait
) {
1699 info
->device
[SCpnt
->target
].wide_state
= neg_inprogress
;
1700 msgqueue_addmsg(&info
->scsi
.msgs
, 4,
1701 EXTENDED_MESSAGE
, 2, EXTENDED_WDTR
,
1702 info
->ifcfg
.wide_max_size
);
1709 if ((info
->device
[SCpnt
->target
].sync_state
== neg_wait
||
1710 info
->device
[SCpnt
->target
].sync_state
== neg_complete
) &&
1711 (SCpnt
->cmnd
[0] == REQUEST_SENSE
||
1712 SCpnt
->cmnd
[0] == INQUIRY
)) {
1713 info
->device
[SCpnt
->target
].sync_state
= neg_inprogress
;
1714 msgqueue_addmsg(&info
->scsi
.msgs
, 5,
1715 EXTENDED_MESSAGE
, 3, EXTENDED_SDTR
,
1716 1000 / info
->ifcfg
.clockrate
,
1717 info
->ifcfg
.sync_max_depth
);
1721 /* following what the ESP driver says */
1722 outb(0, REG_STCL(info
));
1723 outb(0, REG_STCM(info
));
1724 outb(0, REG_STCH(info
));
1725 outb(CMD_NOP
| CMD_WITHDMA
, REG_CMD(info
));
1728 outb(CMD_FLUSHFIFO
, REG_CMD(info
));
1730 /* load bus-id and timeout */
1731 outb(BUSID(SCpnt
->target
), REG_SDID(info
));
1732 outb(info
->ifcfg
.select_timeout
, REG_STIM(info
));
1734 /* synchronous transfers */
1735 fas216_set_sync(info
, SCpnt
->target
);
1737 tot_msglen
= msgqueue_msglength(&info
->scsi
.msgs
);
1739 if (tot_msglen
== 1 || tot_msglen
== 3) {
1741 * We have an easy message length to send...
1743 struct message
*msg
;
1746 info
->scsi
.phase
= PHASE_SELSTEPS
;
1748 /* load message bytes */
1749 while ((msg
= msgqueue_getmsg(&info
->scsi
.msgs
, msgnr
++)) != NULL
) {
1750 for (i
= 0; i
< msg
->length
; i
++)
1751 outb(msg
->msg
[i
], REG_FF(info
));
1752 msg
->fifo
= tot_msglen
- (inb(REG_CFIS(info
)) & CFIS_CF
);
1756 for (i
= 0; i
< SCpnt
->cmd_len
; i
++)
1757 outb(SCpnt
->cmnd
[i
], REG_FF(info
));
1759 if (tot_msglen
== 1)
1760 outb(CMD_SELECTATN
, REG_CMD(info
));
1762 outb(CMD_SELECTATN3
, REG_CMD(info
));
1765 * We have an unusual number of message bytes to send.
1766 * Load first byte into fifo, and issue SELECT with ATN and
1769 struct message
*msg
= msgqueue_getmsg(&info
->scsi
.msgs
, 0);
1771 outb(msg
->msg
[0], REG_FF(info
));
1774 outb(CMD_SELECTATNSTOP
, REG_CMD(info
));
1777 #ifdef DEBUG_CONNECT
1778 printk(", data pointers [%p, %X]\n",
1779 info
->scsi
.SCp
.ptr
, info
->scsi
.SCp
.this_residual
);
1781 /* should now get either DISCONNECT or (FUNCTION DONE with BUS SERVICE) intr */
1784 /* Function: void fas216_done(FAS216_Info *info, unsigned int result)
1785 * Purpose : complete processing for command
1786 * Params : info - interface that completed
1787 * result - driver byte of result
1789 static void fas216_done(FAS216_Info
*info
, unsigned int result
)
1793 fas216_checkmagic(info
, "fas216_done");
1795 SCpnt
= info
->SCpnt
;
1797 if (info
->scsi
.aborting
) {
1798 printk("scsi%d.%c: uncaught abort - returning DID_ABORT\n",
1799 info
->host
->host_no
, fas216_target(info
));
1801 info
->scsi
.aborting
= 0;
1804 info
->stats
.fins
+= 1;
1807 info
->scsi
.phase
= PHASE_IDLE
;
1810 SCpnt
->result
= result
<< 16 | info
->scsi
.SCp
.Message
<< 8 |
1811 info
->scsi
.SCp
.Status
;
1814 * In theory, this should not happen, but just in case it does.
1816 if (info
->scsi
.SCp
.ptr
&&
1817 info
->scsi
.SCp
.this_residual
&&
1819 switch (SCpnt
->cmnd
[0]) {
1823 case TEST_UNIT_READY
:
1828 switch (status_byte(SCpnt
->result
)) {
1829 case CHECK_CONDITION
:
1830 case COMMAND_TERMINATED
:
1833 case RESERVATION_CONFLICT
:
1837 printk(KERN_ERR
"scsi%d.H: incomplete data transfer "
1838 "detected: res=%08X ptr=%p len=%X command=",
1839 info
->host
->host_no
, SCpnt
->result
,
1840 info
->scsi
.SCp
.ptr
, info
->scsi
.SCp
.this_residual
);
1841 print_command(SCpnt
->cmnd
);
1845 #ifdef DEBUG_CONNECT
1846 printk("scsi%d.%c: scsi command (%p) complete, result=%08X\n",
1847 info
->host
->host_no
, fas216_target(info
),
1848 SCpnt
, SCpnt
->result
);
1851 if (!SCpnt
->scsi_done
)
1852 panic("scsi%d.H: null scsi_done function in "
1853 "fas216_done", info
->host
->host_no
);
1855 clear_bit(SCpnt
->target
* 8 + SCpnt
->lun
, info
->busyluns
);
1857 SCpnt
->scsi_done(SCpnt
);
1859 panic("scsi%d.H: null command in fas216_done", info
->host
->host_no
);
1861 if (info
->scsi
.irq
!= NO_IRQ
)
1865 /* Function: int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
1866 * Purpose : queue a command for adapter to process.
1867 * Params : SCpnt - Command to queue
1868 * done - done function to call once command is complete
1869 * Returns : 0 - success, else error
1871 int fas216_queue_command(Scsi_Cmnd
*SCpnt
, void (*done
)(Scsi_Cmnd
*))
1873 FAS216_Info
*info
= (FAS216_Info
*)SCpnt
->host
->hostdata
;
1874 unsigned long flags
;
1876 fas216_checkmagic(info
, "fas216_queue_command");
1878 #ifdef DEBUG_CONNECT
1879 printk("scsi%d.%c: received queuable command (%p) %02X\n",
1880 SCpnt
->host
->host_no
, '0' + SCpnt
->target
,
1881 SCpnt
, SCpnt
->cmnd
[0]);
1884 SCpnt
->scsi_done
= done
;
1885 SCpnt
->host_scribble
= NULL
;
1887 SCpnt
->SCp
.Message
= 0;
1888 SCpnt
->SCp
.Status
= 0;
1890 if (SCpnt
->use_sg
) {
1891 unsigned long len
= 0;
1894 SCpnt
->SCp
.buffer
= (struct scatterlist
*) SCpnt
->buffer
;
1895 SCpnt
->SCp
.buffers_residual
= SCpnt
->use_sg
- 1;
1896 SCpnt
->SCp
.ptr
= (char *) SCpnt
->SCp
.buffer
->address
;
1897 SCpnt
->SCp
.this_residual
= SCpnt
->SCp
.buffer
->length
;
1899 * Calculate correct buffer length
1901 for (buf
= 0; buf
<= SCpnt
->SCp
.buffers_residual
; buf
++)
1902 len
+= SCpnt
->SCp
.buffer
[buf
].length
;
1903 SCpnt
->request_bufflen
= len
;
1905 SCpnt
->SCp
.buffer
= NULL
;
1906 SCpnt
->SCp
.buffers_residual
= 0;
1907 SCpnt
->SCp
.ptr
= (unsigned char *)SCpnt
->request_buffer
;
1908 SCpnt
->SCp
.this_residual
= SCpnt
->request_bufflen
;
1911 info
->stats
.queues
+= 1;
1914 /* add command into execute queue and let it complete under
1915 * whatever scheme we're using.
1917 if (!queue_add_cmd_ordered(&info
->queues
.issue
, SCpnt
)) {
1918 SCpnt
->result
= DID_ERROR
<< 16;
1921 save_flags_cli(flags
);
1922 if (!info
->SCpnt
|| info
->scsi
.disconnectable
)
1924 restore_flags(flags
);
1929 /* Function: void fas216_internal_done(Scsi_Cmnd *SCpnt)
1930 * Purpose : trigger restart of a waiting thread in fas216_command
1931 * Params : SCpnt - Command to wake
1933 static void fas216_internal_done(Scsi_Cmnd
*SCpnt
)
1935 FAS216_Info
*info
= (FAS216_Info
*)SCpnt
->host
->hostdata
;
1937 fas216_checkmagic(info
, "fas216_internal_done");
1939 info
->internal_done
= 1;
1942 /* Function: int fas216_command(Scsi_Cmnd *SCpnt)
1943 * Purpose : queue a command for adapter to process.
1944 * Params : SCpnt - Command to queue
1945 * Returns : scsi result code
1947 int fas216_command(Scsi_Cmnd
*SCpnt
)
1949 FAS216_Info
*info
= (FAS216_Info
*)SCpnt
->host
->hostdata
;
1950 unsigned long flags
;
1952 fas216_checkmagic(info
, "fas216_command");
1954 info
->internal_done
= 0;
1955 fas216_queue_command(SCpnt
, fas216_internal_done
);
1958 * This wastes time, since we can't return until the command is
1959 * complete. We can't sleep either since we may get re-entered!
1960 * However, we must re-enable interrupts, or else we'll be
1966 while (!info
->internal_done
) {
1968 * If we don't have an IRQ, then we must
1969 * poll the card for it's interrupt, and
1970 * use that to call this driver's interrupt
1971 * routine. That way, we keep the command
1974 if (info
->scsi
.irq
== NO_IRQ
) {
1976 while (!(inb(REG_STAT(info
)) & STAT_INT
));
1978 fas216_intr(info
->host
);
1982 restore_flags(flags
);
1984 return SCpnt
->result
;
1987 /* Prototype: void fas216_reportstatus(Scsi_Cmnd **SCpntp1,
1988 * Scsi_Cmnd **SCpntp2, int result, int no_report)
1989 * Purpose : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2
1990 * Params : SCpntp1 - pointer to command to return
1991 * SCpntp2 - pointer to command to check
1992 * result - result to pass back to mid-level done function
1993 * Returns : *SCpntp2 = NULL if *SCpntp1 is the same command
1994 * structure as *SCpntp2.
1996 static void fas216_reportstatus(Scsi_Cmnd
**SCpntp1
, Scsi_Cmnd
**SCpntp2
,
1997 int result
, int no_report
)
1999 Scsi_Cmnd
*SCpnt
= *SCpntp1
;
2004 SCpnt
->result
= result
;
2005 if (!no_report
|| SCpnt
!= *SCpntp2
)
2006 SCpnt
->scsi_done(SCpnt
);
2009 if (SCpnt
== *SCpntp2
)
2013 /* Function: int fas216_eh_abort(Scsi_Cmnd *SCpnt)
2014 * Purpose : abort this command
2015 * Params : SCpnt - command to abort
2016 * Returns : FAILED if unable to abort
2018 int fas216_eh_abort(Scsi_Cmnd
*SCpnt
)
2023 /* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
2024 * Purpose : Reset the device associated with this command
2025 * Params : SCpnt - command specifing device to reset
2026 * Returns : FAILED if unable to reset
2028 int fas216_eh_device_reset(Scsi_Cmnd
*SCpnt
)
2033 /* Function: int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
2034 * Purpose : Reset the complete bus associated with this command
2035 * Params : SCpnt - command specifing bus to reset
2036 * Returns : FAILED if unable to reset
2038 int fas216_eh_bus_reset(Scsi_Cmnd
*SCpnt
)
2043 /* Function: int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
2044 * Purpose : Reset the host associated with this command
2045 * Params : SCpnt - command specifing host to reset
2046 * Returns : FAILED if unable to reset
2048 int fas216_eh_host_reset(Scsi_Cmnd
*SCpnt
)
2053 enum res_abort
{ res_not_running
, res_success
, res_success_clear
, res_snooze
};
2056 * Prototype: enum res_abort fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
2057 * Purpose : abort a command on this host
2058 * Params : SCpnt - command to abort
2059 * Returns : abort status
2061 static enum res_abort
2062 fas216_do_abort(FAS216_Info
*info
, Scsi_Cmnd
*SCpnt
)
2064 enum res_abort res
= res_not_running
;
2066 if (queue_removecmd(&info
->queues
.issue
, SCpnt
)) {
2068 * The command was on the issue queue, and has not been
2069 * issued yet. We can remove the command from the queue,
2070 * and acknowledge the abort. Neither the devices nor the
2071 * interface know about the command.
2073 printk("on issue queue ");
2076 } else if (queue_removecmd(&info
->queues
.disconnected
, SCpnt
)) {
2078 * The command was on the disconnected queue. Simply
2079 * acknowledge the abort condition, and when the target
2080 * reconnects, we will give it an ABORT message. The
2081 * target should then disconnect, and we will clear
2084 printk("on disconnected queue ");
2087 } else if (info
->SCpnt
== SCpnt
) {
2088 unsigned long flags
;
2090 printk("executing ");
2094 switch (info
->scsi
.phase
) {
2096 * If the interface is idle, and the command is 'disconnectable',
2097 * then it is the same as on the disconnected queue. We simply
2098 * remove all traces of the command. When the target reconnects,
2099 * we will give it an ABORT message since the command could not
2100 * be found. When the target finally disconnects, we will clear
2104 if (info
->scsi
.disconnectable
) {
2105 info
->scsi
.disconnectable
= 0;
2112 * If the command has connected and done nothing futher,
2113 * simply force a disconnect. We also need to clear the
2116 case PHASE_SELECTION
:
2117 // info->SCpnt = NULL;
2118 // res = res_success_clear;
2125 restore_flags(flags
);
2126 } else if (info
->origSCpnt
== SCpnt
) {
2128 * The command will be executed next, but a command
2129 * is currently using the interface. This is similar to
2130 * being on the issue queue, except the busylun bit has
2133 info
->origSCpnt
= NULL
;
2134 printk("waiting for execution ");
2135 res
= res_success_clear
;
2142 /* Function: int fas216_abort(Scsi_Cmnd *SCpnt)
2143 * Purpose : abort a command if something horrible happens.
2144 * Params : SCpnt - Command that is believed to be causing a problem.
2145 * Returns : one of SCSI_ABORT_ macros.
2147 int fas216_abort(Scsi_Cmnd
*SCpnt
)
2149 FAS216_Info
*info
= (FAS216_Info
*)SCpnt
->host
->hostdata
;
2150 int result
= SCSI_ABORT_SNOOZE
;
2152 fas216_checkmagic(info
, "fas216_abort");
2154 info
->stats
.aborts
+= 1;
2157 fas216_dumpstate(info
);
2158 fas216_dumpinfo(info
);
2160 printk(KERN_WARNING
"scsi%d: abort ", info
->host
->host_no
);
2162 switch (fas216_do_abort(info
, SCpnt
)) {
2164 * We managed to find the command and cleared it out.
2165 * We do not expect the command to be executing on the
2166 * target, but we have set the busylun bit.
2168 case res_success_clear
:
2170 clear_bit(SCpnt
->target
* 8 + SCpnt
->lun
, info
->busyluns
);
2173 * We found the command, and cleared it out. Either
2174 * the command is still known to be executing on the
2175 * target, or the busylun bit is not set.
2178 printk("success\n");
2179 SCpnt
->result
= DID_ABORT
<< 16;
2180 SCpnt
->scsi_done(SCpnt
);
2181 result
= SCSI_ABORT_SUCCESS
;
2185 * We did find the command, but unfortunately we couldn't
2186 * unhook it from ourselves. Wait some more, and if it
2187 * still doesn't complete, reset the interface.
2191 result
= SCSI_ABORT_SNOOZE
;
2195 * The command could not be found (either because it completed,
2196 * or it got dropped.
2199 case res_not_running
:
2200 result
= SCSI_ABORT_SNOOZE
;
2201 printk("not running\n");
2208 /* Function: void fas216_reset_state(FAS216_Info *info)
2209 * Purpose : Initialise driver internal state
2210 * Params : info - state to initialise
2212 static void fas216_reset_state(FAS216_Info
*info
)
2214 neg_t sync_state
, wide_state
;
2217 fas216_checkmagic(info
, "fas216_reset_state");
2220 * Clear out all stale info in our state structure
2222 memset(info
->busyluns
, 0, sizeof(info
->busyluns
));
2223 msgqueue_flush(&info
->scsi
.msgs
);
2224 info
->scsi
.reconnected
.target
= 0;
2225 info
->scsi
.reconnected
.lun
= 0;
2226 info
->scsi
.reconnected
.tag
= 0;
2227 info
->scsi
.disconnectable
= 0;
2228 info
->scsi
.aborting
= 0;
2229 info
->scsi
.phase
= PHASE_IDLE
;
2230 info
->scsi
.async_stp
=
2231 fas216_syncperiod(info
, info
->ifcfg
.asyncperiod
);
2233 if (info
->ifcfg
.wide_max_size
== 0)
2234 wide_state
= neg_invalid
;
2237 wide_state
= neg_wait
;
2239 wide_state
= neg_invalid
;
2242 if (info
->host
->dma_channel
== NO_DMA
|| !info
->dma
.setup
)
2243 sync_state
= neg_invalid
;
2246 sync_state
= neg_wait
;
2248 sync_state
= neg_invalid
;
2251 for (i
= 0; i
< 8; i
++) {
2252 info
->device
[i
].disconnect_ok
= info
->ifcfg
.disconnect_ok
;
2253 info
->device
[i
].sync_state
= sync_state
;
2254 info
->device
[i
].wide_state
= wide_state
;
2255 info
->device
[i
].period
= info
->ifcfg
.asyncperiod
/ 4;
2256 info
->device
[i
].stp
= info
->scsi
.async_stp
;
2257 info
->device
[i
].sof
= 0;
2258 info
->device
[i
].wide_xfer
= 0;
2262 /* Function: void fas216_init_chip(FAS216_Info *info)
2263 * Purpose : Initialise FAS216 state after reset
2264 * Params : info - state structure for interface
2266 static void fas216_init_chip(FAS216_Info
*info
)
2268 fas216_checkmagic(info
, "fas216_init_chip");
2270 outb(fas216_clockrate(info
->ifcfg
.clockrate
), REG_CLKF(info
));
2271 outb(info
->scsi
.cfg
[0], REG_CNTL1(info
));
2272 outb(info
->scsi
.cfg
[1], REG_CNTL2(info
));
2273 outb(info
->scsi
.cfg
[2], REG_CNTL3(info
));
2274 outb(info
->ifcfg
.select_timeout
, REG_STIM(info
));
2275 outb(0, REG_SOF(info
));
2276 outb(info
->scsi
.async_stp
, REG_STP(info
));
2277 outb(info
->scsi
.cfg
[0], REG_CNTL1(info
));
2280 /* Function: int fas216_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
2281 * Purpose : resets the adapter if something horrible happens.
2282 * Params : SCpnt - Command that is believed to be causing a problem.
2283 * reset_flags - flags indicating reset type that is believed
2285 * Returns : one of SCSI_RESET_ macros, or'd with the SCSI_RESET_*_RESET
2288 int fas216_reset(Scsi_Cmnd
*SCpnt
, unsigned int reset_flags
)
2290 FAS216_Info
*info
= (FAS216_Info
*)SCpnt
->host
->hostdata
;
2293 int synchronous
= reset_flags
& SCSI_RESET_SYNCHRONOUS
;
2295 fas216_checkmagic(info
, "fas216_reset");
2298 * Validate that command is actually on one of our queues if we're doing
2299 * an asynchronous reset
2301 if (reset_flags
& SCSI_RESET_ASYNCHRONOUS
&&
2303 info
->SCpnt
!= SCpnt
&&
2304 info
->origSCpnt
!= SCpnt
&&
2305 !queue_cmdonqueue(&info
->queues
.disconnected
, SCpnt
) &&
2306 !queue_cmdonqueue(&info
->queues
.issue
, SCpnt
)) {
2307 printk("scsi%d: fas216_reset: asynchronous reset for unknown command\n",
2308 info
->host
->host_no
);
2309 return SCSI_RESET_NOT_RUNNING
;
2312 info
->stats
.resets
+= 1;
2315 printk(KERN_WARNING
"scsi%d: reset ", info
->host
->host_no
);
2317 printk("for target %d ", SCpnt
->target
);
2321 outb(info
->scsi
.cfg
[3], REG_CNTL3(info
));
2323 fas216_stoptransfer(info
);
2325 switch (reset_flags
& (SCSI_RESET_SUGGEST_BUS_RESET
| SCSI_RESET_SUGGEST_HOST_RESET
)) {
2326 case SCSI_RESET_SUGGEST_BUS_RESET
:
2327 outb(CMD_RESETSCSI
, REG_CMD(info
));
2328 outb(CMD_NOP
, REG_CMD(info
));
2329 result
|= SCSI_RESET_BUS_RESET
;
2332 case SCSI_RESET_SUGGEST_HOST_RESET
:
2333 outb(CMD_RESETCHIP
, REG_CMD(info
));
2334 outb(CMD_NOP
, REG_CMD(info
));
2335 result
|= SCSI_RESET_HOST_RESET
;
2339 outb(CMD_RESETCHIP
, REG_CMD(info
));
2340 outb(CMD_NOP
, REG_CMD(info
));
2341 outb(CMD_RESETSCSI
, REG_CMD(info
));
2342 result
|= SCSI_RESET_HOST_RESET
| SCSI_RESET_BUS_RESET
;
2347 fas216_reset_state(info
);
2348 fas216_init_chip(info
);
2351 * Signal all commands in progress have been reset
2353 fas216_reportstatus(&info
->SCpnt
, &SCpnt
, DID_RESET
<< 16, synchronous
);
2355 while ((SCptr
= queue_remove(&info
->queues
.disconnected
)) != NULL
)
2356 fas216_reportstatus(&SCptr
, &SCpnt
, DID_RESET
<< 16, synchronous
);
2360 * Command not found on disconnected queue, nor currently
2361 * executing command - check pending commands
2363 if (info
->origSCpnt
== SCpnt
)
2364 info
->origSCpnt
= NULL
;
2366 queue_removecmd(&info
->queues
.issue
, SCpnt
);
2368 SCpnt
->result
= DID_RESET
<< 16;
2370 SCpnt
->scsi_done(SCpnt
);
2373 return result
| SCSI_RESET_SUCCESS
;
2376 /* Function: int fas216_init(struct Scsi_Host *instance)
2377 * Purpose : initialise FAS/NCR/AMD SCSI ic.
2378 * Params : instance - a driver-specific filled-out structure
2379 * Returns : 0 on success
2381 int fas216_init(struct Scsi_Host
*instance
)
2383 FAS216_Info
*info
= (FAS216_Info
*)instance
->hostdata
;
2384 unsigned long flags
;
2387 info
->magic_start
= MAGIC
;
2388 info
->magic_end
= MAGIC
;
2390 info
->host
= instance
;
2391 info
->scsi
.cfg
[0] = instance
->this_id
;
2392 info
->scsi
.cfg
[1] = CNTL2_ENF
| CNTL2_S2FE
;
2393 info
->scsi
.cfg
[2] = info
->ifcfg
.cntl3
| CNTL3_ADIDCHK
| CNTL3_G2CB
;
2394 info
->scsi
.type
= "unknown";
2396 fas216_reset_state(info
);
2398 memset(&info
->stats
, 0, sizeof(info
->stats
));
2400 msgqueue_initialise(&info
->scsi
.msgs
);
2402 if (!queue_initialise(&info
->queues
.issue
))
2405 if (!queue_initialise(&info
->queues
.disconnected
)) {
2406 queue_free(&info
->queues
.issue
);
2410 outb(CMD_RESETCHIP
, REG_CMD(info
));
2412 outb(0, REG_CNTL3(info
));
2413 outb(CNTL2_S2FE
, REG_CNTL2(info
));
2415 if ((inb(REG_CNTL2(info
)) & (~0xe0)) != CNTL2_S2FE
) {
2416 info
->scsi
.type
= "NCR53C90";
2418 outb(0, REG_CNTL2(info
));
2419 outb(0, REG_CNTL3(info
));
2420 outb(5, REG_CNTL3(info
));
2421 if (inb(REG_CNTL3(info
)) != 5) {
2422 info
->scsi
.type
= "NCR53C90A";
2424 outb(0, REG_CNTL3(info
));
2425 info
->scsi
.type
= "NCR53C9x";
2430 outb(CNTL3_ADIDCHK
, REG_CNTL3(info
));
2431 outb(0, REG_CNTL3(info
));
2433 outb(CMD_RESETCHIP
, REG_CMD(info
));
2434 outb(CMD_WITHDMA
| CMD_NOP
, REG_CMD(info
));
2435 outb(CNTL2_ENF
, REG_CNTL2(info
));
2436 outb(CMD_RESETCHIP
, REG_CMD(info
));
2437 switch (inb(REG1_ID(info
))) {
2439 info
->scsi
.type
= "Am53CF94";
2446 /* now for the real initialisation */
2447 fas216_init_chip(info
);
2449 outb(info
->scsi
.cfg
[0] | CNTL1_DISR
, REG_CNTL1(info
));
2450 outb(CMD_RESETSCSI
, REG_CMD(info
));
2452 /* scsi standard says 250ms */
2453 target_jiffies
= jiffies
+ (25 * HZ
) / 100;
2457 while (time_before(jiffies
, target_jiffies
)) barrier();
2459 restore_flags(flags
);
2461 outb(info
->scsi
.cfg
[0], REG_CNTL1(info
));
2462 inb(REG_INST(info
));
2464 /* now for the real initialisation */
2465 fas216_init_chip(info
);
2467 fas216_checkmagic(info
, "fas216_init");
2472 /* Function: int fas216_release(struct Scsi_Host *instance)
2473 * Purpose : release all resources and put everything to bed for
2474 * FAS/NCR/AMD SCSI ic.
2475 * Params : instance - a driver-specific filled-out structure
2476 * Returns : 0 on success
2478 int fas216_release(struct Scsi_Host
*instance
)
2480 FAS216_Info
*info
= (FAS216_Info
*)instance
->hostdata
;
2482 fas216_checkmagic(info
, "fas216_release");
2484 outb(CMD_RESETCHIP
, REG_CMD(info
));
2485 queue_free(&info
->queues
.disconnected
);
2486 queue_free(&info
->queues
.issue
);
2491 int fas216_print_stats(FAS216_Info
*info
, char *buffer
)
2493 return sprintf(buffer
,
2494 "Queued commands: %-10u Issued commands: %-10u\n"
2495 "Done commands : %-10u Reads : %-10u\n"
2496 "Writes : %-10u Others : %-10u\n"
2497 "Disconnects : %-10u Aborts : %-10u\n"
2499 info
->stats
.queues
, info
->stats
.removes
,
2500 info
->stats
.fins
, info
->stats
.reads
,
2501 info
->stats
.writes
, info
->stats
.miscs
,
2502 info
->stats
.disconnects
, info
->stats
.aborts
,
2503 info
->stats
.resets
);
2506 int fas216_print_device(FAS216_Info
*info
, Scsi_Device
*scd
, char *buffer
)
2508 struct fas216_device
*dev
= &info
->device
[scd
->id
];
2512 proc_print_scsidevice(scd
, buffer
, &len
, 0);
2515 p
+= sprintf(p
, " Extensions: ");
2517 if (scd
->tagged_supported
)
2518 p
+= sprintf(p
, "TAG %sabled [%d] ",
2519 scd
->tagged_queue
? "en" : "dis",
2522 p
+= sprintf(p
, "\n Transfers : %d-bit ",
2523 8 << dev
->wide_xfer
);
2526 p
+= sprintf(p
, "sync offset %d, %d ns\n",
2527 dev
->sof
, dev
->period
* 4);
2529 p
+= sprintf(p
, "async\n");
2534 EXPORT_SYMBOL(fas216_init
);
2535 EXPORT_SYMBOL(fas216_abort
);
2536 EXPORT_SYMBOL(fas216_reset
);
2537 EXPORT_SYMBOL(fas216_queue_command
);
2538 EXPORT_SYMBOL(fas216_command
);
2539 EXPORT_SYMBOL(fas216_intr
);
2540 EXPORT_SYMBOL(fas216_release
);
2541 EXPORT_SYMBOL(fas216_eh_abort
);
2542 EXPORT_SYMBOL(fas216_eh_device_reset
);
2543 EXPORT_SYMBOL(fas216_eh_bus_reset
);
2544 EXPORT_SYMBOL(fas216_eh_host_reset
);
2545 EXPORT_SYMBOL(fas216_print_stats
);
2546 EXPORT_SYMBOL(fas216_print_device
);
2549 int init_module(void)
2554 void cleanup_module(void)