]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/isp/isp_target.c
This commit was generated by cvs2svn to compensate for changes in r161561,
[FreeBSD/FreeBSD.git] / sys / dev / isp / isp_target.c
1 /*-
2  * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters.
3  *
4  * Copyright (c) 1997-2006 by Matthew Jacob
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice immediately at the beginning of the file, without modification,
12  *    this list of conditions, and the following disclaimer.
13  * 2. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 /*
29  * Bug fixes gratefully acknowledged from:
30  *      Oded Kedem <oded@kashya.com>
31  */
32 /*
33  * Include header file appropriate for platform we're building on.
34  */
35
36 #ifdef  __NetBSD__
37 #include <dev/ic/isp_netbsd.h>
38 #endif
39 #ifdef  __FreeBSD__
40 #include <sys/cdefs.h>
41 __FBSDID("$FreeBSD$");
42 #include <dev/isp/isp_freebsd.h>
43 #endif
44 #ifdef  __OpenBSD__
45 #include <dev/ic/isp_openbsd.h>
46 #endif
47 #ifdef  __linux__
48 #include "isp_linux.h"
49 #endif
50
51 #ifdef  ISP_TARGET_MODE
52 static const char atiocope[] =
53     "ATIO returned for lun %d because it was in the middle of Bus Device Reset "
54     "on bus %d";
55 static const char atior[] =
56     "ATIO returned on for lun %d on from IID %d because a Bus Reset occurred "
57     "on bus %d";
58
59 static void isp_got_msg(ispsoftc_t *, in_entry_t *);
60 static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *);
61 static void isp_handle_atio(ispsoftc_t *, at_entry_t *);
62 static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *);
63 static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *);
64 static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *);
65
66 /*
67  * The Qlogic driver gets an interrupt to look at response queue entries.
68  * Some of these are status completions for initiatior mode commands, but
69  * if target mode is enabled, we get a whole wad of response queue entries
70  * to be handled here.
71  *
72  * Basically the split into 3 main groups: Lun Enable/Modification responses,
73  * SCSI Command processing, and Immediate Notification events.
74  *
75  * You start by writing a request queue entry to enable target mode (and
76  * establish some resource limitations which you can modify later).
77  * The f/w responds with a LUN ENABLE or LUN MODIFY response with
78  * the status of this action. If the enable was successful, you can expect...
79  *
80  * Response queue entries with SCSI commands encapsulate show up in an ATIO
81  * (Accept Target IO) type- sometimes with enough info to stop the command at
82  * this level. Ultimately the driver has to feed back to the f/w's request
83  * queue a sequence of CTIOs (continue target I/O) that describe data to
84  * be moved and/or status to be sent) and finally finishing with sending
85  * to the f/w's response queue an ATIO which then completes the handshake
86  * with the f/w for that command. There's a lot of variations on this theme,
87  * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel
88  * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic
89  * gist of it.
90  *
91  * The third group that can show up in the response queue are Immediate
92  * Notification events. These include things like notifications of SCSI bus
93  * resets, or Bus Device Reset messages or other messages received. This
94  * a classic oddbins area. It can get  a little weird because you then turn
95  * around and acknowledge the Immediate Notify by writing an entry onto the
96  * request queue and then the f/w turns around and gives you an acknowledgement
97  * to *your* acknowledgement on the response queue (the idea being to let
98  * the f/w tell you when the event is *really* over I guess).
99  *
100  */
101
102
103 /*
104  * A new response queue entry has arrived. The interrupt service code
105  * has already swizzled it into the platform dependent from canonical form.
106  *
107  * Because of the way this driver is designed, unfortunately most of the
108  * actual synchronization work has to be done in the platform specific
109  * code- we have no synchroniation primitives in the common code.
110  */
111
112 int
113 isp_target_notify(ispsoftc_t *isp, void *vptr, uint16_t *optrp)
114 {
115         uint16_t status, seqid;
116         union {
117                 at_entry_t      *atiop;
118                 at2_entry_t     *at2iop;
119                 at2e_entry_t    *at2eiop;
120                 ct_entry_t      *ctiop;
121                 ct2_entry_t     *ct2iop;
122                 ct2e_entry_t    *ct2eiop;
123                 lun_entry_t     *lunenp;
124                 in_entry_t      *inotp;
125                 in_fcentry_t    *inot_fcp;
126                 in_fcentry_e_t  *inote_fcp;
127                 na_entry_t      *nackp;
128                 na_fcentry_t    *nack_fcp;
129                 na_fcentry_e_t  *nacke_fcp;
130                 isphdr_t        *hp;
131                 void *          *vp;
132 #define atiop           unp.atiop
133 #define at2iop          unp.at2iop
134 #define at2eiop         unp.at2eiop
135 #define ctiop           unp.ctiop
136 #define ct2iop          unp.ct2iop
137 #define ct2eiop         unp.ct2eiop
138 #define lunenp          unp.lunenp
139 #define inotp           unp.inotp
140 #define inot_fcp        unp.inot_fcp
141 #define inote_fcp       unp.inote_fcp
142 #define nackp           unp.nackp
143 #define nack_fcp        unp.nack_fcp
144 #define nacke_fcp       unp.nacke_fcp
145 #define hdrp            unp.hp
146         } unp;
147         uint8_t local[QENTRY_LEN];
148         int bus, type, rval = 1;
149
150         type = isp_get_response_type(isp, (isphdr_t *)vptr);
151         unp.vp = vptr;
152
153         ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr);
154
155         switch(type) {
156         case RQSTYPE_ATIO:
157                 isp_get_atio(isp, atiop, (at_entry_t *) local);
158                 isp_handle_atio(isp, (at_entry_t *) local);
159                 break;
160         case RQSTYPE_CTIO:
161                 isp_get_ctio(isp, ctiop, (ct_entry_t *) local);
162                 isp_handle_ctio(isp, (ct_entry_t *) local);
163                 break;
164         case RQSTYPE_ATIO2:
165                 if (IS_2KLOGIN(isp)) {
166                         isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local);
167                 } else {
168                         isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
169         }
170                 isp_handle_atio2(isp, (at2_entry_t *) local);
171                 break;
172         case RQSTYPE_CTIO3:
173         case RQSTYPE_CTIO2:
174                 if (IS_2KLOGIN(isp)) {
175                         isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local);
176                 } else {
177                         isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
178         }
179                 isp_handle_ctio2(isp, (ct2_entry_t *) local);
180                 break;
181         case RQSTYPE_ENABLE_LUN:
182         case RQSTYPE_MODIFY_LUN:
183                 isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
184                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
185                 break;
186
187         case RQSTYPE_NOTIFY:
188                 /*
189                  * Either the ISP received a SCSI message it can't
190                  * handle, or it's returning an Immed. Notify entry
191                  * we sent. We can send Immed. Notify entries to
192                  * increment the firmware's resource count for them
193                  * (we set this initially in the Enable Lun entry).
194                  */
195                 bus = 0;
196                 if (IS_FC(isp)) {
197                         if (IS_2KLOGIN(isp)) {
198                                 isp_get_notify_fc_e(isp, inote_fcp,
199                                     (in_fcentry_e_t *)local);
200                         } else {
201                                 isp_get_notify_fc(isp, inot_fcp,
202                                     (in_fcentry_t *)local);
203                         }
204                         inot_fcp = (in_fcentry_t *) local;
205                         status = inot_fcp->in_status;
206                         seqid = inot_fcp->in_seqid;
207                 } else {
208                         isp_get_notify(isp, inotp, (in_entry_t *)local);
209                         inotp = (in_entry_t *) local;
210                         status = inotp->in_status & 0xff;
211                         seqid = inotp->in_seqid;
212                         if (IS_DUALBUS(isp)) {
213                                 bus = GET_BUS_VAL(inotp->in_iid);
214                                 SET_BUS_VAL(inotp->in_iid, 0);
215                         }
216                 }
217
218                 isp_prt(isp, ISP_LOGTDEBUG0,
219                     "Immediate Notify On Bus %d, status=0x%x seqid=0x%x",
220                     bus, status, seqid);
221
222                 switch (status) {
223                 case IN_MSG_RECEIVED:
224                 case IN_IDE_RECEIVED:
225                         if (IS_FC(isp)) {
226                                 isp_got_msg_fc(isp, (in_fcentry_t *)local);
227                         } else {
228                                 isp_got_msg(isp, (in_entry_t *)local);
229                         }
230                         break;
231                 case IN_RSRC_UNAVAIL:
232                         isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
233                         isp_notify_ack(isp, local);
234                         break;
235                 case IN_RESET:
236                         (void) isp_target_async(isp, 0, ASYNC_BUS_RESET);
237                         break;
238                 case IN_PORT_LOGOUT:
239                 case IN_ABORT_TASK:
240                 case IN_PORT_CHANGED:
241                 case IN_GLOBAL_LOGO:
242                         (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
243                         break;
244                 default:
245                         isp_prt(isp, ISP_LOGERR,
246                             "bad status (0x%x) in isp_target_notify", status);
247                         isp_notify_ack(isp, local);
248                         break;
249                 }
250                 break;
251
252         case RQSTYPE_NOTIFY_ACK:
253                 /*
254                  * The ISP is acknowledging our acknowledgement of an
255                  * Immediate Notify entry for some asynchronous event.
256                  */
257                 if (IS_FC(isp)) {
258                         if (IS_2KLOGIN(isp)) {
259                                 isp_get_notify_ack_fc_e(isp, nacke_fcp,
260                                     (na_fcentry_e_t *)local);
261                         } else {
262                                 isp_get_notify_ack_fc(isp, nack_fcp,
263                                     (na_fcentry_t *)local);
264             }
265                         nack_fcp = (na_fcentry_t *)local;
266                         isp_prt(isp, ISP_LOGTDEBUG1,
267                             "Notify Ack status=0x%x seqid 0x%x",
268                             nack_fcp->na_status, nack_fcp->na_seqid);
269                 } else {
270                         isp_get_notify_ack(isp, nackp, (na_entry_t *)local);
271                         nackp = (na_entry_t *)local;
272                         isp_prt(isp, ISP_LOGTDEBUG1,
273                             "Notify Ack event 0x%x status=0x%x seqid 0x%x",
274                             nackp->na_event, nackp->na_status, nackp->na_seqid);
275                 }
276                 break;
277         default:
278                 isp_prt(isp, ISP_LOGERR,
279                     "Unknown entry type 0x%x in isp_target_notify", type);
280                 rval = 0;
281                 break;
282         }
283 #undef  atiop
284 #undef  at2iop
285 #undef  at2eiop
286 #undef  ctiop
287 #undef  ct2iop
288 #undef  ct2eiop
289 #undef  lunenp
290 #undef  inotp
291 #undef  inot_fcp
292 #undef  inote_fcp
293 #undef  nackp
294 #undef  nack_fcp
295 #undef  nacke_fcp
296 #undef  hdrp
297         return (rval);
298 }
299
300  
301 /*
302  * Toggle (on/off) target mode for bus/target/lun
303  *
304  * The caller has checked for overlap and legality.
305  *
306  * Note that not all of bus, target or lun can be paid attention to.
307  * Note also that this action will not be complete until the f/w writes
308  * response entry. The caller is responsible for synchronizing this.
309  */
310 int
311 isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int tgt, int lun,
312     int cmd_cnt, int inot_cnt, uint32_t opaque)
313 {
314         lun_entry_t el;
315         uint16_t nxti, optr;
316         void *outp;
317
318
319         MEMZERO(&el, sizeof (el));
320         if (IS_DUALBUS(isp)) {
321                 el.le_rsvd = (bus & 0x1) << 7;
322         }
323         el.le_cmd_count = cmd_cnt;
324         el.le_in_count = inot_cnt;
325         if (cmd == RQSTYPE_ENABLE_LUN) {
326                 if (IS_SCSI(isp)) {
327                         el.le_flags = LUN_TQAE|LUN_DISAD;
328                         el.le_cdb6len = 12;
329                         el.le_cdb7len = 12;
330                 }
331         } else if (cmd == -RQSTYPE_ENABLE_LUN) {
332                 cmd = RQSTYPE_ENABLE_LUN;
333                 el.le_cmd_count = 0;
334                 el.le_in_count = 0;
335         } else if (cmd == -RQSTYPE_MODIFY_LUN) {
336                 cmd = RQSTYPE_MODIFY_LUN;
337                 el.le_ops = LUN_CCDECR | LUN_INDECR;
338         } else {
339                 el.le_ops = LUN_CCINCR | LUN_ININCR;
340         }
341         el.le_header.rqs_entry_type = cmd;
342         el.le_header.rqs_entry_count = 1;
343         el.le_reserved = opaque;
344         if (IS_SCSI(isp)) {
345                 el.le_tgt = tgt;
346                 el.le_lun = lun;
347         } else if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
348                 el.le_lun = lun;
349         }
350
351         if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
352                 isp_prt(isp, ISP_LOGERR,
353                     "Request Queue Overflow in isp_lun_cmd");
354                 return (-1);
355         }
356         ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el);
357         isp_put_enable_lun(isp, &el, outp);
358         ISP_ADD_REQUEST(isp, nxti);
359         return (0);
360 }
361
362
363 int
364 isp_target_put_entry(ispsoftc_t *isp, void *ap)
365 {
366         void *outp;
367         uint16_t nxti, optr;
368         uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type;
369
370         if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
371                 isp_prt(isp, ISP_LOGWARN,
372                     "Request Queue Overflow in isp_target_put_entry");
373                 return (-1);
374         }
375         switch (etype) {
376         case RQSTYPE_ATIO:
377                 isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
378                 break;
379         case RQSTYPE_ATIO2:
380         if (IS_2KLOGIN(isp)) {
381             isp_put_atio2e(isp, (at2e_entry_t *) ap, (at2e_entry_t *) outp);
382         } else {
383             isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp);
384         }
385                 break;
386         case RQSTYPE_CTIO:
387                 isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
388                 break;
389         case RQSTYPE_CTIO2:
390         if (IS_2KLOGIN(isp)) {
391             isp_put_ctio2e(isp, (ct2e_entry_t *) ap, (ct2e_entry_t *) outp);
392         } else {
393             isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp);
394         }
395                 break;
396         default:
397                 isp_prt(isp, ISP_LOGERR,
398                     "Unknown type 0x%x in isp_put_entry", etype);
399                 return (-1);
400         }
401
402         ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);
403         ISP_ADD_REQUEST(isp, nxti);
404         return (0);
405 }
406
407 int
408 isp_target_put_atio(ispsoftc_t *isp, void *arg)
409 {
410         union {
411                 at_entry_t _atio;
412                 at2_entry_t _atio2;
413                 at2e_entry_t _atio2e;
414         } atun;
415
416         MEMZERO(&atun, sizeof atun);
417         if (IS_FC(isp)) {
418                 at2_entry_t *aep = arg;
419                 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
420                 atun._atio2.at_header.rqs_entry_count = 1;
421                 if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
422                         atun._atio2.at_scclun = (uint16_t) aep->at_scclun;
423                 } else {
424                         atun._atio2.at_lun = (uint8_t) aep->at_lun;
425                 }
426                 if (IS_2KLOGIN(isp)) {
427                         atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid;
428                 } else {
429                         atun._atio2.at_iid = aep->at_iid;
430                 }
431                 atun._atio2.at_rxid = aep->at_rxid;
432                 atun._atio2.at_status = CT_OK;
433         } else {
434                 at_entry_t *aep = arg;
435                 atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO;
436                 atun._atio.at_header.rqs_entry_count = 1;
437                 atun._atio.at_handle = aep->at_handle;
438                 atun._atio.at_iid = aep->at_iid;
439                 atun._atio.at_tgt = aep->at_tgt;
440                 atun._atio.at_lun = aep->at_lun;
441                 atun._atio.at_tag_type = aep->at_tag_type;
442                 atun._atio.at_tag_val = aep->at_tag_val;
443                 atun._atio.at_status = (aep->at_flags & AT_TQAE);
444                 atun._atio.at_status |= CT_OK;
445         }
446         return (isp_target_put_entry(isp, &atun));
447 }
448
449 /*
450  * Command completion- both for handling cases of no resources or
451  * no blackhole driver, or other cases where we have to, inline,
452  * finish the command sanely, or for normal command completion.
453  *
454  * The 'completion' code value has the scsi status byte in the low 8 bits.
455  * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have
456  * the sense key and  bits 16..23 have the ASCQ and bits 24..31 have the ASC
457  * values.
458  *
459  * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't
460  * NB: inline SCSI sense reporting. As such, we lose this information. XXX.
461  *
462  * For both parallel && fibre channel, we use the feature that does
463  * an automatic resource autoreplenish so we don't have then later do
464  * put of an atio to replenish the f/w's resource count.
465  */
466
467 int
468 isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint16_t hdl)
469 {
470         int sts;
471         union {
472                 ct_entry_t _ctio;
473                 ct2_entry_t _ctio2;
474                 ct2e_entry_t _ctio2e;
475         } un;
476
477         MEMZERO(&un, sizeof un);
478         sts = code & 0xff;
479
480         if (IS_FC(isp)) {
481                 at2_entry_t *aep = arg;
482                 ct2_entry_t *cto = &un._ctio2;
483
484                 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
485                 cto->ct_header.rqs_entry_count = 1;
486                 if ((FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) == 0) {
487                         cto->ct_lun = aep->at_lun;
488                 }
489                 if (IS_2KLOGIN(isp)) {
490                         un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid;
491                 } else {
492                         cto->ct_iid = aep->at_iid;
493                 }
494                 cto->ct_rxid = aep->at_rxid;
495                 cto->rsp.m1.ct_scsi_status = sts;
496                 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1;
497                 if (hdl == 0) {
498                         cto->ct_flags |= CT2_CCINCR;
499                 }
500                 if (aep->at_datalen) {
501                         cto->ct_resid = aep->at_datalen;
502                         cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER;
503                 }
504                 if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
505                         cto->rsp.m1.ct_resp[0] = 0xf0;
506                         cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
507                         cto->rsp.m1.ct_resp[7] = 8;
508                         cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
509                         cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
510                         cto->rsp.m1.ct_senselen = 16;
511                         cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID;
512                 }
513                 cto->ct_syshandle = hdl;
514         } else {
515                 at_entry_t *aep = arg;
516                 ct_entry_t *cto = &un._ctio;
517
518                 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
519                 cto->ct_header.rqs_entry_count = 1;
520                 cto->ct_fwhandle = aep->at_handle;
521                 cto->ct_iid = aep->at_iid;
522                 cto->ct_tgt = aep->at_tgt;
523                 cto->ct_lun = aep->at_lun;
524                 cto->ct_tag_type = aep->at_tag_type;
525                 cto->ct_tag_val = aep->at_tag_val;
526                 if (aep->at_flags & AT_TQAE) {
527                         cto->ct_flags |= CT_TQAE;
528                 }
529                 cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA;
530                 if (hdl == 0) {
531                         cto->ct_flags |= CT_CCINCR;
532                 }
533                 cto->ct_scsi_status = sts;
534                 cto->ct_syshandle = hdl;
535         }
536         return (isp_target_put_entry(isp, &un));
537 }
538
539 /*
540  * These are either broadcast events or specifically CTIO fast completion
541  */
542 int
543 isp_target_async(ispsoftc_t *isp, int bus, int event)
544 {
545         tmd_notify_t notify;
546
547         MEMZERO(&notify, sizeof (tmd_notify_t));
548         notify.nt_hba = isp;
549         notify.nt_iid = INI_ANY;
550         /* nt_tgt set in outer layers */
551         notify.nt_lun = LUN_ANY;
552         notify.nt_tagval = TAG_ANY;
553
554         if (IS_SCSI(isp)) {
555                 TAG_INSERT_BUS(notify.nt_tagval, bus);
556         }
557
558         switch (event) {
559         case ASYNC_LOOP_UP:
560         case ASYNC_PTPMODE:
561                 notify.nt_ncode = NT_LINK_UP;
562                 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
563                 break;
564         case ASYNC_LOOP_DOWN:
565                 notify.nt_ncode = NT_LINK_DOWN;
566                 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
567                 break;
568         case ASYNC_LIP_F8:
569         case ASYNC_LIP_OCCURRED:
570         case ASYNC_LOOP_RESET:
571                 notify.nt_ncode = NT_LIP_RESET;
572                 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
573                 break;
574         case ASYNC_BUS_RESET:
575         case ASYNC_TIMEOUT_RESET:       /* XXX: where does this come from ? */
576                 notify.nt_ncode = NT_BUS_RESET;
577                 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
578                 break;
579         case ASYNC_DEVICE_RESET:
580                 notify.nt_ncode = NT_TARGET_RESET;
581                 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
582                 break;
583         case ASYNC_CTIO_DONE:
584         {
585                 uint8_t storage[QENTRY_LEN];
586                 memset(storage, 0, QENTRY_LEN);
587                 if (IS_FC(isp)) {
588                         /* This should also suffice for 2K login code */
589                         ct2_entry_t *ct = (ct2_entry_t *) storage;
590                         ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
591                         ct->ct_status = CT_OK;
592                         ct->ct_syshandle = bus;
593                         ct->ct_flags = CT2_SENDSTATUS|CT2_FASTPOST;
594                 } else {
595                         ct_entry_t *ct = (ct_entry_t *) storage;
596                         ct->ct_header.rqs_entry_type = RQSTYPE_CTIO;
597                         ct->ct_status = CT_OK;
598                         ct->ct_fwhandle = bus;
599                         ct->ct_flags = CT_SENDSTATUS;
600                 }
601                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
602                 return (0);
603         }
604         default:
605                 isp_prt(isp, ISP_LOGERR,
606                     "isp_target_async: unknown event 0x%x", event);
607                 if (isp->isp_state == ISP_RUNSTATE) {
608                         isp_notify_ack(isp, NULL);
609                 }
610                 break;
611         }
612         return (0);
613 }
614
615
616 /*
617  * Process a received message.
618  * The ISP firmware can handle most messages, there are only
619  * a few that we need to deal with:
620  * - abort: clean up the current command
621  * - abort tag and clear queue
622  */
623
624 static void
625 isp_got_msg(ispsoftc_t *isp, in_entry_t *inp)
626 {
627         tmd_notify_t nt;
628         uint8_t status = inp->in_status & ~QLTM_SVALID;
629
630         MEMZERO(&nt, sizeof (nt));
631         nt.nt_hba = isp;
632         nt.nt_iid = GET_IID_VAL(inp->in_iid);
633         nt.nt_tgt = inp->in_tgt;
634         nt.nt_lun = inp->in_lun;
635         IN_MAKE_TAGID(nt.nt_tagval, 0, inp);
636         nt.nt_lreserved = inp;
637
638         if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) {
639                 switch (inp->in_msg[0]) {
640                 case MSG_ABORT:
641                         nt.nt_ncode = NT_ABORT_TASK_SET;
642                         break;
643                 case MSG_BUS_DEV_RESET:
644                         nt.nt_ncode = NT_TARGET_RESET;
645                         break;
646                 case MSG_ABORT_TAG:
647                         nt.nt_ncode = NT_ABORT_TASK;
648                         break;
649                 case MSG_CLEAR_QUEUE:
650                         nt.nt_ncode = NT_CLEAR_TASK_SET;
651                         break;
652                 case MSG_REL_RECOVERY:
653                         nt.nt_ncode = NT_CLEAR_ACA;
654                         break;
655                 case MSG_TERM_IO_PROC:
656                         nt.nt_ncode = NT_ABORT_TASK;
657                         break;
658                 case MSG_LUN_RESET:
659                         nt.nt_ncode = NT_LUN_RESET;
660                         break;
661                 default:
662                         isp_prt(isp, ISP_LOGERR,
663                             "unhandled message 0x%x", inp->in_msg[0]);
664                         isp_notify_ack(isp, inp);
665                         return;
666                 }
667                 (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
668         } else {
669                 isp_prt(isp, ISP_LOGERR,
670                     "unknown immediate notify status 0x%x", inp->in_status);
671                 isp_notify_ack(isp, inp);
672         }
673 }
674
675 /*
676  * Synthesize a message from the task management flags in a FCP_CMND_IU.
677  */
678 static void
679 isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
680 {
681         tmd_notify_t nt;
682         static const char f1[] = "%s from loop id %d lun %d seq 0x%x";
683         static const char f2[] = 
684             "unknown %s 0x%x lun %d loop id %d task flags 0x%x seq 0x%x\n";
685         uint16_t seqid, loopid;
686
687         MEMZERO(&nt, sizeof (tmd_notify_t));
688         nt.nt_hba = isp;
689         if (IS_2KLOGIN(isp)) {
690                 nt.nt_iid = ((in_fcentry_e_t *)inp)->in_iid;
691                 loopid = ((in_fcentry_e_t *)inp)->in_iid;
692                 seqid = ((in_fcentry_e_t *)inp)->in_seqid;
693         } else {
694                 nt.nt_iid = inp->in_iid;
695                 loopid = inp->in_iid;
696                 seqid = inp->in_seqid;
697         }
698         /* nt_tgt set in outer layers */
699         if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
700                 nt.nt_lun = inp->in_scclun;
701         } else {
702                 nt.nt_lun = inp->in_lun;
703         }
704         IN_FC_MAKE_TAGID(nt.nt_tagval, 0, seqid);
705         nt.nt_lreserved = inp;
706
707         if (inp->in_status != IN_MSG_RECEIVED) {
708                 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status",
709                     inp->in_status, nt.nt_lun, loopid, inp->in_task_flags,
710                     inp->in_seqid);
711                 isp_notify_ack(isp, inp);
712                 return;
713         }
714
715         if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) {
716                 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
717                     loopid, nt.nt_lun, inp->in_seqid);
718                 nt.nt_ncode = NT_ABORT_TASK_SET;
719         } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) {
720                 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
721                     loopid, nt.nt_lun, inp->in_seqid);
722                 nt.nt_ncode = NT_CLEAR_TASK_SET;
723         } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) {
724                 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
725                     loopid, nt.nt_lun, inp->in_seqid);
726                 nt.nt_ncode = NT_LUN_RESET;
727         } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) {
728                 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
729                     loopid, nt.nt_lun, inp->in_seqid);
730                 nt.nt_ncode = NT_TARGET_RESET;
731         } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) {
732                 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
733                     loopid, nt.nt_lun, inp->in_seqid);
734                 nt.nt_ncode = NT_CLEAR_ACA;
735         } else {
736                 isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status,
737                     nt.nt_lun, loopid, inp->in_task_flags,  inp->in_seqid);
738                 isp_notify_ack(isp, inp);
739                 return;
740         }
741         (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
742 }
743
744 void
745 isp_notify_ack(ispsoftc_t *isp, void *arg)
746 {
747         char storage[QENTRY_LEN];
748         uint16_t nxti, optr;
749         void *outp;
750
751         if (isp_getrqentry(isp, &nxti, &optr, &outp)) {
752                 isp_prt(isp, ISP_LOGWARN,
753                     "Request Queue Overflow For isp_notify_ack");
754                 return;
755         }
756
757         MEMZERO(storage, QENTRY_LEN);
758
759         if (IS_FC(isp)) {
760                 na_fcentry_t *na = (na_fcentry_t *) storage;
761                 int iid = 0;
762
763                 if (arg) {
764                         in_fcentry_t *inp = arg;
765                         MEMCPY(storage, arg, sizeof (isphdr_t));
766                         if (IS_2KLOGIN(isp)) {
767                                 ((na_fcentry_e_t *)na)->na_iid =
768                                     ((in_fcentry_e_t *)inp)->in_iid;
769                                 iid = ((na_fcentry_e_t *)na)->na_iid;
770                         } else {
771                                 na->na_iid = inp->in_iid;
772                                 iid = na->na_iid;
773                         }
774                         na->na_task_flags =
775                             inp->in_task_flags & TASK_FLAGS_RESERVED_MASK;
776                         na->na_seqid = inp->in_seqid;
777                         na->na_flags = NAFC_RCOUNT;
778                         na->na_status = inp->in_status;
779                         if (inp->in_status == IN_RESET) {
780                                 na->na_flags |= NAFC_RST_CLRD;
781                         }
782                         if (inp->in_status == IN_MSG_RECEIVED) {
783                                 na->na_flags |= NAFC_TVALID;
784                                 na->na_response = 0;    /* XXX SUCCEEDED XXX */
785                         }
786                 } else {
787                         na->na_flags = NAFC_RST_CLRD;
788                 }
789                 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
790                 na->na_header.rqs_entry_count = 1;
791                 if (IS_2KLOGIN(isp)) {
792                         isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na,
793                             (na_fcentry_e_t *)outp);
794                 } else {
795                         isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp);
796                 }
797                 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack iid %u seqid %x flags "
798                     "%x tflags %x response %x", iid, na->na_seqid,
799                     na->na_flags, na->na_task_flags, na->na_response);
800         } else {
801                 na_entry_t *na = (na_entry_t *) storage;
802                 if (arg) {
803                         in_entry_t *inp = arg;
804                         MEMCPY(storage, arg, sizeof (isphdr_t));
805                         na->na_iid = inp->in_iid;
806                         na->na_lun = inp->in_lun;
807                         na->na_tgt = inp->in_tgt;
808                         na->na_seqid = inp->in_seqid;
809                         if (inp->in_status == IN_RESET) {
810                                 na->na_event = NA_RST_CLRD;
811                         }
812                 } else {
813                         na->na_event = NA_RST_CLRD;
814                 }
815                 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
816                 na->na_header.rqs_entry_count = 1;
817                 isp_put_notify_ack(isp, na, (na_entry_t *)outp);
818                 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack iid %u lun %u tgt %u "
819                     "seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt,
820                     na->na_seqid, na->na_event);
821         }
822         ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage);
823         ISP_ADD_REQUEST(isp, nxti);
824 }
825
826 static void
827 isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
828 {
829         int lun;
830         lun = aep->at_lun;
831         /*
832          * The firmware status (except for the QLTM_SVALID bit) indicates
833          * why this ATIO was sent to us.
834          *
835          * If QLTM_SVALID is set, the firware has recommended Sense Data.
836          *
837          * If the DISCONNECTS DISABLED bit is set in the flags field,
838          * we're still connected on the SCSI bus - i.e. the initiator
839          * did not set DiscPriv in the identify message. We don't care
840          * about this so it's ignored.
841          */
842
843         switch(aep->at_status & ~QLTM_SVALID) {
844         case AT_PATH_INVALID:
845                 /*
846                  * ATIO rejected by the firmware due to disabled lun.
847                  */
848                 isp_prt(isp, ISP_LOGERR,
849                     "rejected ATIO for disabled lun %d", lun);
850                 break;
851         case AT_NOCAP:
852                 /*
853                  * Requested Capability not available
854                  * We sent an ATIO that overflowed the firmware's
855                  * command resource count.
856                  */
857                 isp_prt(isp, ISP_LOGERR,
858                     "rejected ATIO for lun %d because of command count"
859                     " overflow", lun);
860                 break;
861
862         case AT_BDR_MSG:
863                 /*
864                  * If we send an ATIO to the firmware to increment
865                  * its command resource count, and the firmware is
866                  * recovering from a Bus Device Reset, it returns
867                  * the ATIO with this status. We set the command
868                  * resource count in the Enable Lun entry and do
869                  * not increment it. Therefore we should never get
870                  * this status here.
871                  */
872                 isp_prt(isp, ISP_LOGERR, atiocope, lun,
873                     GET_BUS_VAL(aep->at_iid));
874                 break;
875
876         case AT_CDB:            /* Got a CDB */
877         case AT_PHASE_ERROR:    /* Bus Phase Sequence Error */
878                 /*
879                  * Punt to platform specific layer.
880                  */
881                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
882                 break;
883
884         case AT_RESET:
885                 /*
886                  * A bus reset came along and blew away this command. Why
887                  * they do this in addition the async event code stuff,
888                  * I dunno.
889                  *
890                  * Ignore it because the async event will clear things
891                  * up for us.
892                  */
893                 isp_prt(isp, ISP_LOGWARN, atior, lun,
894                     GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid));
895                 break;
896
897
898         default:
899                 isp_prt(isp, ISP_LOGERR,
900                     "Unknown ATIO status 0x%x from initiator %d for lun %d",
901                     aep->at_status, aep->at_iid, lun);
902                 (void) isp_target_put_atio(isp, aep);
903                 break;
904         }
905 }
906
907 static void
908 isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
909 {
910         int lun, iid;
911
912         if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
913                 lun = aep->at_scclun;
914         } else {
915                 lun = aep->at_lun;
916         }
917
918         if (IS_2KLOGIN(isp)) {
919                 iid = ((at2e_entry_t *)aep)->at_iid;
920         } else {
921                 iid = aep->at_iid;
922         }
923
924         /*
925          * The firmware status (except for the QLTM_SVALID bit) indicates
926          * why this ATIO was sent to us.
927          *
928          * If QLTM_SVALID is set, the firware has recommended Sense Data.
929          *
930          * If the DISCONNECTS DISABLED bit is set in the flags field,
931          * we're still connected on the SCSI bus - i.e. the initiator
932          * did not set DiscPriv in the identify message. We don't care
933          * about this so it's ignored.
934          */
935
936         switch(aep->at_status & ~QLTM_SVALID) {
937         case AT_PATH_INVALID:
938                 /*
939                  * ATIO rejected by the firmware due to disabled lun.
940                  */
941                 isp_prt(isp, ISP_LOGERR,
942                     "rejected ATIO2 for disabled lun %d", lun);
943                 break;
944         case AT_NOCAP:
945                 /*
946                  * Requested Capability not available
947                  * We sent an ATIO that overflowed the firmware's
948                  * command resource count.
949                  */
950                 isp_prt(isp, ISP_LOGERR,
951                     "rejected ATIO2 for lun %d- command count overflow", lun);
952                 break;
953
954         case AT_BDR_MSG:
955                 /*
956                  * If we send an ATIO to the firmware to increment
957                  * its command resource count, and the firmware is
958                  * recovering from a Bus Device Reset, it returns
959                  * the ATIO with this status. We set the command
960                  * resource count in the Enable Lun entry and no
961                  * not increment it. Therefore we should never get
962                  * this status here.
963                  */
964                 isp_prt(isp, ISP_LOGERR, atiocope, lun, 0);
965                 break;
966
967         case AT_CDB:            /* Got a CDB */
968                 /*
969                  * Punt to platform specific layer.
970                  */
971                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
972                 break;
973
974         case AT_RESET:
975                 /*
976                  * A bus reset came along an blew away this command. Why
977                  * they do this in addition the async event code stuff,
978                  * I dunno.
979                  *
980                  * Ignore it because the async event will clear things
981                  * up for us.
982                  */
983                 isp_prt(isp, ISP_LOGERR, atior, lun, iid, 0);
984                 break;
985
986
987         default:
988                 isp_prt(isp, ISP_LOGERR,
989                     "Unknown ATIO2 status 0x%x from initiator %d for lun %d",
990                     aep->at_status, iid, lun);
991                 (void) isp_target_put_atio(isp, aep);
992                 break;
993         }
994 }
995
996 static void
997 isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
998 {
999         void *xs;
1000         int pl = ISP_LOGTDEBUG2;
1001         char *fmsg = NULL;
1002
1003         if (ct->ct_syshandle) {
1004                 xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1005                 if (xs == NULL)
1006                         pl = ISP_LOGALL;
1007         } else {
1008                 xs = NULL;
1009         }
1010
1011         switch(ct->ct_status & ~QLTM_SVALID) {
1012         case CT_OK:
1013                 /*
1014                  * There are generally 3 possibilities as to why we'd get
1015                  * this condition:
1016                  *      We disconnected after receiving a CDB.
1017                  *      We sent or received data.
1018                  *      We sent status & command complete.
1019                  */
1020
1021                 if (ct->ct_flags & CT_SENDSTATUS) {
1022                         break;
1023                 } else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) {
1024                         /*
1025                          * Nothing to do in this case.
1026                          */
1027                         isp_prt(isp, pl, "CTIO- iid %d disconnected OK",
1028                             ct->ct_iid);
1029                         return;
1030                 }
1031                 break;
1032
1033         case CT_BDR_MSG:
1034                 /*
1035                  * Bus Device Reset message received or the SCSI Bus has
1036                  * been Reset; the firmware has gone to Bus Free.
1037                  *
1038                  * The firmware generates an async mailbox interupt to
1039                  * notify us of this and returns outstanding CTIOs with this
1040                  * status. These CTIOs are handled in that same way as
1041                  * CT_ABORTED ones, so just fall through here.
1042                  */
1043                 fmsg = "Bus Device Reset";
1044                 /*FALLTHROUGH*/
1045         case CT_RESET:
1046                 if (fmsg == NULL)
1047                         fmsg = "Bus Reset";
1048                 /*FALLTHROUGH*/
1049         case CT_ABORTED:
1050                 /*
1051                  * When an Abort message is received the firmware goes to
1052                  * Bus Free and returns all outstanding CTIOs with the status
1053                  * set, then sends us an Immediate Notify entry.
1054                  */
1055                 if (fmsg == NULL)
1056                         fmsg = "ABORT TAG message sent by Initiator";
1057
1058                 isp_prt(isp, ISP_LOGWARN, "CTIO destroyed by %s", fmsg);
1059                 break;
1060
1061         case CT_INVAL:
1062                 /*
1063                  * CTIO rejected by the firmware due to disabled lun.
1064                  * "Cannot Happen".
1065                  */
1066                 isp_prt(isp, ISP_LOGERR,
1067                     "Firmware rejected CTIO for disabled lun %d",
1068                     ct->ct_lun);
1069                 break;
1070
1071         case CT_NOPATH:
1072                 /*
1073                  * CTIO rejected by the firmware due "no path for the
1074                  * nondisconnecting nexus specified". This means that
1075                  * we tried to access the bus while a non-disconnecting
1076                  * command is in process.
1077                  */
1078                 isp_prt(isp, ISP_LOGERR,
1079                     "Firmware rejected CTIO for bad nexus %d/%d/%d",
1080                     ct->ct_iid, ct->ct_tgt, ct->ct_lun);
1081                 break;
1082
1083         case CT_RSELTMO:
1084                 fmsg = "Reselection";
1085                 /*FALLTHROUGH*/
1086         case CT_TIMEOUT:
1087                 if (fmsg == NULL)
1088                         fmsg = "Command";
1089                 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1090                 break;
1091
1092         case    CT_PANIC:
1093                 if (fmsg == NULL)
1094                         fmsg = "Unrecoverable Error";
1095                 /*FALLTHROUGH*/
1096         case CT_ERR:
1097                 if (fmsg == NULL)
1098                         fmsg = "Completed with Error";
1099                 /*FALLTHROUGH*/
1100         case CT_PHASE_ERROR:
1101                 if (fmsg == NULL)
1102                         fmsg = "Phase Sequence Error";
1103                 /*FALLTHROUGH*/
1104         case CT_TERMINATED:
1105                 if (fmsg == NULL)
1106                         fmsg = "terminated by TERMINATE TRANSFER";
1107                 /*FALLTHROUGH*/
1108         case CT_NOACK:
1109                 if (fmsg == NULL)
1110                         fmsg = "unacknowledged Immediate Notify pending";
1111                 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1112                 break;
1113         default:
1114                 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x",
1115                     ct->ct_status & ~QLTM_SVALID);
1116                 break;
1117         }
1118
1119         if (xs == NULL) {
1120                 /*
1121                  * There may be more than one CTIO for a data transfer,
1122                  * or this may be a status CTIO we're not monitoring.
1123                  *
1124                  * The assumption is that they'll all be returned in the
1125                  * order we got them.
1126                  */
1127                 if (ct->ct_syshandle == 0) {
1128                         if ((ct->ct_flags & CT_SENDSTATUS) == 0) {
1129                                 isp_prt(isp, pl,
1130                                     "intermediate CTIO completed ok");
1131                         } else {
1132                                 isp_prt(isp, pl,
1133                                     "unmonitored CTIO completed ok");
1134                         }
1135                 } else {
1136                         isp_prt(isp, pl,
1137                             "NO xs for CTIO (handle 0x%x) status 0x%x",
1138                             ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1139                 }
1140         } else {
1141                 /*
1142                  * Final CTIO completed. Release DMA resources and
1143                  * notify platform dependent layers.
1144                  */
1145                 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
1146                         ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1147                 }
1148                 isp_prt(isp, pl, "final CTIO complete");
1149                 /*
1150                  * The platform layer will destroy the handle if appropriate.
1151                  */
1152                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1153         }
1154 }
1155
1156 static void
1157 isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
1158 {
1159         XS_T *xs;
1160         int pl = ISP_LOGTDEBUG2;
1161         char *fmsg = NULL;
1162
1163         if (ct->ct_syshandle) {
1164                 xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
1165                 if (xs == NULL)
1166                         pl = ISP_LOGALL;
1167         } else {
1168                 xs = NULL;
1169         }
1170
1171         switch(ct->ct_status & ~QLTM_SVALID) {
1172         case CT_BUS_ERROR:
1173                 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error");
1174                 /* FALL Through */
1175         case CT_DATA_OVER:
1176         case CT_DATA_UNDER:
1177         case CT_OK:
1178                 /*
1179                  * There are generally 2 possibilities as to why we'd get
1180                  * this condition:
1181                  *      We sent or received data.
1182                  *      We sent status & command complete.
1183                  */
1184
1185                 break;
1186
1187         case CT_BDR_MSG:
1188                 /*
1189                  * Target Reset function received.
1190                  *
1191                  * The firmware generates an async mailbox interupt to
1192                  * notify us of this and returns outstanding CTIOs with this
1193                  * status. These CTIOs are handled in that same way as
1194                  * CT_ABORTED ones, so just fall through here.
1195                  */
1196                 fmsg = "TARGET RESET Task Management Function Received";
1197                 /*FALLTHROUGH*/
1198         case CT_RESET:
1199                 if (fmsg == NULL)
1200                         fmsg = "LIP Reset";
1201                 /*FALLTHROUGH*/
1202         case CT_ABORTED:
1203                 /*
1204                  * When an Abort message is received the firmware goes to
1205                  * Bus Free and returns all outstanding CTIOs with the status
1206                  * set, then sends us an Immediate Notify entry.
1207                  */
1208                 if (fmsg == NULL)
1209                         fmsg = "ABORT Task Management Function Received";
1210
1211                 isp_prt(isp, ISP_LOGERR, "CTIO2 destroyed by %s: RX_ID=0x%x",
1212                     fmsg, ct->ct_rxid);
1213                 break;
1214
1215         case CT_INVAL:
1216                 /*
1217                  * CTIO rejected by the firmware - invalid data direction.
1218                  */
1219                 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data direction");
1220                 break;
1221
1222         case CT_RSELTMO:
1223                 fmsg = "failure to reconnect to initiator";
1224                 /*FALLTHROUGH*/
1225         case CT_TIMEOUT:
1226                 if (fmsg == NULL)
1227                         fmsg = "command";
1228                 isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
1229                 break;
1230
1231         case CT_ERR:
1232                 fmsg = "Completed with Error";
1233                 /*FALLTHROUGH*/
1234         case CT_LOGOUT:
1235                 if (fmsg == NULL)
1236                         fmsg = "Port Logout";
1237                 /*FALLTHROUGH*/
1238         case CT_PORTNOTAVAIL:
1239                 if (fmsg == NULL)
1240                         fmsg = "Port not available";
1241                 /*FALLTHROUGH*/
1242         case CT_PORTCHANGED:
1243                 if (fmsg == NULL)
1244                         fmsg = "Port Changed";
1245                 /*FALLTHROUGH*/
1246         case CT_NOACK:
1247                 if (fmsg == NULL)
1248                         fmsg = "unacknowledged Immediate Notify pending";
1249                 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg);
1250                 break;
1251
1252         case CT_INVRXID:
1253                 /*
1254                  * CTIO rejected by the firmware because an invalid RX_ID.
1255                  * Just print a message.
1256                  */
1257                 isp_prt(isp, ISP_LOGERR,
1258                     "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
1259                 break;
1260
1261         default:
1262                 isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x",
1263                     ct->ct_status & ~QLTM_SVALID);
1264                 break;
1265         }
1266
1267         if (xs == NULL) {
1268                 /*
1269                  * There may be more than one CTIO for a data transfer,
1270                  * or this may be a status CTIO we're not monitoring.
1271                  *
1272                  * The assumption is that they'll all be returned in the
1273                  * order we got them.
1274                  */
1275                 if (ct->ct_syshandle == 0) {
1276                         if ((ct->ct_flags & CT2_SENDSTATUS) == 0) {
1277                                 isp_prt(isp, pl,
1278                                     "intermediate CTIO completed ok");
1279                         } else {
1280                                 isp_prt(isp, pl,
1281                                     "unmonitored CTIO completed ok");
1282                         }
1283                 } else {
1284                         isp_prt(isp, pl,
1285                             "NO xs for CTIO (handle 0x%x) status 0x%x",
1286                             ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID);
1287                 }
1288         } else {
1289                 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) {
1290                         ISP_DMAFREE(isp, xs, ct->ct_syshandle);
1291                 }
1292                 if (ct->ct_flags & CT2_SENDSTATUS) {
1293                         /*
1294                          * Sent status and command complete.
1295                          *
1296                          * We're now really done with this command, so we
1297                          * punt to the platform dependent layers because
1298                          * only there can we do the appropriate command
1299                          * complete thread synchronization.
1300                          */
1301                         isp_prt(isp, pl, "status CTIO complete");
1302                 } else {
1303                         /*
1304                          * Final CTIO completed. Release DMA resources and
1305                          * notify platform dependent layers.
1306                          */
1307                         isp_prt(isp, pl, "data CTIO complete");
1308                 }
1309                 (void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
1310                 /*
1311                  * The platform layer will destroy the handle if appropriate.
1312                  */
1313         }
1314 }
1315 #endif