1/*- 2 * Copyright (c) 1997-2009 by Matthew Jacob 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28/* 29 * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters. 30 */ 31/* 32 * Bug fixes gratefully acknowledged from: 33 * Oded Kedem <oded@kashya.com> 34 */ 35/* 36 * Include header file appropriate for platform we're building on. 37 */ 38 39#ifdef __NetBSD__ 40#include <dev/ic/isp_netbsd.h> 41#endif 42#ifdef __FreeBSD__ 43#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 1997-2009 by Matthew Jacob 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28/* 29 * Machine and OS Independent Target Mode Code for the Qlogic SCSI/FC adapters. 30 */ 31/* 32 * Bug fixes gratefully acknowledged from: 33 * Oded Kedem <oded@kashya.com> 34 */ 35/* 36 * Include header file appropriate for platform we're building on. 37 */ 38 39#ifdef __NetBSD__ 40#include <dev/ic/isp_netbsd.h> 41#endif 42#ifdef __FreeBSD__ 43#include <sys/cdefs.h>
|
44__FBSDID("$FreeBSD: head/sys/dev/isp/isp_target.c 204397 2010-02-27 05:41:23Z mjacob $");
| 44__FBSDID("$FreeBSD: head/sys/dev/isp/isp_target.c 238869 2012-07-28 20:06:29Z mjacob $");
|
45#include <dev/isp/isp_freebsd.h> 46#endif 47#ifdef __OpenBSD__ 48#include <dev/ic/isp_openbsd.h> 49#endif 50#ifdef __linux__ 51#include "isp_linux.h" 52#endif 53 54#ifdef ISP_TARGET_MODE 55static const char atiocope[] = "ATIO returned for lun %d because it was in the middle of Bus Device Reset on bus %d"; 56static const char atior[] = "ATIO returned on for lun %d on from loopid %d because a Bus Reset occurred on bus %d"; 57static const char rqo[] = "%s: Request Queue Overflow"; 58 59static void isp_got_msg(ispsoftc_t *, in_entry_t *); 60static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *); 61static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *); 62static void isp_handle_atio(ispsoftc_t *, at_entry_t *); 63static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *); 64static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *); 65static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *); 66static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *); 67static void isp_handle_24xx_inotify(ispsoftc_t *, in_fcentry_24xx_t *); 68 69/* 70 * The Qlogic driver gets an interrupt to look at response queue entries. 71 * Some of these are status completions for initiatior mode commands, but 72 * if target mode is enabled, we get a whole wad of response queue entries 73 * to be handled here. 74 * 75 * Basically the split into 3 main groups: Lun Enable/Modification responses, 76 * SCSI Command processing, and Immediate Notification events. 77 * 78 * You start by writing a request queue entry to enable target mode (and 79 * establish some resource limitations which you can modify later). 80 * The f/w responds with a LUN ENABLE or LUN MODIFY response with 81 * the status of this action. If the enable was successful, you can expect... 82 * 83 * Response queue entries with SCSI commands encapsulate show up in an ATIO 84 * (Accept Target IO) type- sometimes with enough info to stop the command at 85 * this level. Ultimately the driver has to feed back to the f/w's request 86 * queue a sequence of CTIOs (continue target I/O) that describe data to 87 * be moved and/or status to be sent) and finally finishing with sending 88 * to the f/w's response queue an ATIO which then completes the handshake 89 * with the f/w for that command. There's a lot of variations on this theme, 90 * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel 91 * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic 92 * gist of it. 93 * 94 * The third group that can show up in the response queue are Immediate 95 * Notification events. These include things like notifications of SCSI bus 96 * resets, or Bus Device Reset messages or other messages received. This 97 * a classic oddbins area. It can get a little weird because you then turn 98 * around and acknowledge the Immediate Notify by writing an entry onto the 99 * request queue and then the f/w turns around and gives you an acknowledgement 100 * to *your* acknowledgement on the response queue (the idea being to let 101 * the f/w tell you when the event is *really* over I guess). 102 * 103 */ 104 105 106/* 107 * A new response queue entry has arrived. The interrupt service code 108 * has already swizzled it into the platform dependent from canonical form. 109 * 110 * Because of the way this driver is designed, unfortunately most of the 111 * actual synchronization work has to be done in the platform specific 112 * code- we have no synchroniation primitives in the common code. 113 */ 114 115int 116isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) 117{ 118 uint16_t status; 119 uint32_t seqid; 120 union { 121 at_entry_t *atiop; 122 at2_entry_t *at2iop; 123 at2e_entry_t *at2eiop; 124 at7_entry_t *at7iop; 125 ct_entry_t *ctiop; 126 ct2_entry_t *ct2iop; 127 ct2e_entry_t *ct2eiop; 128 ct7_entry_t *ct7iop; 129 lun_entry_t *lunenp; 130 in_entry_t *inotp; 131 in_fcentry_t *inot_fcp; 132 in_fcentry_e_t *inote_fcp; 133 in_fcentry_24xx_t *inot_24xx; 134 na_entry_t *nackp; 135 na_fcentry_t *nack_fcp; 136 na_fcentry_e_t *nacke_fcp; 137 na_fcentry_24xx_t *nack_24xx; 138 isphdr_t *hp; 139 abts_t *abts; 140 abts_rsp_t *abts_rsp; 141 els_t *els; 142 void * *vp; 143#define atiop unp.atiop 144#define at2iop unp.at2iop 145#define at2eiop unp.at2eiop 146#define at7iop unp.at7iop 147#define ctiop unp.ctiop 148#define ct2iop unp.ct2iop 149#define ct2eiop unp.ct2eiop 150#define ct7iop unp.ct7iop 151#define lunenp unp.lunenp 152#define inotp unp.inotp 153#define inot_fcp unp.inot_fcp 154#define inote_fcp unp.inote_fcp 155#define inot_24xx unp.inot_24xx 156#define nackp unp.nackp 157#define nack_fcp unp.nack_fcp 158#define nacke_fcp unp.nacke_fcp 159#define nack_24xx unp.nack_24xx 160#define abts unp.abts 161#define abts_rsp unp.abts_rsp 162#define els unp.els 163#define hdrp unp.hp 164 } unp; 165 uint8_t local[QENTRY_LEN]; 166 uint16_t iid; 167 int bus, type, level, rval = 1; 168 isp_notify_t notify; 169 170 type = isp_get_response_type(isp, (isphdr_t *)vptr); 171 unp.vp = vptr; 172 173 ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr); 174 175 switch (type) { 176 case RQSTYPE_ATIO: 177 if (IS_24XX(isp)) { 178 int len; 179 180 isp_get_atio7(isp, at7iop, (at7_entry_t *) local); 181 at7iop = (at7_entry_t *) local; 182 /* 183 * Check for and do something with commands whose 184 * IULEN extends past a single queue entry. 185 */ 186 len = at7iop->at_ta_len & 0xfffff; 187 if (len > (QENTRY_LEN - 8)) { 188 len -= (QENTRY_LEN - 8); 189 isp_prt(isp, ISP_LOGINFO, "long IU length (%d) ignored", len); 190 while (len > 0) { 191 *optrp = ISP_NXT_QENTRY(*optrp, RESULT_QUEUE_LEN(isp)); 192 len -= QENTRY_LEN; 193 } 194 } 195 /* 196 * Check for a task management function 197 */ 198 if (at7iop->at_cmnd.fcp_cmnd_task_management) { 199 isp_got_tmf_24xx(isp, at7iop); 200 break; 201 } 202 /* 203 * Just go straight to outer layer for this one. 204 */ 205 isp_async(isp, ISPASYNC_TARGET_ACTION, local); 206 } else { 207 isp_get_atio(isp, atiop, (at_entry_t *) local); 208 isp_handle_atio(isp, (at_entry_t *) local); 209 } 210 break; 211 212 case RQSTYPE_CTIO: 213 isp_get_ctio(isp, ctiop, (ct_entry_t *) local); 214 isp_handle_ctio(isp, (ct_entry_t *) local); 215 break; 216 217 case RQSTYPE_ATIO2: 218 if (ISP_CAP_2KLOGIN(isp)) { 219 isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local); 220 } else { 221 isp_get_atio2(isp, at2iop, (at2_entry_t *) local); 222 } 223 isp_handle_atio2(isp, (at2_entry_t *) local); 224 break; 225 226 case RQSTYPE_CTIO3: 227 case RQSTYPE_CTIO2: 228 if (ISP_CAP_2KLOGIN(isp)) { 229 isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local); 230 } else { 231 isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local); 232 } 233 isp_handle_ctio2(isp, (ct2_entry_t *) local); 234 break; 235 236 case RQSTYPE_CTIO7: 237 isp_get_ctio7(isp, ct7iop, (ct7_entry_t *) local); 238 isp_handle_ctio7(isp, (ct7_entry_t *) local); 239 break; 240 241 case RQSTYPE_ENABLE_LUN: 242 case RQSTYPE_MODIFY_LUN: 243 isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local); 244 isp_async(isp, ISPASYNC_TARGET_ACTION, local); 245 break; 246 247 case RQSTYPE_NOTIFY: 248 bus = 0; 249 if (IS_24XX(isp)) { 250 isp_get_notify_24xx(isp, inot_24xx, (in_fcentry_24xx_t *)local); 251 inot_24xx = (in_fcentry_24xx_t *) local; 252 isp_handle_24xx_inotify(isp, inot_24xx); 253 break; 254 } 255 if (IS_FC(isp)) { 256 if (ISP_CAP_2KLOGIN(isp)) { 257 in_fcentry_e_t *ecp = (in_fcentry_e_t *)local; 258 isp_get_notify_fc_e(isp, inote_fcp, ecp); 259 iid = ecp->in_iid; 260 status = ecp->in_status; 261 seqid = ecp->in_seqid; 262 } else { 263 in_fcentry_t *fcp = (in_fcentry_t *)local; 264 isp_get_notify_fc(isp, inot_fcp, fcp); 265 iid = fcp->in_iid; 266 status = fcp->in_status; 267 seqid = fcp->in_seqid; 268 } 269 } else { 270 in_entry_t *inp = (in_entry_t *)local; 271 isp_get_notify(isp, inotp, inp); 272 status = inp->in_status & 0xff; 273 seqid = inp->in_seqid; 274 iid = inp->in_iid; 275 if (IS_DUALBUS(isp)) { 276 bus = GET_BUS_VAL(inp->in_iid); 277 SET_BUS_VAL(inp->in_iid, 0); 278 } 279 } 280 281 isp_prt(isp, ISP_LOGTDEBUG0, "Immediate Notify On Bus %d, status=0x%x seqid=0x%x", bus, status, seqid); 282 283 switch (status) { 284 case IN_MSG_RECEIVED: 285 case IN_IDE_RECEIVED: 286 if (IS_FC(isp)) { 287 isp_got_msg_fc(isp, (in_fcentry_t *)local); 288 } else { 289 isp_got_msg(isp, (in_entry_t *)local); 290 } 291 break; 292 case IN_RSRC_UNAVAIL: 293 isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs");
| 45#include <dev/isp/isp_freebsd.h> 46#endif 47#ifdef __OpenBSD__ 48#include <dev/ic/isp_openbsd.h> 49#endif 50#ifdef __linux__ 51#include "isp_linux.h" 52#endif 53 54#ifdef ISP_TARGET_MODE 55static const char atiocope[] = "ATIO returned for lun %d because it was in the middle of Bus Device Reset on bus %d"; 56static const char atior[] = "ATIO returned on for lun %d on from loopid %d because a Bus Reset occurred on bus %d"; 57static const char rqo[] = "%s: Request Queue Overflow"; 58 59static void isp_got_msg(ispsoftc_t *, in_entry_t *); 60static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *); 61static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *); 62static void isp_handle_atio(ispsoftc_t *, at_entry_t *); 63static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *); 64static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *); 65static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *); 66static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *); 67static void isp_handle_24xx_inotify(ispsoftc_t *, in_fcentry_24xx_t *); 68 69/* 70 * The Qlogic driver gets an interrupt to look at response queue entries. 71 * Some of these are status completions for initiatior mode commands, but 72 * if target mode is enabled, we get a whole wad of response queue entries 73 * to be handled here. 74 * 75 * Basically the split into 3 main groups: Lun Enable/Modification responses, 76 * SCSI Command processing, and Immediate Notification events. 77 * 78 * You start by writing a request queue entry to enable target mode (and 79 * establish some resource limitations which you can modify later). 80 * The f/w responds with a LUN ENABLE or LUN MODIFY response with 81 * the status of this action. If the enable was successful, you can expect... 82 * 83 * Response queue entries with SCSI commands encapsulate show up in an ATIO 84 * (Accept Target IO) type- sometimes with enough info to stop the command at 85 * this level. Ultimately the driver has to feed back to the f/w's request 86 * queue a sequence of CTIOs (continue target I/O) that describe data to 87 * be moved and/or status to be sent) and finally finishing with sending 88 * to the f/w's response queue an ATIO which then completes the handshake 89 * with the f/w for that command. There's a lot of variations on this theme, 90 * including flags you can set in the CTIO for the Qlogic 2X00 fibre channel 91 * cards that 'auto-replenish' the f/w's ATIO count, but this is the basic 92 * gist of it. 93 * 94 * The third group that can show up in the response queue are Immediate 95 * Notification events. These include things like notifications of SCSI bus 96 * resets, or Bus Device Reset messages or other messages received. This 97 * a classic oddbins area. It can get a little weird because you then turn 98 * around and acknowledge the Immediate Notify by writing an entry onto the 99 * request queue and then the f/w turns around and gives you an acknowledgement 100 * to *your* acknowledgement on the response queue (the idea being to let 101 * the f/w tell you when the event is *really* over I guess). 102 * 103 */ 104 105 106/* 107 * A new response queue entry has arrived. The interrupt service code 108 * has already swizzled it into the platform dependent from canonical form. 109 * 110 * Because of the way this driver is designed, unfortunately most of the 111 * actual synchronization work has to be done in the platform specific 112 * code- we have no synchroniation primitives in the common code. 113 */ 114 115int 116isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) 117{ 118 uint16_t status; 119 uint32_t seqid; 120 union { 121 at_entry_t *atiop; 122 at2_entry_t *at2iop; 123 at2e_entry_t *at2eiop; 124 at7_entry_t *at7iop; 125 ct_entry_t *ctiop; 126 ct2_entry_t *ct2iop; 127 ct2e_entry_t *ct2eiop; 128 ct7_entry_t *ct7iop; 129 lun_entry_t *lunenp; 130 in_entry_t *inotp; 131 in_fcentry_t *inot_fcp; 132 in_fcentry_e_t *inote_fcp; 133 in_fcentry_24xx_t *inot_24xx; 134 na_entry_t *nackp; 135 na_fcentry_t *nack_fcp; 136 na_fcentry_e_t *nacke_fcp; 137 na_fcentry_24xx_t *nack_24xx; 138 isphdr_t *hp; 139 abts_t *abts; 140 abts_rsp_t *abts_rsp; 141 els_t *els; 142 void * *vp; 143#define atiop unp.atiop 144#define at2iop unp.at2iop 145#define at2eiop unp.at2eiop 146#define at7iop unp.at7iop 147#define ctiop unp.ctiop 148#define ct2iop unp.ct2iop 149#define ct2eiop unp.ct2eiop 150#define ct7iop unp.ct7iop 151#define lunenp unp.lunenp 152#define inotp unp.inotp 153#define inot_fcp unp.inot_fcp 154#define inote_fcp unp.inote_fcp 155#define inot_24xx unp.inot_24xx 156#define nackp unp.nackp 157#define nack_fcp unp.nack_fcp 158#define nacke_fcp unp.nacke_fcp 159#define nack_24xx unp.nack_24xx 160#define abts unp.abts 161#define abts_rsp unp.abts_rsp 162#define els unp.els 163#define hdrp unp.hp 164 } unp; 165 uint8_t local[QENTRY_LEN]; 166 uint16_t iid; 167 int bus, type, level, rval = 1; 168 isp_notify_t notify; 169 170 type = isp_get_response_type(isp, (isphdr_t *)vptr); 171 unp.vp = vptr; 172 173 ISP_TDQE(isp, "isp_target_notify", (int) *optrp, vptr); 174 175 switch (type) { 176 case RQSTYPE_ATIO: 177 if (IS_24XX(isp)) { 178 int len; 179 180 isp_get_atio7(isp, at7iop, (at7_entry_t *) local); 181 at7iop = (at7_entry_t *) local; 182 /* 183 * Check for and do something with commands whose 184 * IULEN extends past a single queue entry. 185 */ 186 len = at7iop->at_ta_len & 0xfffff; 187 if (len > (QENTRY_LEN - 8)) { 188 len -= (QENTRY_LEN - 8); 189 isp_prt(isp, ISP_LOGINFO, "long IU length (%d) ignored", len); 190 while (len > 0) { 191 *optrp = ISP_NXT_QENTRY(*optrp, RESULT_QUEUE_LEN(isp)); 192 len -= QENTRY_LEN; 193 } 194 } 195 /* 196 * Check for a task management function 197 */ 198 if (at7iop->at_cmnd.fcp_cmnd_task_management) { 199 isp_got_tmf_24xx(isp, at7iop); 200 break; 201 } 202 /* 203 * Just go straight to outer layer for this one. 204 */ 205 isp_async(isp, ISPASYNC_TARGET_ACTION, local); 206 } else { 207 isp_get_atio(isp, atiop, (at_entry_t *) local); 208 isp_handle_atio(isp, (at_entry_t *) local); 209 } 210 break; 211 212 case RQSTYPE_CTIO: 213 isp_get_ctio(isp, ctiop, (ct_entry_t *) local); 214 isp_handle_ctio(isp, (ct_entry_t *) local); 215 break; 216 217 case RQSTYPE_ATIO2: 218 if (ISP_CAP_2KLOGIN(isp)) { 219 isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local); 220 } else { 221 isp_get_atio2(isp, at2iop, (at2_entry_t *) local); 222 } 223 isp_handle_atio2(isp, (at2_entry_t *) local); 224 break; 225 226 case RQSTYPE_CTIO3: 227 case RQSTYPE_CTIO2: 228 if (ISP_CAP_2KLOGIN(isp)) { 229 isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local); 230 } else { 231 isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local); 232 } 233 isp_handle_ctio2(isp, (ct2_entry_t *) local); 234 break; 235 236 case RQSTYPE_CTIO7: 237 isp_get_ctio7(isp, ct7iop, (ct7_entry_t *) local); 238 isp_handle_ctio7(isp, (ct7_entry_t *) local); 239 break; 240 241 case RQSTYPE_ENABLE_LUN: 242 case RQSTYPE_MODIFY_LUN: 243 isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local); 244 isp_async(isp, ISPASYNC_TARGET_ACTION, local); 245 break; 246 247 case RQSTYPE_NOTIFY: 248 bus = 0; 249 if (IS_24XX(isp)) { 250 isp_get_notify_24xx(isp, inot_24xx, (in_fcentry_24xx_t *)local); 251 inot_24xx = (in_fcentry_24xx_t *) local; 252 isp_handle_24xx_inotify(isp, inot_24xx); 253 break; 254 } 255 if (IS_FC(isp)) { 256 if (ISP_CAP_2KLOGIN(isp)) { 257 in_fcentry_e_t *ecp = (in_fcentry_e_t *)local; 258 isp_get_notify_fc_e(isp, inote_fcp, ecp); 259 iid = ecp->in_iid; 260 status = ecp->in_status; 261 seqid = ecp->in_seqid; 262 } else { 263 in_fcentry_t *fcp = (in_fcentry_t *)local; 264 isp_get_notify_fc(isp, inot_fcp, fcp); 265 iid = fcp->in_iid; 266 status = fcp->in_status; 267 seqid = fcp->in_seqid; 268 } 269 } else { 270 in_entry_t *inp = (in_entry_t *)local; 271 isp_get_notify(isp, inotp, inp); 272 status = inp->in_status & 0xff; 273 seqid = inp->in_seqid; 274 iid = inp->in_iid; 275 if (IS_DUALBUS(isp)) { 276 bus = GET_BUS_VAL(inp->in_iid); 277 SET_BUS_VAL(inp->in_iid, 0); 278 } 279 } 280 281 isp_prt(isp, ISP_LOGTDEBUG0, "Immediate Notify On Bus %d, status=0x%x seqid=0x%x", bus, status, seqid); 282 283 switch (status) { 284 case IN_MSG_RECEIVED: 285 case IN_IDE_RECEIVED: 286 if (IS_FC(isp)) { 287 isp_got_msg_fc(isp, (in_fcentry_t *)local); 288 } else { 289 isp_got_msg(isp, (in_entry_t *)local); 290 } 291 break; 292 case IN_RSRC_UNAVAIL: 293 isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs");
|
294 (void) isp_notify_ack(isp, local);
| 294 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, local);
|
295 break; 296 297 case IN_RESET: 298 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 299 notify.nt_hba = isp; 300 notify.nt_wwn = INI_ANY; 301 notify.nt_tgt = TGT_ANY; 302 notify.nt_nphdl = iid; 303 notify.nt_sid = PORT_ANY; 304 notify.nt_did = PORT_ANY; 305 notify.nt_lun = LUN_ANY; 306 notify.nt_tagval = TAG_ANY; 307 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 308 notify.nt_ncode = NT_BUS_RESET; 309 notify.nt_need_ack = 1; 310 notify.nt_lreserved = local; 311 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 312 break; 313 314 case IN_PORT_LOGOUT: 315 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 316 notify.nt_hba = isp; 317 notify.nt_wwn = INI_ANY; 318 notify.nt_nphdl = iid; 319 notify.nt_sid = PORT_ANY; 320 notify.nt_did = PORT_ANY; 321 notify.nt_ncode = NT_LOGOUT; 322 notify.nt_need_ack = 1; 323 notify.nt_lreserved = local; 324 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 325 break; 326 327 case IN_ABORT_TASK: 328 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 329 notify.nt_hba = isp; 330 notify.nt_wwn = INI_ANY; 331 notify.nt_nphdl = iid; 332 notify.nt_sid = PORT_ANY; 333 notify.nt_did = PORT_ANY; 334 notify.nt_ncode = NT_ABORT_TASK; 335 notify.nt_need_ack = 1; 336 notify.nt_lreserved = local; 337 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 338 break; 339 340 case IN_GLOBAL_LOGO: 341 isp_prt(isp, ISP_LOGTINFO, "%s: all ports logged out", __func__); 342 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 343 notify.nt_hba = isp; 344 notify.nt_wwn = INI_ANY; 345 notify.nt_nphdl = NIL_HANDLE; 346 notify.nt_sid = PORT_ANY; 347 notify.nt_did = PORT_ANY; 348 notify.nt_ncode = NT_GLOBAL_LOGOUT;
| 295 break; 296 297 case IN_RESET: 298 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 299 notify.nt_hba = isp; 300 notify.nt_wwn = INI_ANY; 301 notify.nt_tgt = TGT_ANY; 302 notify.nt_nphdl = iid; 303 notify.nt_sid = PORT_ANY; 304 notify.nt_did = PORT_ANY; 305 notify.nt_lun = LUN_ANY; 306 notify.nt_tagval = TAG_ANY; 307 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 308 notify.nt_ncode = NT_BUS_RESET; 309 notify.nt_need_ack = 1; 310 notify.nt_lreserved = local; 311 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 312 break; 313 314 case IN_PORT_LOGOUT: 315 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 316 notify.nt_hba = isp; 317 notify.nt_wwn = INI_ANY; 318 notify.nt_nphdl = iid; 319 notify.nt_sid = PORT_ANY; 320 notify.nt_did = PORT_ANY; 321 notify.nt_ncode = NT_LOGOUT; 322 notify.nt_need_ack = 1; 323 notify.nt_lreserved = local; 324 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 325 break; 326 327 case IN_ABORT_TASK: 328 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 329 notify.nt_hba = isp; 330 notify.nt_wwn = INI_ANY; 331 notify.nt_nphdl = iid; 332 notify.nt_sid = PORT_ANY; 333 notify.nt_did = PORT_ANY; 334 notify.nt_ncode = NT_ABORT_TASK; 335 notify.nt_need_ack = 1; 336 notify.nt_lreserved = local; 337 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 338 break; 339 340 case IN_GLOBAL_LOGO: 341 isp_prt(isp, ISP_LOGTINFO, "%s: all ports logged out", __func__); 342 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 343 notify.nt_hba = isp; 344 notify.nt_wwn = INI_ANY; 345 notify.nt_nphdl = NIL_HANDLE; 346 notify.nt_sid = PORT_ANY; 347 notify.nt_did = PORT_ANY; 348 notify.nt_ncode = NT_GLOBAL_LOGOUT;
|
| 349 notify.nt_need_ack = 1; 350 notify.nt_lreserved = local;
|
349 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
| 351 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
350 (void) isp_notify_ack(isp, local);
| |
351 break; 352 353 case IN_PORT_CHANGED: 354 isp_prt(isp, ISP_LOGTINFO, "%s: port changed", __func__);
| 352 break; 353 354 case IN_PORT_CHANGED: 355 isp_prt(isp, ISP_LOGTINFO, "%s: port changed", __func__);
|
355 (void) isp_notify_ack(isp, local);
| 356 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 357 notify.nt_hba = isp; 358 notify.nt_wwn = INI_ANY; 359 notify.nt_nphdl = NIL_HANDLE; 360 notify.nt_sid = PORT_ANY; 361 notify.nt_did = PORT_ANY; 362 notify.nt_ncode = NT_CHANGED; 363 notify.nt_need_ack = 1; 364 notify.nt_lreserved = local; 365 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
356 break; 357 358 default: 359 ISP_SNPRINTF(local, sizeof local, "%s: unknown status to RQSTYPE_NOTIFY (0x%x)", __func__, status); 360 isp_print_bytes(isp, local, QENTRY_LEN, vptr);
| 366 break; 367 368 default: 369 ISP_SNPRINTF(local, sizeof local, "%s: unknown status to RQSTYPE_NOTIFY (0x%x)", __func__, status); 370 isp_print_bytes(isp, local, QENTRY_LEN, vptr);
|
361 (void) isp_notify_ack(isp, local);
| 371 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, local);
|
362 break; 363 } 364 break; 365 366 case RQSTYPE_NOTIFY_ACK: 367 /* 368 * The ISP is acknowledging our acknowledgement of an 369 * Immediate Notify entry for some asynchronous event. 370 */ 371 if (IS_24XX(isp)) { 372 isp_get_notify_ack_24xx(isp, nack_24xx, (na_fcentry_24xx_t *) local); 373 nack_24xx = (na_fcentry_24xx_t *) local; 374 if (nack_24xx->na_status != NA_OK) { 375 level = ISP_LOGINFO; 376 } else { 377 level = ISP_LOGTDEBUG1; 378 } 379 isp_prt(isp, level, "Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x", nack_24xx->na_status, nack_24xx->na_status_subcode, nack_24xx->na_rxid); 380 } else if (IS_FC(isp)) { 381 if (ISP_CAP_2KLOGIN(isp)) { 382 isp_get_notify_ack_fc_e(isp, nacke_fcp, (na_fcentry_e_t *)local); 383 } else { 384 isp_get_notify_ack_fc(isp, nack_fcp, (na_fcentry_t *)local); 385 } 386 nack_fcp = (na_fcentry_t *)local; 387 if (nack_fcp->na_status != NA_OK) { 388 level = ISP_LOGINFO; 389 } else { 390 level = ISP_LOGTDEBUG1; 391 } 392 isp_prt(isp, level, "Notify Ack Status=0x%x seqid 0x%x", nack_fcp->na_status, nack_fcp->na_seqid); 393 } else { 394 isp_get_notify_ack(isp, nackp, (na_entry_t *)local); 395 nackp = (na_entry_t *)local; 396 if (nackp->na_status != NA_OK) { 397 level = ISP_LOGINFO; 398 } else { 399 level = ISP_LOGTDEBUG1; 400 } 401 isp_prt(isp, level, "Notify Ack event 0x%x status=0x%x seqid 0x%x", nackp->na_event, nackp->na_status, nackp->na_seqid); 402 } 403 break; 404 405 case RQSTYPE_ABTS_RCVD: 406 isp_get_abts(isp, abts, (abts_t *)local); 407 isp_async(isp, ISPASYNC_TARGET_ACTION, &local); 408 break; 409 case RQSTYPE_ABTS_RSP: 410 isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local); 411 abts_rsp = (abts_rsp_t *) local; 412 if (abts_rsp->abts_rsp_status) { 413 level = ISP_LOGINFO; 414 } else { 415 level = ISP_LOGTDEBUG0; 416 } 417 isp_prt(isp, level, "ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)", abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status, 418 abts_rsp->abts_rsp_payload.rsp.subcode1, abts_rsp->abts_rsp_payload.rsp.subcode2); 419 break; 420 default: 421 isp_prt(isp, ISP_LOGERR, "%s: unknown entry type 0x%x", __func__, type); 422 rval = 0; 423 break; 424 } 425#undef atiop 426#undef at2iop 427#undef at2eiop 428#undef at7iop 429#undef ctiop 430#undef ct2iop 431#undef ct2eiop 432#undef ct7iop 433#undef lunenp 434#undef inotp 435#undef inot_fcp 436#undef inote_fcp 437#undef inot_24xx 438#undef nackp 439#undef nack_fcp 440#undef nacke_fcp 441#undef hack_24xx 442#undef abts 443#undef abts_rsp 444#undef els 445#undef hdrp 446 return (rval); 447} 448 449 450/* 451 * Toggle (on/off) target mode for bus/target/lun. 452 * 453 * The caller has checked for overlap and legality. 454 * 455 * Note that not all of bus, target or lun can be paid attention to. 456 * Note also that this action will not be complete until the f/w writes 457 * a response entry. The caller is responsible for synchronizing with this. 458 */ 459int 460isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int lun, int cmd_cnt, int inot_cnt) 461{ 462 lun_entry_t el; 463 void *outp; 464 465 ISP_MEMZERO(&el, sizeof (el)); 466 if (IS_DUALBUS(isp)) { 467 el.le_rsvd = (bus & 0x1) << 7; 468 }
| 372 break; 373 } 374 break; 375 376 case RQSTYPE_NOTIFY_ACK: 377 /* 378 * The ISP is acknowledging our acknowledgement of an 379 * Immediate Notify entry for some asynchronous event. 380 */ 381 if (IS_24XX(isp)) { 382 isp_get_notify_ack_24xx(isp, nack_24xx, (na_fcentry_24xx_t *) local); 383 nack_24xx = (na_fcentry_24xx_t *) local; 384 if (nack_24xx->na_status != NA_OK) { 385 level = ISP_LOGINFO; 386 } else { 387 level = ISP_LOGTDEBUG1; 388 } 389 isp_prt(isp, level, "Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x", nack_24xx->na_status, nack_24xx->na_status_subcode, nack_24xx->na_rxid); 390 } else if (IS_FC(isp)) { 391 if (ISP_CAP_2KLOGIN(isp)) { 392 isp_get_notify_ack_fc_e(isp, nacke_fcp, (na_fcentry_e_t *)local); 393 } else { 394 isp_get_notify_ack_fc(isp, nack_fcp, (na_fcentry_t *)local); 395 } 396 nack_fcp = (na_fcentry_t *)local; 397 if (nack_fcp->na_status != NA_OK) { 398 level = ISP_LOGINFO; 399 } else { 400 level = ISP_LOGTDEBUG1; 401 } 402 isp_prt(isp, level, "Notify Ack Status=0x%x seqid 0x%x", nack_fcp->na_status, nack_fcp->na_seqid); 403 } else { 404 isp_get_notify_ack(isp, nackp, (na_entry_t *)local); 405 nackp = (na_entry_t *)local; 406 if (nackp->na_status != NA_OK) { 407 level = ISP_LOGINFO; 408 } else { 409 level = ISP_LOGTDEBUG1; 410 } 411 isp_prt(isp, level, "Notify Ack event 0x%x status=0x%x seqid 0x%x", nackp->na_event, nackp->na_status, nackp->na_seqid); 412 } 413 break; 414 415 case RQSTYPE_ABTS_RCVD: 416 isp_get_abts(isp, abts, (abts_t *)local); 417 isp_async(isp, ISPASYNC_TARGET_ACTION, &local); 418 break; 419 case RQSTYPE_ABTS_RSP: 420 isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local); 421 abts_rsp = (abts_rsp_t *) local; 422 if (abts_rsp->abts_rsp_status) { 423 level = ISP_LOGINFO; 424 } else { 425 level = ISP_LOGTDEBUG0; 426 } 427 isp_prt(isp, level, "ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)", abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status, 428 abts_rsp->abts_rsp_payload.rsp.subcode1, abts_rsp->abts_rsp_payload.rsp.subcode2); 429 break; 430 default: 431 isp_prt(isp, ISP_LOGERR, "%s: unknown entry type 0x%x", __func__, type); 432 rval = 0; 433 break; 434 } 435#undef atiop 436#undef at2iop 437#undef at2eiop 438#undef at7iop 439#undef ctiop 440#undef ct2iop 441#undef ct2eiop 442#undef ct7iop 443#undef lunenp 444#undef inotp 445#undef inot_fcp 446#undef inote_fcp 447#undef inot_24xx 448#undef nackp 449#undef nack_fcp 450#undef nacke_fcp 451#undef hack_24xx 452#undef abts 453#undef abts_rsp 454#undef els 455#undef hdrp 456 return (rval); 457} 458 459 460/* 461 * Toggle (on/off) target mode for bus/target/lun. 462 * 463 * The caller has checked for overlap and legality. 464 * 465 * Note that not all of bus, target or lun can be paid attention to. 466 * Note also that this action will not be complete until the f/w writes 467 * a response entry. The caller is responsible for synchronizing with this. 468 */ 469int 470isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int lun, int cmd_cnt, int inot_cnt) 471{ 472 lun_entry_t el; 473 void *outp; 474 475 ISP_MEMZERO(&el, sizeof (el)); 476 if (IS_DUALBUS(isp)) { 477 el.le_rsvd = (bus & 0x1) << 7; 478 }
|
469 el.le_cmd_count = cmd_cnt; 470 el.le_in_count = inot_cnt;
| 479 el.le_cmd_count = (cmd_cnt < 0)? -cmd_cnt : cmd_cnt; 480 el.le_in_count = (inot_cnt < 0)? -inot_cnt : inot_cnt;
|
471 if (cmd == RQSTYPE_ENABLE_LUN) { 472 if (IS_SCSI(isp)) { 473 el.le_flags = LUN_TQAE|LUN_DISAD; 474 el.le_cdb6len = 12; 475 el.le_cdb7len = 12; 476 }
| 481 if (cmd == RQSTYPE_ENABLE_LUN) { 482 if (IS_SCSI(isp)) { 483 el.le_flags = LUN_TQAE|LUN_DISAD; 484 el.le_cdb6len = 12; 485 el.le_cdb7len = 12; 486 }
|
477 } else if (cmd == -RQSTYPE_ENABLE_LUN) { 478 cmd = RQSTYPE_ENABLE_LUN; 479 el.le_cmd_count = 0; 480 el.le_in_count = 0; 481 } else if (cmd == -RQSTYPE_MODIFY_LUN) { 482 cmd = RQSTYPE_MODIFY_LUN; 483 el.le_ops = LUN_CCDECR | LUN_INDECR;
| 487 } else if (cmd == RQSTYPE_MODIFY_LUN) { 488 if (cmd_cnt == 0 && inot_cnt == 0) { 489 isp_prt(isp, ISP_LOGWARN, "makes no sense to modify a lun with both command and immediate notify counts as zero"); 490 return (0); 491 } 492 if (cmd_cnt < 0) 493 el.le_ops |= LUN_CCDECR; 494 else 495 el.le_ops |= LUN_CCINCR; 496 if (inot_cnt < 0) 497 el.le_ops |= LUN_INDECR; 498 else 499 el.le_ops |= LUN_ININCR;
|
484 } else {
| 500 } else {
|
485 el.le_ops = LUN_CCINCR | LUN_ININCR;
| 501 isp_prt(isp, ISP_LOGWARN, "unknown cmd (0x%x) in %s", cmd, __func__); 502 return (-1);
|
486 } 487 el.le_header.rqs_entry_type = cmd; 488 el.le_header.rqs_entry_count = 1; 489 if (IS_SCSI(isp)) { 490 el.le_tgt = SDPARAM(isp, bus)->isp_initiator_id; 491 el.le_lun = lun; 492 } else if (ISP_CAP_SCCFW(isp) == 0) { 493 el.le_lun = lun; 494 } 495 el.le_timeout = 30; 496 497 outp = isp_getrqentry(isp); 498 if (outp == NULL) { 499 isp_prt(isp, ISP_LOGERR, rqo, __func__); 500 return (-1); 501 } 502 isp_put_enable_lun(isp, &el, outp); 503 ISP_TDQE(isp, "isp_lun_cmd", isp->isp_reqidx, &el); 504 ISP_SYNC_REQUEST(isp); 505 return (0); 506} 507 508int 509isp_target_put_entry(ispsoftc_t *isp, void *ap) 510{ 511 void *outp; 512 uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type; 513 514 outp = isp_getrqentry(isp); 515 if (outp == NULL) { 516 isp_prt(isp, ISP_LOGWARN, rqo, __func__); 517 return (-1); 518 } 519 switch (etype) { 520 case RQSTYPE_ATIO: 521 isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp); 522 break; 523 case RQSTYPE_ATIO2: 524 if (ISP_CAP_2KLOGIN(isp)) { 525 isp_put_atio2e(isp, (at2e_entry_t *) ap, (at2e_entry_t *) outp); 526 } else { 527 isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp); 528 } 529 break; 530 case RQSTYPE_CTIO: 531 isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp); 532 break; 533 case RQSTYPE_CTIO2: 534 if (ISP_CAP_2KLOGIN(isp)) { 535 isp_put_ctio2e(isp, (ct2e_entry_t *) ap, (ct2e_entry_t *) outp); 536 } else { 537 isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp); 538 } 539 break; 540 case RQSTYPE_CTIO7: 541 isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp); 542 break; 543 default: 544 isp_prt(isp, ISP_LOGERR, "%s: Unknown type 0x%x", __func__, etype); 545 return (-1); 546 } 547 ISP_TDQE(isp, __func__, isp->isp_reqidx, ap); 548 ISP_SYNC_REQUEST(isp); 549 return (0); 550} 551 552int 553isp_target_put_atio(ispsoftc_t *isp, void *arg) 554{ 555 union { 556 at_entry_t _atio; 557 at2_entry_t _atio2; 558 at2e_entry_t _atio2e; 559 } atun; 560 561 ISP_MEMZERO(&atun, sizeof atun); 562 if (IS_FC(isp)) { 563 at2_entry_t *aep = arg; 564 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2; 565 atun._atio2.at_header.rqs_entry_count = 1; 566 if (ISP_CAP_SCCFW(isp)) { 567 atun._atio2.at_scclun = aep->at_scclun; 568 } else { 569 atun._atio2.at_lun = (uint8_t) aep->at_lun; 570 } 571 if (ISP_CAP_2KLOGIN(isp)) { 572 atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid; 573 } else { 574 atun._atio2.at_iid = aep->at_iid; 575 } 576 atun._atio2.at_rxid = aep->at_rxid; 577 atun._atio2.at_status = CT_OK; 578 } else { 579 at_entry_t *aep = arg; 580 atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO; 581 atun._atio.at_header.rqs_entry_count = 1; 582 atun._atio.at_handle = aep->at_handle; 583 atun._atio.at_iid = aep->at_iid; 584 atun._atio.at_tgt = aep->at_tgt; 585 atun._atio.at_lun = aep->at_lun; 586 atun._atio.at_tag_type = aep->at_tag_type; 587 atun._atio.at_tag_val = aep->at_tag_val; 588 atun._atio.at_status = (aep->at_flags & AT_TQAE); 589 atun._atio.at_status |= CT_OK; 590 } 591 return (isp_target_put_entry(isp, &atun)); 592} 593 594/* 595 * Command completion- both for handling cases of no resources or 596 * no blackhole driver, or other cases where we have to, inline, 597 * finish the command sanely, or for normal command completion. 598 * 599 * The 'completion' code value has the scsi status byte in the low 8 bits. 600 * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have 601 * the sense key and bits 16..23 have the ASCQ and bits 24..31 have the ASC 602 * values. 603 * 604 * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't 605 * NB: inline SCSI sense reporting. As such, we lose this information. XXX. 606 * 607 * For both parallel && fibre channel, we use the feature that does 608 * an automatic resource autoreplenish so we don't have then later do 609 * put of an atio to replenish the f/w's resource count. 610 */ 611 612int 613isp_endcmd(ispsoftc_t *isp, ...) 614{ 615 uint32_t code, hdl; 616 uint8_t sts; 617 union { 618 ct_entry_t _ctio; 619 ct2_entry_t _ctio2; 620 ct2e_entry_t _ctio2e; 621 ct7_entry_t _ctio7; 622 } un; 623 va_list ap; 624 625 ISP_MEMZERO(&un, sizeof un); 626 627 if (IS_24XX(isp)) { 628 int vpidx, nphdl; 629 at7_entry_t *aep; 630 ct7_entry_t *cto = &un._ctio7; 631 632 va_start(ap, isp); 633 aep = va_arg(ap, at7_entry_t *); 634 nphdl = va_arg(ap, int); 635 /* 636 * Note that vpidx may equal 0xff (unknown) here 637 */ 638 vpidx = va_arg(ap, int); 639 code = va_arg(ap, uint32_t); 640 hdl = va_arg(ap, uint32_t); 641 va_end(ap); 642 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] chan %d code %x", __func__, aep->at_rxid, vpidx, code); 643 644 sts = code & 0xff; 645 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 646 cto->ct_header.rqs_entry_count = 1; 647 cto->ct_nphdl = nphdl; 648 cto->ct_rxid = aep->at_rxid; 649 cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2]; 650 cto->ct_iid_hi = aep->at_hdr.s_id[0]; 651 cto->ct_oxid = aep->at_hdr.ox_id; 652 cto->ct_scsi_status = sts; 653 cto->ct_vpidx = vpidx; 654 cto->ct_flags = CT7_NOACK; 655 if (code & ECMD_TERMINATE) { 656 cto->ct_flags |= CT7_TERMINATE; 657 } else if (code & ECMD_SVALID) { 658 cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS; 659 cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8); 660 cto->rsp.m1.ct_resplen = cto->ct_senselen = min(16, MAXRESPLEN_24XX); 661 ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp)); 662 cto->rsp.m1.ct_resp[0] = 0xf0; 663 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf; 664 cto->rsp.m1.ct_resp[7] = 8;
| 503 } 504 el.le_header.rqs_entry_type = cmd; 505 el.le_header.rqs_entry_count = 1; 506 if (IS_SCSI(isp)) { 507 el.le_tgt = SDPARAM(isp, bus)->isp_initiator_id; 508 el.le_lun = lun; 509 } else if (ISP_CAP_SCCFW(isp) == 0) { 510 el.le_lun = lun; 511 } 512 el.le_timeout = 30; 513 514 outp = isp_getrqentry(isp); 515 if (outp == NULL) { 516 isp_prt(isp, ISP_LOGERR, rqo, __func__); 517 return (-1); 518 } 519 isp_put_enable_lun(isp, &el, outp); 520 ISP_TDQE(isp, "isp_lun_cmd", isp->isp_reqidx, &el); 521 ISP_SYNC_REQUEST(isp); 522 return (0); 523} 524 525int 526isp_target_put_entry(ispsoftc_t *isp, void *ap) 527{ 528 void *outp; 529 uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type; 530 531 outp = isp_getrqentry(isp); 532 if (outp == NULL) { 533 isp_prt(isp, ISP_LOGWARN, rqo, __func__); 534 return (-1); 535 } 536 switch (etype) { 537 case RQSTYPE_ATIO: 538 isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp); 539 break; 540 case RQSTYPE_ATIO2: 541 if (ISP_CAP_2KLOGIN(isp)) { 542 isp_put_atio2e(isp, (at2e_entry_t *) ap, (at2e_entry_t *) outp); 543 } else { 544 isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp); 545 } 546 break; 547 case RQSTYPE_CTIO: 548 isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp); 549 break; 550 case RQSTYPE_CTIO2: 551 if (ISP_CAP_2KLOGIN(isp)) { 552 isp_put_ctio2e(isp, (ct2e_entry_t *) ap, (ct2e_entry_t *) outp); 553 } else { 554 isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp); 555 } 556 break; 557 case RQSTYPE_CTIO7: 558 isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp); 559 break; 560 default: 561 isp_prt(isp, ISP_LOGERR, "%s: Unknown type 0x%x", __func__, etype); 562 return (-1); 563 } 564 ISP_TDQE(isp, __func__, isp->isp_reqidx, ap); 565 ISP_SYNC_REQUEST(isp); 566 return (0); 567} 568 569int 570isp_target_put_atio(ispsoftc_t *isp, void *arg) 571{ 572 union { 573 at_entry_t _atio; 574 at2_entry_t _atio2; 575 at2e_entry_t _atio2e; 576 } atun; 577 578 ISP_MEMZERO(&atun, sizeof atun); 579 if (IS_FC(isp)) { 580 at2_entry_t *aep = arg; 581 atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2; 582 atun._atio2.at_header.rqs_entry_count = 1; 583 if (ISP_CAP_SCCFW(isp)) { 584 atun._atio2.at_scclun = aep->at_scclun; 585 } else { 586 atun._atio2.at_lun = (uint8_t) aep->at_lun; 587 } 588 if (ISP_CAP_2KLOGIN(isp)) { 589 atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid; 590 } else { 591 atun._atio2.at_iid = aep->at_iid; 592 } 593 atun._atio2.at_rxid = aep->at_rxid; 594 atun._atio2.at_status = CT_OK; 595 } else { 596 at_entry_t *aep = arg; 597 atun._atio.at_header.rqs_entry_type = RQSTYPE_ATIO; 598 atun._atio.at_header.rqs_entry_count = 1; 599 atun._atio.at_handle = aep->at_handle; 600 atun._atio.at_iid = aep->at_iid; 601 atun._atio.at_tgt = aep->at_tgt; 602 atun._atio.at_lun = aep->at_lun; 603 atun._atio.at_tag_type = aep->at_tag_type; 604 atun._atio.at_tag_val = aep->at_tag_val; 605 atun._atio.at_status = (aep->at_flags & AT_TQAE); 606 atun._atio.at_status |= CT_OK; 607 } 608 return (isp_target_put_entry(isp, &atun)); 609} 610 611/* 612 * Command completion- both for handling cases of no resources or 613 * no blackhole driver, or other cases where we have to, inline, 614 * finish the command sanely, or for normal command completion. 615 * 616 * The 'completion' code value has the scsi status byte in the low 8 bits. 617 * If status is a CHECK CONDITION and bit 8 is nonzero, then bits 12..15 have 618 * the sense key and bits 16..23 have the ASCQ and bits 24..31 have the ASC 619 * values. 620 * 621 * NB: the key, asc, ascq, cannot be used for parallel SCSI as it doesn't 622 * NB: inline SCSI sense reporting. As such, we lose this information. XXX. 623 * 624 * For both parallel && fibre channel, we use the feature that does 625 * an automatic resource autoreplenish so we don't have then later do 626 * put of an atio to replenish the f/w's resource count. 627 */ 628 629int 630isp_endcmd(ispsoftc_t *isp, ...) 631{ 632 uint32_t code, hdl; 633 uint8_t sts; 634 union { 635 ct_entry_t _ctio; 636 ct2_entry_t _ctio2; 637 ct2e_entry_t _ctio2e; 638 ct7_entry_t _ctio7; 639 } un; 640 va_list ap; 641 642 ISP_MEMZERO(&un, sizeof un); 643 644 if (IS_24XX(isp)) { 645 int vpidx, nphdl; 646 at7_entry_t *aep; 647 ct7_entry_t *cto = &un._ctio7; 648 649 va_start(ap, isp); 650 aep = va_arg(ap, at7_entry_t *); 651 nphdl = va_arg(ap, int); 652 /* 653 * Note that vpidx may equal 0xff (unknown) here 654 */ 655 vpidx = va_arg(ap, int); 656 code = va_arg(ap, uint32_t); 657 hdl = va_arg(ap, uint32_t); 658 va_end(ap); 659 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] chan %d code %x", __func__, aep->at_rxid, vpidx, code); 660 661 sts = code & 0xff; 662 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 663 cto->ct_header.rqs_entry_count = 1; 664 cto->ct_nphdl = nphdl; 665 cto->ct_rxid = aep->at_rxid; 666 cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2]; 667 cto->ct_iid_hi = aep->at_hdr.s_id[0]; 668 cto->ct_oxid = aep->at_hdr.ox_id; 669 cto->ct_scsi_status = sts; 670 cto->ct_vpidx = vpidx; 671 cto->ct_flags = CT7_NOACK; 672 if (code & ECMD_TERMINATE) { 673 cto->ct_flags |= CT7_TERMINATE; 674 } else if (code & ECMD_SVALID) { 675 cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS; 676 cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8); 677 cto->rsp.m1.ct_resplen = cto->ct_senselen = min(16, MAXRESPLEN_24XX); 678 ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp)); 679 cto->rsp.m1.ct_resp[0] = 0xf0; 680 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf; 681 cto->rsp.m1.ct_resp[7] = 8;
|
665 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff; 666 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
| 682 cto->rsp.m1.ct_resp[12] = (code >> 16) & 0xff; 683 cto->rsp.m1.ct_resp[13] = (code >> 24) & 0xff;
|
667 } else { 668 cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS; 669 } 670 if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) { 671 cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl; 672 if (cto->ct_resid < 0) { 673 cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8); 674 } else if (cto->ct_resid > 0) { 675 cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8); 676 } 677 } 678 cto->ct_syshandle = hdl; 679 } else if (IS_FC(isp)) { 680 at2_entry_t *aep; 681 ct2_entry_t *cto = &un._ctio2; 682 683 va_start(ap, isp); 684 aep = va_arg(ap, at2_entry_t *); 685 code = va_arg(ap, uint32_t); 686 hdl = va_arg(ap, uint32_t); 687 va_end(ap); 688 689 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] code %x", __func__, aep->at_rxid, code); 690 691 sts = code & 0xff; 692 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 693 cto->ct_header.rqs_entry_count = 1; 694 if (ISP_CAP_SCCFW(isp) == 0) { 695 cto->ct_lun = aep->at_lun; 696 } 697 if (ISP_CAP_2KLOGIN(isp)) { 698 un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid; 699 } else { 700 cto->ct_iid = aep->at_iid; 701 } 702 cto->ct_rxid = aep->at_rxid; 703 cto->rsp.m1.ct_scsi_status = sts; 704 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1; 705 if (hdl == 0) { 706 cto->ct_flags |= CT2_CCINCR; 707 } 708 if (aep->at_datalen) { 709 cto->ct_resid = aep->at_datalen; 710 cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER; 711 } 712 if (sts == SCSI_CHECK && (code & ECMD_SVALID)) { 713 cto->rsp.m1.ct_resp[0] = 0xf0; 714 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf; 715 cto->rsp.m1.ct_resp[7] = 8; 716 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff; 717 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff; 718 cto->rsp.m1.ct_senselen = 16; 719 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID; 720 } 721 cto->ct_syshandle = hdl; 722 } else { 723 at_entry_t *aep; 724 ct_entry_t *cto = &un._ctio; 725 726 va_start(ap, isp); 727 aep = va_arg(ap, at_entry_t *); 728 code = va_arg(ap, uint32_t); 729 hdl = va_arg(ap, uint32_t); 730 va_end(ap); 731 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [IID %d] code %x", __func__, aep->at_iid, code); 732 sts = code; 733 734 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO; 735 cto->ct_header.rqs_entry_count = 1; 736 cto->ct_fwhandle = aep->at_handle; 737 cto->ct_iid = aep->at_iid; 738 cto->ct_tgt = aep->at_tgt; 739 cto->ct_lun = aep->at_lun; 740 cto->ct_tag_type = aep->at_tag_type; 741 cto->ct_tag_val = aep->at_tag_val; 742 if (aep->at_flags & AT_TQAE) { 743 cto->ct_flags |= CT_TQAE; 744 } 745 cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA; 746 if (hdl == 0) { 747 cto->ct_flags |= CT_CCINCR; 748 } 749 cto->ct_scsi_status = sts; 750 cto->ct_syshandle = hdl; 751 } 752 return (isp_target_put_entry(isp, &un)); 753} 754 755/* 756 * These are either broadcast events or specifically CTIO fast completion 757 */ 758 759int 760isp_target_async(ispsoftc_t *isp, int bus, int event) 761{ 762 isp_notify_t notify; 763 764 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 765 notify.nt_hba = isp; 766 notify.nt_wwn = INI_ANY; 767 notify.nt_nphdl = NIL_HANDLE; 768 notify.nt_sid = PORT_ANY; 769 notify.nt_did = PORT_ANY; 770 notify.nt_tgt = TGT_ANY; 771 notify.nt_channel = bus; 772 notify.nt_lun = LUN_ANY; 773 notify.nt_tagval = TAG_ANY; 774 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 775 776 switch (event) { 777 case ASYNC_LOOP_UP: 778 case ASYNC_PTPMODE: 779 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP UP", __func__); 780 notify.nt_ncode = NT_LINK_UP; 781 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 782 break; 783 case ASYNC_LOOP_DOWN: 784 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP DOWN", __func__); 785 notify.nt_ncode = NT_LINK_DOWN; 786 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 787 break; 788 case ASYNC_LIP_ERROR: 789 case ASYNC_LIP_F8: 790 case ASYNC_LIP_OCCURRED: 791 case ASYNC_LOOP_RESET: 792 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LIP RESET", __func__); 793 notify.nt_ncode = NT_LIP_RESET; 794 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 795 break; 796 case ASYNC_BUS_RESET: 797 case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */ 798 isp_prt(isp, ISP_LOGTDEBUG0, "%s: BUS RESET", __func__); 799 notify.nt_ncode = NT_BUS_RESET; 800 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 801 break; 802 case ASYNC_DEVICE_RESET: 803 isp_prt(isp, ISP_LOGTDEBUG0, "%s: DEVICE RESET", __func__); 804 notify.nt_ncode = NT_TARGET_RESET; 805 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 806 break; 807 case ASYNC_CTIO_DONE: 808 { 809 uint8_t storage[QENTRY_LEN]; 810 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO DONE", __func__); 811 memset(storage, 0, QENTRY_LEN); 812 if (IS_24XX(isp)) { 813 ct7_entry_t *ct = (ct7_entry_t *) storage; 814 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 815 ct->ct_nphdl = CT7_OK; 816 ct->ct_syshandle = bus; 817 ct->ct_flags = CT7_SENDSTATUS; 818 } else if (IS_FC(isp)) { 819 /* This should also suffice for 2K login code */ 820 ct2_entry_t *ct = (ct2_entry_t *) storage; 821 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 822 ct->ct_status = CT_OK; 823 ct->ct_syshandle = bus; 824 ct->ct_flags = CT2_SENDSTATUS|CT2_FASTPOST; 825 } else { 826 ct_entry_t *ct = (ct_entry_t *) storage; 827 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO; 828 ct->ct_status = CT_OK; 829 ct->ct_syshandle = bus; 830 /* we skip fwhandle here */ 831 ct->ct_fwhandle = 0; 832 ct->ct_flags = CT_SENDSTATUS; 833 } 834 isp_async(isp, ISPASYNC_TARGET_ACTION, storage); 835 break; 836 } 837 default: 838 isp_prt(isp, ISP_LOGERR, "%s: unknown event 0x%x", __func__, event); 839 if (isp->isp_state == ISP_RUNSTATE) {
| 684 } else { 685 cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS; 686 } 687 if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) { 688 cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl; 689 if (cto->ct_resid < 0) { 690 cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8); 691 } else if (cto->ct_resid > 0) { 692 cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8); 693 } 694 } 695 cto->ct_syshandle = hdl; 696 } else if (IS_FC(isp)) { 697 at2_entry_t *aep; 698 ct2_entry_t *cto = &un._ctio2; 699 700 va_start(ap, isp); 701 aep = va_arg(ap, at2_entry_t *); 702 code = va_arg(ap, uint32_t); 703 hdl = va_arg(ap, uint32_t); 704 va_end(ap); 705 706 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] code %x", __func__, aep->at_rxid, code); 707 708 sts = code & 0xff; 709 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 710 cto->ct_header.rqs_entry_count = 1; 711 if (ISP_CAP_SCCFW(isp) == 0) { 712 cto->ct_lun = aep->at_lun; 713 } 714 if (ISP_CAP_2KLOGIN(isp)) { 715 un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid; 716 } else { 717 cto->ct_iid = aep->at_iid; 718 } 719 cto->ct_rxid = aep->at_rxid; 720 cto->rsp.m1.ct_scsi_status = sts; 721 cto->ct_flags = CT2_SENDSTATUS | CT2_NO_DATA | CT2_FLAG_MODE1; 722 if (hdl == 0) { 723 cto->ct_flags |= CT2_CCINCR; 724 } 725 if (aep->at_datalen) { 726 cto->ct_resid = aep->at_datalen; 727 cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER; 728 } 729 if (sts == SCSI_CHECK && (code & ECMD_SVALID)) { 730 cto->rsp.m1.ct_resp[0] = 0xf0; 731 cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf; 732 cto->rsp.m1.ct_resp[7] = 8; 733 cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff; 734 cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff; 735 cto->rsp.m1.ct_senselen = 16; 736 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID; 737 } 738 cto->ct_syshandle = hdl; 739 } else { 740 at_entry_t *aep; 741 ct_entry_t *cto = &un._ctio; 742 743 va_start(ap, isp); 744 aep = va_arg(ap, at_entry_t *); 745 code = va_arg(ap, uint32_t); 746 hdl = va_arg(ap, uint32_t); 747 va_end(ap); 748 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [IID %d] code %x", __func__, aep->at_iid, code); 749 sts = code; 750 751 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO; 752 cto->ct_header.rqs_entry_count = 1; 753 cto->ct_fwhandle = aep->at_handle; 754 cto->ct_iid = aep->at_iid; 755 cto->ct_tgt = aep->at_tgt; 756 cto->ct_lun = aep->at_lun; 757 cto->ct_tag_type = aep->at_tag_type; 758 cto->ct_tag_val = aep->at_tag_val; 759 if (aep->at_flags & AT_TQAE) { 760 cto->ct_flags |= CT_TQAE; 761 } 762 cto->ct_flags = CT_SENDSTATUS | CT_NO_DATA; 763 if (hdl == 0) { 764 cto->ct_flags |= CT_CCINCR; 765 } 766 cto->ct_scsi_status = sts; 767 cto->ct_syshandle = hdl; 768 } 769 return (isp_target_put_entry(isp, &un)); 770} 771 772/* 773 * These are either broadcast events or specifically CTIO fast completion 774 */ 775 776int 777isp_target_async(ispsoftc_t *isp, int bus, int event) 778{ 779 isp_notify_t notify; 780 781 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 782 notify.nt_hba = isp; 783 notify.nt_wwn = INI_ANY; 784 notify.nt_nphdl = NIL_HANDLE; 785 notify.nt_sid = PORT_ANY; 786 notify.nt_did = PORT_ANY; 787 notify.nt_tgt = TGT_ANY; 788 notify.nt_channel = bus; 789 notify.nt_lun = LUN_ANY; 790 notify.nt_tagval = TAG_ANY; 791 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 792 793 switch (event) { 794 case ASYNC_LOOP_UP: 795 case ASYNC_PTPMODE: 796 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP UP", __func__); 797 notify.nt_ncode = NT_LINK_UP; 798 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 799 break; 800 case ASYNC_LOOP_DOWN: 801 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP DOWN", __func__); 802 notify.nt_ncode = NT_LINK_DOWN; 803 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 804 break; 805 case ASYNC_LIP_ERROR: 806 case ASYNC_LIP_F8: 807 case ASYNC_LIP_OCCURRED: 808 case ASYNC_LOOP_RESET: 809 isp_prt(isp, ISP_LOGTDEBUG0, "%s: LIP RESET", __func__); 810 notify.nt_ncode = NT_LIP_RESET; 811 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 812 break; 813 case ASYNC_BUS_RESET: 814 case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */ 815 isp_prt(isp, ISP_LOGTDEBUG0, "%s: BUS RESET", __func__); 816 notify.nt_ncode = NT_BUS_RESET; 817 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 818 break; 819 case ASYNC_DEVICE_RESET: 820 isp_prt(isp, ISP_LOGTDEBUG0, "%s: DEVICE RESET", __func__); 821 notify.nt_ncode = NT_TARGET_RESET; 822 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 823 break; 824 case ASYNC_CTIO_DONE: 825 { 826 uint8_t storage[QENTRY_LEN]; 827 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO DONE", __func__); 828 memset(storage, 0, QENTRY_LEN); 829 if (IS_24XX(isp)) { 830 ct7_entry_t *ct = (ct7_entry_t *) storage; 831 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 832 ct->ct_nphdl = CT7_OK; 833 ct->ct_syshandle = bus; 834 ct->ct_flags = CT7_SENDSTATUS; 835 } else if (IS_FC(isp)) { 836 /* This should also suffice for 2K login code */ 837 ct2_entry_t *ct = (ct2_entry_t *) storage; 838 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 839 ct->ct_status = CT_OK; 840 ct->ct_syshandle = bus; 841 ct->ct_flags = CT2_SENDSTATUS|CT2_FASTPOST; 842 } else { 843 ct_entry_t *ct = (ct_entry_t *) storage; 844 ct->ct_header.rqs_entry_type = RQSTYPE_CTIO; 845 ct->ct_status = CT_OK; 846 ct->ct_syshandle = bus; 847 /* we skip fwhandle here */ 848 ct->ct_fwhandle = 0; 849 ct->ct_flags = CT_SENDSTATUS; 850 } 851 isp_async(isp, ISPASYNC_TARGET_ACTION, storage); 852 break; 853 } 854 default: 855 isp_prt(isp, ISP_LOGERR, "%s: unknown event 0x%x", __func__, event); 856 if (isp->isp_state == ISP_RUNSTATE) {
|
840 (void) isp_notify_ack(isp, NULL);
| 857 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, NULL);
|
841 } 842 break; 843 } 844 return (0); 845} 846 847 848/* 849 * Process a received message. 850 * The ISP firmware can handle most messages, there are only 851 * a few that we need to deal with: 852 * - abort: clean up the current command 853 * - abort tag and clear queue 854 */ 855 856static void 857isp_got_msg(ispsoftc_t *isp, in_entry_t *inp) 858{ 859 isp_notify_t notify; 860 uint8_t status = inp->in_status & ~QLTM_SVALID; 861 862 ISP_MEMZERO(¬ify, sizeof (notify)); 863 notify.nt_hba = isp; 864 notify.nt_wwn = INI_ANY; 865 notify.nt_nphdl = GET_IID_VAL(inp->in_iid); 866 notify.nt_sid = PORT_ANY; 867 notify.nt_did = PORT_ANY; 868 notify.nt_channel = GET_BUS_VAL(inp->in_iid); 869 notify.nt_tgt = inp->in_tgt; 870 notify.nt_lun = inp->in_lun; 871 IN_MAKE_TAGID(notify.nt_tagval, inp); 872 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 873 notify.nt_lreserved = inp; 874 875 if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) { 876 switch (inp->in_msg[0]) { 877 case MSG_ABORT: 878 notify.nt_ncode = NT_ABORT_TASK_SET; 879 break; 880 case MSG_BUS_DEV_RESET: 881 notify.nt_ncode = NT_TARGET_RESET; 882 break; 883 case MSG_ABORT_TAG: 884 notify.nt_ncode = NT_ABORT_TASK; 885 break; 886 case MSG_CLEAR_QUEUE: 887 notify.nt_ncode = NT_CLEAR_TASK_SET; 888 break; 889 case MSG_REL_RECOVERY: 890 notify.nt_ncode = NT_CLEAR_ACA; 891 break; 892 case MSG_TERM_IO_PROC: 893 notify.nt_ncode = NT_ABORT_TASK; 894 break; 895 case MSG_LUN_RESET: 896 notify.nt_ncode = NT_LUN_RESET; 897 break; 898 default: 899 isp_prt(isp, ISP_LOGERR, "%s: unhandled message 0x%x", __func__, inp->in_msg[0]);
| 858 } 859 break; 860 } 861 return (0); 862} 863 864 865/* 866 * Process a received message. 867 * The ISP firmware can handle most messages, there are only 868 * a few that we need to deal with: 869 * - abort: clean up the current command 870 * - abort tag and clear queue 871 */ 872 873static void 874isp_got_msg(ispsoftc_t *isp, in_entry_t *inp) 875{ 876 isp_notify_t notify; 877 uint8_t status = inp->in_status & ~QLTM_SVALID; 878 879 ISP_MEMZERO(¬ify, sizeof (notify)); 880 notify.nt_hba = isp; 881 notify.nt_wwn = INI_ANY; 882 notify.nt_nphdl = GET_IID_VAL(inp->in_iid); 883 notify.nt_sid = PORT_ANY; 884 notify.nt_did = PORT_ANY; 885 notify.nt_channel = GET_BUS_VAL(inp->in_iid); 886 notify.nt_tgt = inp->in_tgt; 887 notify.nt_lun = inp->in_lun; 888 IN_MAKE_TAGID(notify.nt_tagval, inp); 889 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 890 notify.nt_lreserved = inp; 891 892 if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) { 893 switch (inp->in_msg[0]) { 894 case MSG_ABORT: 895 notify.nt_ncode = NT_ABORT_TASK_SET; 896 break; 897 case MSG_BUS_DEV_RESET: 898 notify.nt_ncode = NT_TARGET_RESET; 899 break; 900 case MSG_ABORT_TAG: 901 notify.nt_ncode = NT_ABORT_TASK; 902 break; 903 case MSG_CLEAR_QUEUE: 904 notify.nt_ncode = NT_CLEAR_TASK_SET; 905 break; 906 case MSG_REL_RECOVERY: 907 notify.nt_ncode = NT_CLEAR_ACA; 908 break; 909 case MSG_TERM_IO_PROC: 910 notify.nt_ncode = NT_ABORT_TASK; 911 break; 912 case MSG_LUN_RESET: 913 notify.nt_ncode = NT_LUN_RESET; 914 break; 915 default: 916 isp_prt(isp, ISP_LOGERR, "%s: unhandled message 0x%x", __func__, inp->in_msg[0]);
|
900 (void) isp_notify_ack(isp, inp);
| 917 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp);
|
901 return; 902 } 903 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 904 } else { 905 isp_prt(isp, ISP_LOGERR, "%s: unknown immediate notify status 0x%x", __func__, inp->in_status);
| 918 return; 919 } 920 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 921 } else { 922 isp_prt(isp, ISP_LOGERR, "%s: unknown immediate notify status 0x%x", __func__, inp->in_status);
|
906 (void) isp_notify_ack(isp, inp);
| 923 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp);
|
907 } 908} 909 910/* 911 * Synthesize a message from the task management flags in a FCP_CMND_IU. 912 */ 913static void 914isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp) 915{ 916 isp_notify_t notify; 917 static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x"; 918 static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x task flags 0x%x seq 0x%x\n"; 919 uint16_t seqid, loopid; 920 921 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 922 notify.nt_hba = isp; 923 notify.nt_wwn = INI_ANY; 924 if (ISP_CAP_2KLOGIN(isp)) { 925 notify.nt_nphdl = ((in_fcentry_e_t *)inp)->in_iid; 926 loopid = ((in_fcentry_e_t *)inp)->in_iid; 927 seqid = ((in_fcentry_e_t *)inp)->in_seqid; 928 } else { 929 notify.nt_nphdl = inp->in_iid; 930 loopid = inp->in_iid; 931 seqid = inp->in_seqid; 932 } 933 notify.nt_sid = PORT_ANY; 934 notify.nt_did = PORT_ANY; 935 936 /* nt_tgt set in outer layers */ 937 if (ISP_CAP_SCCFW(isp)) { 938 notify.nt_lun = inp->in_scclun; 939 } else { 940 notify.nt_lun = inp->in_lun; 941 } 942 notify.nt_tagval = seqid; 943 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 944 notify.nt_need_ack = 1; 945 notify.nt_lreserved = inp; 946 947 if (inp->in_status != IN_MSG_RECEIVED) { 948 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status", inp->in_status, notify.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
| 924 } 925} 926 927/* 928 * Synthesize a message from the task management flags in a FCP_CMND_IU. 929 */ 930static void 931isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp) 932{ 933 isp_notify_t notify; 934 static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x"; 935 static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x task flags 0x%x seq 0x%x\n"; 936 uint16_t seqid, loopid; 937 938 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 939 notify.nt_hba = isp; 940 notify.nt_wwn = INI_ANY; 941 if (ISP_CAP_2KLOGIN(isp)) { 942 notify.nt_nphdl = ((in_fcentry_e_t *)inp)->in_iid; 943 loopid = ((in_fcentry_e_t *)inp)->in_iid; 944 seqid = ((in_fcentry_e_t *)inp)->in_seqid; 945 } else { 946 notify.nt_nphdl = inp->in_iid; 947 loopid = inp->in_iid; 948 seqid = inp->in_seqid; 949 } 950 notify.nt_sid = PORT_ANY; 951 notify.nt_did = PORT_ANY; 952 953 /* nt_tgt set in outer layers */ 954 if (ISP_CAP_SCCFW(isp)) { 955 notify.nt_lun = inp->in_scclun; 956 } else { 957 notify.nt_lun = inp->in_lun; 958 } 959 notify.nt_tagval = seqid; 960 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 961 notify.nt_need_ack = 1; 962 notify.nt_lreserved = inp; 963 964 if (inp->in_status != IN_MSG_RECEIVED) { 965 isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status", inp->in_status, notify.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
|
949 (void) isp_notify_ack(isp, inp);
| 966 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp);
|
950 return; 951 } 952 953 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) { 954 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", loopid, notify.nt_lun, inp->in_seqid); 955 notify.nt_ncode = NT_ABORT_TASK_SET; 956 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) { 957 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", loopid, notify.nt_lun, inp->in_seqid); 958 notify.nt_ncode = NT_CLEAR_TASK_SET; 959 } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) { 960 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", loopid, notify.nt_lun, inp->in_seqid); 961 notify.nt_ncode = NT_LUN_RESET; 962 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) { 963 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", loopid, notify.nt_lun, inp->in_seqid); 964 notify.nt_ncode = NT_TARGET_RESET; 965 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) { 966 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", loopid, notify.nt_lun, inp->in_seqid); 967 notify.nt_ncode = NT_CLEAR_ACA; 968 } else { 969 isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status, notify.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
| 967 return; 968 } 969 970 if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) { 971 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", loopid, notify.nt_lun, inp->in_seqid); 972 notify.nt_ncode = NT_ABORT_TASK_SET; 973 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) { 974 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", loopid, notify.nt_lun, inp->in_seqid); 975 notify.nt_ncode = NT_CLEAR_TASK_SET; 976 } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) { 977 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", loopid, notify.nt_lun, inp->in_seqid); 978 notify.nt_ncode = NT_LUN_RESET; 979 } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) { 980 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", loopid, notify.nt_lun, inp->in_seqid); 981 notify.nt_ncode = NT_TARGET_RESET; 982 } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) { 983 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", loopid, notify.nt_lun, inp->in_seqid); 984 notify.nt_ncode = NT_CLEAR_ACA; 985 } else { 986 isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status, notify.nt_lun, loopid, inp->in_task_flags, inp->in_seqid);
|
970 (void) isp_notify_ack(isp, inp);
| 987 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp);
|
971 return; 972 } 973 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 974} 975 976static void 977isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep) 978{ 979 isp_notify_t notify; 980 static const char f1[] = "%s from PortID 0x%06x lun %d seq 0x%08x"; 981 static const char f2[] = "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x"; 982 uint16_t chan; 983 uint32_t sid, did; 984 985 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 986 notify.nt_hba = isp; 987 notify.nt_wwn = INI_ANY; 988 notify.nt_lun = (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | (aep->at_cmnd.fcp_cmnd_lun[1]); 989 notify.nt_tagval = aep->at_rxid; 990 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 991 notify.nt_lreserved = aep; 992 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | (aep->at_hdr.s_id[2]); 993 994 /* Channel has to derived from D_ID */ 995 did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2]; 996 for (chan = 0; chan < isp->isp_nchan; chan++) { 997 if (FCPARAM(isp, chan)->isp_portid == did) { 998 break; 999 } 1000 } 1001 if (chan == isp->isp_nchan) { 1002 isp_prt(isp, ISP_LOGWARN, "%s: D_ID 0x%x not found on any channel", __func__, did); 1003 /* just drop on the floor */ 1004 return; 1005 } 1006 notify.nt_nphdl = NIL_HANDLE; /* unknown here */ 1007 notify.nt_sid = sid; 1008 notify.nt_did = did; 1009 notify.nt_channel = chan; 1010 if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_ABORT_TASK_SET) { 1011 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", sid, notify.nt_lun, aep->at_rxid); 1012 notify.nt_ncode = NT_ABORT_TASK_SET; 1013 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_TASK_SET) { 1014 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", sid, notify.nt_lun, aep->at_rxid); 1015 notify.nt_ncode = NT_CLEAR_TASK_SET; 1016 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_LUN_RESET) { 1017 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", sid, notify.nt_lun, aep->at_rxid); 1018 notify.nt_ncode = NT_LUN_RESET; 1019 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_TGT_RESET) { 1020 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", sid, notify.nt_lun, aep->at_rxid); 1021 notify.nt_ncode = NT_TARGET_RESET; 1022 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_ACA) { 1023 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", sid, notify.nt_lun, aep->at_rxid); 1024 notify.nt_ncode = NT_CLEAR_ACA; 1025 } else { 1026 isp_prt(isp, ISP_LOGWARN, f2, aep->at_cmnd.fcp_cmnd_task_management, notify.nt_lun, sid, aep->at_rxid); 1027 notify.nt_ncode = NT_UNKNOWN; 1028 return; 1029 } 1030 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 1031} 1032 1033int 1034isp_notify_ack(ispsoftc_t *isp, void *arg) 1035{ 1036 char storage[QENTRY_LEN]; 1037 void *outp; 1038 1039 /* 1040 * This is in case a Task Management Function ends up here. 1041 */ 1042 if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) { 1043 at7_entry_t *aep = arg; 1044 return (isp_endcmd(isp, aep, NIL_HANDLE, 0, 0, 0)); 1045 } 1046 1047 outp = isp_getrqentry(isp); 1048 if (outp == NULL) { 1049 isp_prt(isp, ISP_LOGWARN, rqo, __func__); 1050 return (1); 1051 } 1052 1053 ISP_MEMZERO(storage, QENTRY_LEN); 1054 1055 if (IS_24XX(isp)) { 1056 na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage;
| 988 return; 989 } 990 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 991} 992 993static void 994isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep) 995{ 996 isp_notify_t notify; 997 static const char f1[] = "%s from PortID 0x%06x lun %d seq 0x%08x"; 998 static const char f2[] = "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x"; 999 uint16_t chan; 1000 uint32_t sid, did; 1001 1002 ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); 1003 notify.nt_hba = isp; 1004 notify.nt_wwn = INI_ANY; 1005 notify.nt_lun = (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | (aep->at_cmnd.fcp_cmnd_lun[1]); 1006 notify.nt_tagval = aep->at_rxid; 1007 notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); 1008 notify.nt_lreserved = aep; 1009 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | (aep->at_hdr.s_id[2]); 1010 1011 /* Channel has to derived from D_ID */ 1012 did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2]; 1013 for (chan = 0; chan < isp->isp_nchan; chan++) { 1014 if (FCPARAM(isp, chan)->isp_portid == did) { 1015 break; 1016 } 1017 } 1018 if (chan == isp->isp_nchan) { 1019 isp_prt(isp, ISP_LOGWARN, "%s: D_ID 0x%x not found on any channel", __func__, did); 1020 /* just drop on the floor */ 1021 return; 1022 } 1023 notify.nt_nphdl = NIL_HANDLE; /* unknown here */ 1024 notify.nt_sid = sid; 1025 notify.nt_did = did; 1026 notify.nt_channel = chan; 1027 if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_ABORT_TASK_SET) { 1028 isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", sid, notify.nt_lun, aep->at_rxid); 1029 notify.nt_ncode = NT_ABORT_TASK_SET; 1030 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_TASK_SET) { 1031 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", sid, notify.nt_lun, aep->at_rxid); 1032 notify.nt_ncode = NT_CLEAR_TASK_SET; 1033 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_LUN_RESET) { 1034 isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", sid, notify.nt_lun, aep->at_rxid); 1035 notify.nt_ncode = NT_LUN_RESET; 1036 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_TGT_RESET) { 1037 isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", sid, notify.nt_lun, aep->at_rxid); 1038 notify.nt_ncode = NT_TARGET_RESET; 1039 } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_ACA) { 1040 isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", sid, notify.nt_lun, aep->at_rxid); 1041 notify.nt_ncode = NT_CLEAR_ACA; 1042 } else { 1043 isp_prt(isp, ISP_LOGWARN, f2, aep->at_cmnd.fcp_cmnd_task_management, notify.nt_lun, sid, aep->at_rxid); 1044 notify.nt_ncode = NT_UNKNOWN; 1045 return; 1046 } 1047 isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); 1048} 1049 1050int 1051isp_notify_ack(ispsoftc_t *isp, void *arg) 1052{ 1053 char storage[QENTRY_LEN]; 1054 void *outp; 1055 1056 /* 1057 * This is in case a Task Management Function ends up here. 1058 */ 1059 if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) { 1060 at7_entry_t *aep = arg; 1061 return (isp_endcmd(isp, aep, NIL_HANDLE, 0, 0, 0)); 1062 } 1063 1064 outp = isp_getrqentry(isp); 1065 if (outp == NULL) { 1066 isp_prt(isp, ISP_LOGWARN, rqo, __func__); 1067 return (1); 1068 } 1069 1070 ISP_MEMZERO(storage, QENTRY_LEN); 1071 1072 if (IS_24XX(isp)) { 1073 na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage;
|
| 1074 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; 1075 na->na_header.rqs_entry_count = 1;
|
1057 if (arg) { 1058 in_fcentry_24xx_t *in = arg; 1059 na->na_nphdl = in->in_nphdl;
| 1076 if (arg) { 1077 in_fcentry_24xx_t *in = arg; 1078 na->na_nphdl = in->in_nphdl;
|
1060 na->na_flags = in->in_flags & IN24XX_FLAG_PUREX_IOCB;
| 1079 na->na_flags = in->in_flags;
|
1061 na->na_status = in->in_status; 1062 na->na_status_subcode = in->in_status_subcode; 1063 na->na_rxid = in->in_rxid; 1064 na->na_oxid = in->in_oxid; 1065 na->na_vpidx = in->in_vpidx; 1066 if (in->in_status == IN24XX_SRR_RCVD) { 1067 na->na_srr_rxid = in->in_srr_rxid; 1068 na->na_srr_reloff_hi = in->in_srr_reloff_hi; 1069 na->na_srr_reloff_lo = in->in_srr_reloff_lo; 1070 na->na_srr_iu = in->in_srr_iu;
| 1080 na->na_status = in->in_status; 1081 na->na_status_subcode = in->in_status_subcode; 1082 na->na_rxid = in->in_rxid; 1083 na->na_oxid = in->in_oxid; 1084 na->na_vpidx = in->in_vpidx; 1085 if (in->in_status == IN24XX_SRR_RCVD) { 1086 na->na_srr_rxid = in->in_srr_rxid; 1087 na->na_srr_reloff_hi = in->in_srr_reloff_hi; 1088 na->na_srr_reloff_lo = in->in_srr_reloff_lo; 1089 na->na_srr_iu = in->in_srr_iu;
|
1071 na->na_srr_flags = 1; 1072 na->na_srr_reject_vunique = 0; 1073 na->na_srr_reject_explanation = 1; 1074 na->na_srr_reject_code = 1;
| 1090 /* 1091 * Whether we're accepting the SRR or rejecting 1092 * it is determined by looking at the in_reserved 1093 * field in the original notify structure. 1094 */ 1095 if (in->in_reserved) { 1096 na->na_srr_flags = 1; 1097 na->na_srr_reject_vunique = 0; 1098 na->na_srr_reject_code = 9; /* unable to perform this command at this time */ 1099 na->na_srr_reject_explanation = 0x2a; /* unable to supply the requested data */ 1100 }
|
1075 } 1076 }
| 1101 } 1102 }
|
1077 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; 1078 na->na_header.rqs_entry_count = 1;
| |
1079 isp_put_notify_24xx_ack(isp, na, (na_fcentry_24xx_t *)outp); 1080 } else if (IS_FC(isp)) { 1081 na_fcentry_t *na = (na_fcentry_t *) storage; 1082 int iid = 0; 1083 1084 if (arg) { 1085 in_fcentry_t *inp = arg; 1086 ISP_MEMCPY(storage, arg, sizeof (isphdr_t)); 1087 if (ISP_CAP_2KLOGIN(isp)) { 1088 ((na_fcentry_e_t *)na)->na_iid = ((in_fcentry_e_t *)inp)->in_iid; 1089 iid = ((na_fcentry_e_t *)na)->na_iid; 1090 } else { 1091 na->na_iid = inp->in_iid; 1092 iid = na->na_iid; 1093 } 1094 na->na_task_flags = inp->in_task_flags & TASK_FLAGS_RESERVED_MASK; 1095 na->na_seqid = inp->in_seqid;
| 1103 isp_put_notify_24xx_ack(isp, na, (na_fcentry_24xx_t *)outp); 1104 } else if (IS_FC(isp)) { 1105 na_fcentry_t *na = (na_fcentry_t *) storage; 1106 int iid = 0; 1107 1108 if (arg) { 1109 in_fcentry_t *inp = arg; 1110 ISP_MEMCPY(storage, arg, sizeof (isphdr_t)); 1111 if (ISP_CAP_2KLOGIN(isp)) { 1112 ((na_fcentry_e_t *)na)->na_iid = ((in_fcentry_e_t *)inp)->in_iid; 1113 iid = ((na_fcentry_e_t *)na)->na_iid; 1114 } else { 1115 na->na_iid = inp->in_iid; 1116 iid = na->na_iid; 1117 } 1118 na->na_task_flags = inp->in_task_flags & TASK_FLAGS_RESERVED_MASK; 1119 na->na_seqid = inp->in_seqid;
|
1096 na->na_flags = NAFC_RCOUNT;
| |
1097 na->na_status = inp->in_status;
| 1120 na->na_status = inp->in_status;
|
| 1121 na->na_flags = NAFC_RCOUNT;
|
1098 if (inp->in_status == IN_RESET) {
| 1122 if (inp->in_status == IN_RESET) {
|
1099 na->na_flags |= NAFC_RST_CLRD;
| 1123 na->na_flags = NAFC_RST_CLRD; /* We do not modify resource counts for LIP resets */
|
1100 } 1101 if (inp->in_status == IN_MSG_RECEIVED) { 1102 na->na_flags |= NAFC_TVALID; 1103 na->na_response = 0; /* XXX SUCCEEDED XXX */ 1104 } 1105 } else { 1106 na->na_flags = NAFC_RST_CLRD; 1107 } 1108 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; 1109 na->na_header.rqs_entry_count = 1; 1110 if (ISP_CAP_2KLOGIN(isp)) { 1111 isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na, (na_fcentry_e_t *)outp); 1112 } else { 1113 isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp); 1114 } 1115 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x flags %x tflags %x response %x", iid, na->na_seqid, 1116 na->na_flags, na->na_task_flags, na->na_response); 1117 } else { 1118 na_entry_t *na = (na_entry_t *) storage; 1119 if (arg) { 1120 in_entry_t *inp = arg; 1121 ISP_MEMCPY(storage, arg, sizeof (isphdr_t)); 1122 na->na_iid = inp->in_iid; 1123 na->na_lun = inp->in_lun; 1124 na->na_tgt = inp->in_tgt; 1125 na->na_seqid = inp->in_seqid; 1126 if (inp->in_status == IN_RESET) { 1127 na->na_event = NA_RST_CLRD; 1128 } 1129 } else { 1130 na->na_event = NA_RST_CLRD; 1131 } 1132 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; 1133 na->na_header.rqs_entry_count = 1; 1134 isp_put_notify_ack(isp, na, (na_entry_t *)outp); 1135 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt %u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt, na->na_seqid, na->na_event); 1136 } 1137 ISP_TDQE(isp, "isp_notify_ack", isp->isp_reqidx, storage); 1138 ISP_SYNC_REQUEST(isp); 1139 return (0); 1140} 1141 1142int 1143isp_acknak_abts(ispsoftc_t *isp, void *arg, int errno) 1144{ 1145 char storage[QENTRY_LEN]; 1146 uint16_t tmpw; 1147 uint8_t tmpb; 1148 abts_t *abts = arg; 1149 abts_rsp_t *rsp = (abts_rsp_t *) storage; 1150 void *outp; 1151 1152 if (!IS_24XX(isp)) { 1153 isp_prt(isp, ISP_LOGERR, "%s: called for non-24XX card", __func__); 1154 return (0); 1155 } 1156 1157 if (abts->abts_header.rqs_entry_type != RQSTYPE_ABTS_RCVD) { 1158 isp_prt(isp, ISP_LOGERR, "%s: called for non-ABTS entry (0x%x)", __func__, abts->abts_header.rqs_entry_type); 1159 return (0); 1160 } 1161 1162 outp = isp_getrqentry(isp); 1163 if (outp == NULL) { 1164 isp_prt(isp, ISP_LOGWARN, rqo, __func__); 1165 return (1); 1166 } 1167 1168 ISP_MEMCPY(rsp, abts, QENTRY_LEN); 1169 rsp->abts_rsp_header.rqs_entry_type = RQSTYPE_ABTS_RSP; 1170 1171 /* 1172 * Swap destination and source for response. 1173 */ 1174 rsp->abts_rsp_r_ctl = BA_ACC; 1175 tmpw = rsp->abts_rsp_did_lo; 1176 tmpb = rsp->abts_rsp_did_hi; 1177 rsp->abts_rsp_did_lo = rsp->abts_rsp_sid_lo; 1178 rsp->abts_rsp_did_hi = rsp->abts_rsp_sid_hi; 1179 rsp->abts_rsp_sid_lo = tmpw; 1180 rsp->abts_rsp_sid_hi = tmpb; 1181 1182 rsp->abts_rsp_f_ctl_hi ^= 0x80; /* invert Exchange Context */ 1183 rsp->abts_rsp_f_ctl_hi &= ~0x7f; /* clear Sequence Initiator and other bits */ 1184 rsp->abts_rsp_f_ctl_hi |= 0x10; /* abort the whole exchange */ 1185 rsp->abts_rsp_f_ctl_hi |= 0x8; /* last data frame of sequence */ 1186 rsp->abts_rsp_f_ctl_hi |= 0x1; /* transfer Sequence Initiative */ 1187 rsp->abts_rsp_f_ctl_lo = 0; 1188 1189 if (errno == 0) { 1190 uint16_t rx_id, ox_id; 1191 1192 rx_id = rsp->abts_rsp_rx_id; 1193 ox_id = rsp->abts_rsp_ox_id; 1194 ISP_MEMZERO(&rsp->abts_rsp_payload.ba_acc, sizeof (rsp->abts_rsp_payload.ba_acc)); 1195 isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS of 0x%x being BA_ACC'd", rsp->abts_rsp_rxid_abts, rsp->abts_rsp_rxid_task); 1196 rsp->abts_rsp_payload.ba_acc.aborted_rx_id = rx_id; 1197 rsp->abts_rsp_payload.ba_acc.aborted_ox_id = ox_id; 1198 rsp->abts_rsp_payload.ba_acc.high_seq_cnt = 0xffff; 1199 } else { 1200 ISP_MEMZERO(&rsp->abts_rsp_payload.ba_rjt, sizeof (rsp->abts_rsp_payload.ba_acc)); 1201 switch (errno) { 1202 case ENOMEM:
| 1124 } 1125 if (inp->in_status == IN_MSG_RECEIVED) { 1126 na->na_flags |= NAFC_TVALID; 1127 na->na_response = 0; /* XXX SUCCEEDED XXX */ 1128 } 1129 } else { 1130 na->na_flags = NAFC_RST_CLRD; 1131 } 1132 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; 1133 na->na_header.rqs_entry_count = 1; 1134 if (ISP_CAP_2KLOGIN(isp)) { 1135 isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na, (na_fcentry_e_t *)outp); 1136 } else { 1137 isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp); 1138 } 1139 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x flags %x tflags %x response %x", iid, na->na_seqid, 1140 na->na_flags, na->na_task_flags, na->na_response); 1141 } else { 1142 na_entry_t *na = (na_entry_t *) storage; 1143 if (arg) { 1144 in_entry_t *inp = arg; 1145 ISP_MEMCPY(storage, arg, sizeof (isphdr_t)); 1146 na->na_iid = inp->in_iid; 1147 na->na_lun = inp->in_lun; 1148 na->na_tgt = inp->in_tgt; 1149 na->na_seqid = inp->in_seqid; 1150 if (inp->in_status == IN_RESET) { 1151 na->na_event = NA_RST_CLRD; 1152 } 1153 } else { 1154 na->na_event = NA_RST_CLRD; 1155 } 1156 na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; 1157 na->na_header.rqs_entry_count = 1; 1158 isp_put_notify_ack(isp, na, (na_entry_t *)outp); 1159 isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt %u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt, na->na_seqid, na->na_event); 1160 } 1161 ISP_TDQE(isp, "isp_notify_ack", isp->isp_reqidx, storage); 1162 ISP_SYNC_REQUEST(isp); 1163 return (0); 1164} 1165 1166int 1167isp_acknak_abts(ispsoftc_t *isp, void *arg, int errno) 1168{ 1169 char storage[QENTRY_LEN]; 1170 uint16_t tmpw; 1171 uint8_t tmpb; 1172 abts_t *abts = arg; 1173 abts_rsp_t *rsp = (abts_rsp_t *) storage; 1174 void *outp; 1175 1176 if (!IS_24XX(isp)) { 1177 isp_prt(isp, ISP_LOGERR, "%s: called for non-24XX card", __func__); 1178 return (0); 1179 } 1180 1181 if (abts->abts_header.rqs_entry_type != RQSTYPE_ABTS_RCVD) { 1182 isp_prt(isp, ISP_LOGERR, "%s: called for non-ABTS entry (0x%x)", __func__, abts->abts_header.rqs_entry_type); 1183 return (0); 1184 } 1185 1186 outp = isp_getrqentry(isp); 1187 if (outp == NULL) { 1188 isp_prt(isp, ISP_LOGWARN, rqo, __func__); 1189 return (1); 1190 } 1191 1192 ISP_MEMCPY(rsp, abts, QENTRY_LEN); 1193 rsp->abts_rsp_header.rqs_entry_type = RQSTYPE_ABTS_RSP; 1194 1195 /* 1196 * Swap destination and source for response. 1197 */ 1198 rsp->abts_rsp_r_ctl = BA_ACC; 1199 tmpw = rsp->abts_rsp_did_lo; 1200 tmpb = rsp->abts_rsp_did_hi; 1201 rsp->abts_rsp_did_lo = rsp->abts_rsp_sid_lo; 1202 rsp->abts_rsp_did_hi = rsp->abts_rsp_sid_hi; 1203 rsp->abts_rsp_sid_lo = tmpw; 1204 rsp->abts_rsp_sid_hi = tmpb; 1205 1206 rsp->abts_rsp_f_ctl_hi ^= 0x80; /* invert Exchange Context */ 1207 rsp->abts_rsp_f_ctl_hi &= ~0x7f; /* clear Sequence Initiator and other bits */ 1208 rsp->abts_rsp_f_ctl_hi |= 0x10; /* abort the whole exchange */ 1209 rsp->abts_rsp_f_ctl_hi |= 0x8; /* last data frame of sequence */ 1210 rsp->abts_rsp_f_ctl_hi |= 0x1; /* transfer Sequence Initiative */ 1211 rsp->abts_rsp_f_ctl_lo = 0; 1212 1213 if (errno == 0) { 1214 uint16_t rx_id, ox_id; 1215 1216 rx_id = rsp->abts_rsp_rx_id; 1217 ox_id = rsp->abts_rsp_ox_id; 1218 ISP_MEMZERO(&rsp->abts_rsp_payload.ba_acc, sizeof (rsp->abts_rsp_payload.ba_acc)); 1219 isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS of 0x%x being BA_ACC'd", rsp->abts_rsp_rxid_abts, rsp->abts_rsp_rxid_task); 1220 rsp->abts_rsp_payload.ba_acc.aborted_rx_id = rx_id; 1221 rsp->abts_rsp_payload.ba_acc.aborted_ox_id = ox_id; 1222 rsp->abts_rsp_payload.ba_acc.high_seq_cnt = 0xffff; 1223 } else { 1224 ISP_MEMZERO(&rsp->abts_rsp_payload.ba_rjt, sizeof (rsp->abts_rsp_payload.ba_acc)); 1225 switch (errno) { 1226 case ENOMEM:
|
1203 rsp->abts_rsp_payload.ba_rjt.reason = 5; /* Logical Busy */
| 1227 rsp->abts_rsp_payload.ba_rjt.reason = 5; /* Logical Unit Busy */
|
1204 break; 1205 default: 1206 rsp->abts_rsp_payload.ba_rjt.reason = 9; /* Unable to perform command request */ 1207 break; 1208 } 1209 } 1210 1211 /* 1212 * The caller will have set response values as appropriate 1213 * in the ABTS structure just before calling us. 1214 */ 1215 isp_put_abts_rsp(isp, rsp, (abts_rsp_t *)outp); 1216 ISP_TDQE(isp, "isp_acknak_abts", isp->isp_reqidx, storage); 1217 ISP_SYNC_REQUEST(isp); 1218 return (0); 1219} 1220 1221static void 1222isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep) 1223{ 1224 int lun; 1225 lun = aep->at_lun; 1226 /* 1227 * The firmware status (except for the QLTM_SVALID bit) indicates 1228 * why this ATIO was sent to us. 1229 * 1230 * If QLTM_SVALID is set, the firware has recommended Sense Data. 1231 * 1232 * If the DISCONNECTS DISABLED bit is set in the flags field, 1233 * we're still connected on the SCSI bus - i.e. the initiator 1234 * did not set DiscPriv in the identify message. We don't care 1235 * about this so it's ignored. 1236 */ 1237 1238 switch (aep->at_status & ~QLTM_SVALID) { 1239 case AT_PATH_INVALID: 1240 /* 1241 * ATIO rejected by the firmware due to disabled lun. 1242 */ 1243 isp_prt(isp, ISP_LOGERR, "rejected ATIO for disabled lun %d", lun); 1244 break; 1245 case AT_NOCAP: 1246 /* 1247 * Requested Capability not available 1248 * We sent an ATIO that overflowed the firmware's 1249 * command resource count. 1250 */ 1251 isp_prt(isp, ISP_LOGERR, "rejected ATIO for lun %d because of command count overflow", lun); 1252 break; 1253 1254 case AT_BDR_MSG: 1255 /* 1256 * If we send an ATIO to the firmware to increment 1257 * its command resource count, and the firmware is 1258 * recovering from a Bus Device Reset, it returns 1259 * the ATIO with this status. We set the command 1260 * resource count in the Enable Lun entry and do 1261 * not increment it. Therefore we should never get 1262 * this status here. 1263 */ 1264 isp_prt(isp, ISP_LOGERR, atiocope, lun, GET_BUS_VAL(aep->at_iid)); 1265 break; 1266 1267 case AT_CDB: /* Got a CDB */ 1268 case AT_PHASE_ERROR: /* Bus Phase Sequence Error */ 1269 /* 1270 * Punt to platform specific layer. 1271 */ 1272 isp_async(isp, ISPASYNC_TARGET_ACTION, aep); 1273 break; 1274 1275 case AT_RESET: 1276 /* 1277 * A bus reset came along and blew away this command. Why 1278 * they do this in addition the async event code stuff, 1279 * I dunno. 1280 * 1281 * Ignore it because the async event will clear things 1282 * up for us. 1283 */ 1284 isp_prt(isp, ISP_LOGWARN, atior, lun, GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid)); 1285 break; 1286 1287 1288 default: 1289 isp_prt(isp, ISP_LOGERR, "Unknown ATIO status 0x%x from loopid %d for lun %d", aep->at_status, aep->at_iid, lun); 1290 (void) isp_target_put_atio(isp, aep); 1291 break; 1292 } 1293} 1294 1295static void 1296isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep) 1297{ 1298 int lun, iid; 1299 1300 if (ISP_CAP_SCCFW(isp)) { 1301 lun = aep->at_scclun; 1302 } else { 1303 lun = aep->at_lun; 1304 } 1305 1306 if (ISP_CAP_2KLOGIN(isp)) { 1307 iid = ((at2e_entry_t *)aep)->at_iid; 1308 } else { 1309 iid = aep->at_iid; 1310 } 1311 1312 /* 1313 * The firmware status (except for the QLTM_SVALID bit) indicates 1314 * why this ATIO was sent to us. 1315 * 1316 * If QLTM_SVALID is set, the firware has recommended Sense Data. 1317 * 1318 * If the DISCONNECTS DISABLED bit is set in the flags field, 1319 * we're still connected on the SCSI bus - i.e. the initiator 1320 * did not set DiscPriv in the identify message. We don't care 1321 * about this so it's ignored. 1322 */ 1323 1324 switch (aep->at_status & ~QLTM_SVALID) { 1325 case AT_PATH_INVALID: 1326 /* 1327 * ATIO rejected by the firmware due to disabled lun. 1328 */ 1329 isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for disabled lun %d", lun); 1330 break; 1331 case AT_NOCAP: 1332 /* 1333 * Requested Capability not available 1334 * We sent an ATIO that overflowed the firmware's 1335 * command resource count. 1336 */ 1337 isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for lun %d- command count overflow", lun); 1338 break; 1339 1340 case AT_BDR_MSG: 1341 /* 1342 * If we send an ATIO to the firmware to increment 1343 * its command resource count, and the firmware is 1344 * recovering from a Bus Device Reset, it returns 1345 * the ATIO with this status. We set the command 1346 * resource count in the Enable Lun entry and no 1347 * not increment it. Therefore we should never get 1348 * this status here. 1349 */ 1350 isp_prt(isp, ISP_LOGERR, atiocope, lun, 0); 1351 break; 1352 1353 case AT_CDB: /* Got a CDB */ 1354 /* 1355 * Punt to platform specific layer. 1356 */ 1357 isp_async(isp, ISPASYNC_TARGET_ACTION, aep); 1358 break; 1359 1360 case AT_RESET: 1361 /* 1362 * A bus reset came along an blew away this command. Why 1363 * they do this in addition the async event code stuff, 1364 * I dunno. 1365 * 1366 * Ignore it because the async event will clear things 1367 * up for us. 1368 */ 1369 isp_prt(isp, ISP_LOGERR, atior, lun, iid, 0); 1370 break; 1371 1372 1373 default: 1374 isp_prt(isp, ISP_LOGERR, "Unknown ATIO2 status 0x%x from loopid %d for lun %d", aep->at_status, iid, lun); 1375 (void) isp_target_put_atio(isp, aep); 1376 break; 1377 } 1378} 1379 1380static void 1381isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct) 1382{ 1383 void *xs; 1384 int pl = ISP_LOGTDEBUG2; 1385 char *fmsg = NULL; 1386 1387 if (ct->ct_syshandle) { 1388 xs = isp_find_xs_tgt(isp, ct->ct_syshandle); 1389 if (xs == NULL) { 1390 pl = ISP_LOGALL; 1391 } 1392 } else { 1393 xs = NULL; 1394 } 1395 1396 switch (ct->ct_status & ~QLTM_SVALID) { 1397 case CT_OK: 1398 /* 1399 * There are generally 3 possibilities as to why we'd get 1400 * this condition: 1401 * We disconnected after receiving a CDB. 1402 * We sent or received data. 1403 * We sent status & command complete. 1404 */ 1405 1406 if (ct->ct_flags & CT_SENDSTATUS) { 1407 break; 1408 } else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) { 1409 /* 1410 * Nothing to do in this case. 1411 */ 1412 isp_prt(isp, pl, "CTIO- iid %d disconnected OK", ct->ct_iid); 1413 return; 1414 } 1415 break; 1416 1417 case CT_BDR_MSG: 1418 /* 1419 * Bus Device Reset message received or the SCSI Bus has 1420 * been Reset; the firmware has gone to Bus Free. 1421 * 1422 * The firmware generates an async mailbox interrupt to 1423 * notify us of this and returns outstanding CTIOs with this 1424 * status. These CTIOs are handled in that same way as 1425 * CT_ABORTED ones, so just fall through here. 1426 */ 1427 fmsg = "Bus Device Reset"; 1428 /*FALLTHROUGH*/ 1429 case CT_RESET: 1430 if (fmsg == NULL) 1431 fmsg = "Bus Reset"; 1432 /*FALLTHROUGH*/ 1433 case CT_ABORTED: 1434 /* 1435 * When an Abort message is received the firmware goes to 1436 * Bus Free and returns all outstanding CTIOs with the status 1437 * set, then sends us an Immediate Notify entry. 1438 */ 1439 if (fmsg == NULL) 1440 fmsg = "ABORT TAG message sent by Initiator"; 1441 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO destroyed by %s", fmsg); 1442 break; 1443 1444 case CT_INVAL: 1445 /* 1446 * CTIO rejected by the firmware due to disabled lun. 1447 * "Cannot Happen". 1448 */ 1449 isp_prt(isp, ISP_LOGERR, "Firmware rejected CTIO for disabled lun %d", ct->ct_lun); 1450 break; 1451 1452 case CT_NOPATH: 1453 /* 1454 * CTIO rejected by the firmware due "no path for the 1455 * nondisconnecting nexus specified". This means that 1456 * we tried to access the bus while a non-disconnecting 1457 * command is in process. 1458 */ 1459 isp_prt(isp, ISP_LOGERR, "Firmware rejected CTIO for bad nexus %d/%d/%d", ct->ct_iid, ct->ct_tgt, ct->ct_lun); 1460 break; 1461 1462 case CT_RSELTMO: 1463 fmsg = "Reselection"; 1464 /*FALLTHROUGH*/ 1465 case CT_TIMEOUT: 1466 if (fmsg == NULL) 1467 fmsg = "Command"; 1468 isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg); 1469 break; 1470 1471 case CT_PANIC: 1472 if (fmsg == NULL) 1473 fmsg = "Unrecoverable Error"; 1474 /*FALLTHROUGH*/ 1475 case CT_ERR: 1476 if (fmsg == NULL) 1477 fmsg = "Completed with Error"; 1478 /*FALLTHROUGH*/ 1479 case CT_PHASE_ERROR: 1480 if (fmsg == NULL) 1481 fmsg = "Phase Sequence Error"; 1482 /*FALLTHROUGH*/ 1483 case CT_TERMINATED: 1484 if (fmsg == NULL) 1485 fmsg = "terminated by TERMINATE TRANSFER"; 1486 /*FALLTHROUGH*/ 1487 case CT_NOACK: 1488 if (fmsg == NULL) 1489 fmsg = "unacknowledged Immediate Notify pending"; 1490 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg); 1491 break; 1492 default: 1493 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x", ct->ct_status & ~QLTM_SVALID); 1494 break; 1495 } 1496 1497 if (xs == NULL) { 1498 /* 1499 * There may be more than one CTIO for a data transfer, 1500 * or this may be a status CTIO we're not monitoring. 1501 * 1502 * The assumption is that they'll all be returned in the 1503 * order we got them. 1504 */ 1505 if (ct->ct_syshandle == 0) { 1506 if ((ct->ct_flags & CT_SENDSTATUS) == 0) { 1507 isp_prt(isp, pl, "intermediate CTIO completed ok"); 1508 } else { 1509 isp_prt(isp, pl, "unmonitored CTIO completed ok"); 1510 } 1511 } else { 1512 isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); 1513 } 1514 } else { 1515 /* 1516 * Final CTIO completed. Release DMA resources and 1517 * notify platform dependent layers. 1518 */ 1519 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) { 1520 ISP_DMAFREE(isp, xs, ct->ct_syshandle); 1521 } 1522 isp_prt(isp, pl, "final CTIO complete"); 1523 /* 1524 * The platform layer will destroy the handle if appropriate. 1525 */ 1526 isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1527 } 1528} 1529 1530static void 1531isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct) 1532{ 1533 void *xs; 1534 int pl = ISP_LOGTDEBUG2; 1535 char *fmsg = NULL; 1536 1537 if (ct->ct_syshandle) { 1538 xs = isp_find_xs_tgt(isp, ct->ct_syshandle); 1539 if (xs == NULL) { 1540 pl = ISP_LOGALL; 1541 } 1542 } else { 1543 xs = NULL; 1544 } 1545 1546 switch (ct->ct_status & ~QLTM_SVALID) { 1547 case CT_BUS_ERROR: 1548 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error"); 1549 /* FALL Through */ 1550 case CT_DATA_OVER: 1551 case CT_DATA_UNDER: 1552 case CT_OK: 1553 /* 1554 * There are generally 2 possibilities as to why we'd get 1555 * this condition: 1556 * We sent or received data. 1557 * We sent status & command complete. 1558 */ 1559 1560 break; 1561 1562 case CT_BDR_MSG: 1563 /* 1564 * Target Reset function received. 1565 * 1566 * The firmware generates an async mailbox interrupt to 1567 * notify us of this and returns outstanding CTIOs with this 1568 * status. These CTIOs are handled in that same way as 1569 * CT_ABORTED ones, so just fall through here. 1570 */ 1571 fmsg = "TARGET RESET"; 1572 /*FALLTHROUGH*/ 1573 case CT_RESET: 1574 if (fmsg == NULL) 1575 fmsg = "LIP Reset"; 1576 /*FALLTHROUGH*/ 1577 case CT_ABORTED: 1578 /* 1579 * When an Abort message is received the firmware goes to 1580 * Bus Free and returns all outstanding CTIOs with the status 1581 * set, then sends us an Immediate Notify entry. 1582 */ 1583 if (fmsg == NULL) { 1584 fmsg = "ABORT"; 1585 } 1586 1587 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); 1588 break; 1589 1590 case CT_INVAL: 1591 /* 1592 * CTIO rejected by the firmware - invalid data direction. 1593 */ 1594 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data direction"); 1595 break; 1596 1597 case CT_RSELTMO: 1598 fmsg = "failure to reconnect to initiator"; 1599 /*FALLTHROUGH*/ 1600 case CT_TIMEOUT: 1601 if (fmsg == NULL) 1602 fmsg = "command"; 1603 isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg); 1604 break; 1605 1606 case CT_ERR: 1607 fmsg = "Completed with Error"; 1608 /*FALLTHROUGH*/ 1609 case CT_LOGOUT: 1610 if (fmsg == NULL) 1611 fmsg = "Port Logout"; 1612 /*FALLTHROUGH*/ 1613 case CT_PORTUNAVAIL: 1614 if (fmsg == NULL) 1615 fmsg = "Port not available"; 1616 /*FALLTHROUGH*/ 1617 case CT_PORTCHANGED: 1618 if (fmsg == NULL) 1619 fmsg = "Port Changed"; 1620 /*FALLTHROUGH*/ 1621 case CT_NOACK: 1622 if (fmsg == NULL) 1623 fmsg = "unacknowledged Immediate Notify pending"; 1624 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg); 1625 break; 1626 1627 case CT_INVRXID: 1628 /* 1629 * CTIO rejected by the firmware because an invalid RX_ID. 1630 * Just print a message. 1631 */ 1632 isp_prt(isp, ISP_LOGWARN, "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid); 1633 break; 1634 1635 default: 1636 isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x", ct->ct_status & ~QLTM_SVALID); 1637 break; 1638 } 1639 1640 if (xs == NULL) { 1641 /* 1642 * There may be more than one CTIO for a data transfer, 1643 * or this may be a status CTIO we're not monitoring. 1644 * 1645 * The assumption is that they'll all be returned in the 1646 * order we got them. 1647 */ 1648 if (ct->ct_syshandle == 0) { 1649 if ((ct->ct_flags & CT2_SENDSTATUS) == 0) { 1650 isp_prt(isp, pl, "intermediate CTIO completed ok"); 1651 } else { 1652 isp_prt(isp, pl, "unmonitored CTIO completed ok"); 1653 } 1654 } else { 1655 isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); 1656 } 1657 } else { 1658 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) { 1659 ISP_DMAFREE(isp, xs, ct->ct_syshandle); 1660 } 1661 if (ct->ct_flags & CT2_SENDSTATUS) { 1662 /* 1663 * Sent status and command complete. 1664 * 1665 * We're now really done with this command, so we 1666 * punt to the platform dependent layers because 1667 * only there can we do the appropriate command 1668 * complete thread synchronization. 1669 */ 1670 isp_prt(isp, pl, "status CTIO complete"); 1671 } else { 1672 /* 1673 * Final CTIO completed. Release DMA resources and 1674 * notify platform dependent layers. 1675 */ 1676 isp_prt(isp, pl, "data CTIO complete"); 1677 } 1678 isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1679 /* 1680 * The platform layer will destroy the handle if appropriate. 1681 */ 1682 } 1683} 1684 1685static void 1686isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct) 1687{ 1688 void *xs; 1689 int pl = ISP_LOGTDEBUG2; 1690 char *fmsg = NULL; 1691 1692 if (ct->ct_syshandle) { 1693 xs = isp_find_xs_tgt(isp, ct->ct_syshandle); 1694 if (xs == NULL) { 1695 pl = ISP_LOGALL; 1696 } 1697 } else { 1698 xs = NULL; 1699 } 1700 1701 switch (ct->ct_nphdl) { 1702 case CT7_BUS_ERROR: 1703 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error"); 1704 /* FALL Through */ 1705 case CT7_DATA_OVER: 1706 case CT7_DATA_UNDER: 1707 case CT7_OK: 1708 /* 1709 * There are generally 2 possibilities as to why we'd get 1710 * this condition: 1711 * We sent or received data. 1712 * We sent status & command complete. 1713 */ 1714 1715 break; 1716 1717 case CT7_RESET: 1718 if (fmsg == NULL) { 1719 fmsg = "LIP Reset"; 1720 } 1721 /*FALLTHROUGH*/ 1722 case CT7_ABORTED: 1723 /* 1724 * When an Abort message is received the firmware goes to 1725 * Bus Free and returns all outstanding CTIOs with the status 1726 * set, then sends us an Immediate Notify entry. 1727 */ 1728 if (fmsg == NULL) { 1729 fmsg = "ABORT"; 1730 } 1731 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); 1732 break; 1733 1734 case CT7_TIMEOUT: 1735 if (fmsg == NULL) { 1736 fmsg = "command"; 1737 } 1738 isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg); 1739 break; 1740 1741 case CT7_ERR: 1742 fmsg = "Completed with Error"; 1743 /*FALLTHROUGH*/ 1744 case CT7_LOGOUT: 1745 if (fmsg == NULL) { 1746 fmsg = "Port Logout"; 1747 } 1748 /*FALLTHROUGH*/ 1749 case CT7_PORTUNAVAIL: 1750 if (fmsg == NULL) { 1751 fmsg = "Port not available"; 1752 } 1753 /*FALLTHROUGH*/ 1754 case CT7_PORTCHANGED: 1755 if (fmsg == NULL) { 1756 fmsg = "Port Changed"; 1757 } 1758 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg); 1759 break; 1760 1761 case CT7_INVRXID: 1762 /* 1763 * CTIO rejected by the firmware because an invalid RX_ID. 1764 * Just print a message. 1765 */ 1766 isp_prt(isp, ISP_LOGWARN, "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid); 1767 break; 1768 1769 case CT7_REASSY_ERR: 1770 isp_prt(isp, ISP_LOGWARN, "reassembly error"); 1771 break; 1772 1773 case CT7_SRR:
| 1228 break; 1229 default: 1230 rsp->abts_rsp_payload.ba_rjt.reason = 9; /* Unable to perform command request */ 1231 break; 1232 } 1233 } 1234 1235 /* 1236 * The caller will have set response values as appropriate 1237 * in the ABTS structure just before calling us. 1238 */ 1239 isp_put_abts_rsp(isp, rsp, (abts_rsp_t *)outp); 1240 ISP_TDQE(isp, "isp_acknak_abts", isp->isp_reqidx, storage); 1241 ISP_SYNC_REQUEST(isp); 1242 return (0); 1243} 1244 1245static void 1246isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep) 1247{ 1248 int lun; 1249 lun = aep->at_lun; 1250 /* 1251 * The firmware status (except for the QLTM_SVALID bit) indicates 1252 * why this ATIO was sent to us. 1253 * 1254 * If QLTM_SVALID is set, the firware has recommended Sense Data. 1255 * 1256 * If the DISCONNECTS DISABLED bit is set in the flags field, 1257 * we're still connected on the SCSI bus - i.e. the initiator 1258 * did not set DiscPriv in the identify message. We don't care 1259 * about this so it's ignored. 1260 */ 1261 1262 switch (aep->at_status & ~QLTM_SVALID) { 1263 case AT_PATH_INVALID: 1264 /* 1265 * ATIO rejected by the firmware due to disabled lun. 1266 */ 1267 isp_prt(isp, ISP_LOGERR, "rejected ATIO for disabled lun %d", lun); 1268 break; 1269 case AT_NOCAP: 1270 /* 1271 * Requested Capability not available 1272 * We sent an ATIO that overflowed the firmware's 1273 * command resource count. 1274 */ 1275 isp_prt(isp, ISP_LOGERR, "rejected ATIO for lun %d because of command count overflow", lun); 1276 break; 1277 1278 case AT_BDR_MSG: 1279 /* 1280 * If we send an ATIO to the firmware to increment 1281 * its command resource count, and the firmware is 1282 * recovering from a Bus Device Reset, it returns 1283 * the ATIO with this status. We set the command 1284 * resource count in the Enable Lun entry and do 1285 * not increment it. Therefore we should never get 1286 * this status here. 1287 */ 1288 isp_prt(isp, ISP_LOGERR, atiocope, lun, GET_BUS_VAL(aep->at_iid)); 1289 break; 1290 1291 case AT_CDB: /* Got a CDB */ 1292 case AT_PHASE_ERROR: /* Bus Phase Sequence Error */ 1293 /* 1294 * Punt to platform specific layer. 1295 */ 1296 isp_async(isp, ISPASYNC_TARGET_ACTION, aep); 1297 break; 1298 1299 case AT_RESET: 1300 /* 1301 * A bus reset came along and blew away this command. Why 1302 * they do this in addition the async event code stuff, 1303 * I dunno. 1304 * 1305 * Ignore it because the async event will clear things 1306 * up for us. 1307 */ 1308 isp_prt(isp, ISP_LOGWARN, atior, lun, GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid)); 1309 break; 1310 1311 1312 default: 1313 isp_prt(isp, ISP_LOGERR, "Unknown ATIO status 0x%x from loopid %d for lun %d", aep->at_status, aep->at_iid, lun); 1314 (void) isp_target_put_atio(isp, aep); 1315 break; 1316 } 1317} 1318 1319static void 1320isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep) 1321{ 1322 int lun, iid; 1323 1324 if (ISP_CAP_SCCFW(isp)) { 1325 lun = aep->at_scclun; 1326 } else { 1327 lun = aep->at_lun; 1328 } 1329 1330 if (ISP_CAP_2KLOGIN(isp)) { 1331 iid = ((at2e_entry_t *)aep)->at_iid; 1332 } else { 1333 iid = aep->at_iid; 1334 } 1335 1336 /* 1337 * The firmware status (except for the QLTM_SVALID bit) indicates 1338 * why this ATIO was sent to us. 1339 * 1340 * If QLTM_SVALID is set, the firware has recommended Sense Data. 1341 * 1342 * If the DISCONNECTS DISABLED bit is set in the flags field, 1343 * we're still connected on the SCSI bus - i.e. the initiator 1344 * did not set DiscPriv in the identify message. We don't care 1345 * about this so it's ignored. 1346 */ 1347 1348 switch (aep->at_status & ~QLTM_SVALID) { 1349 case AT_PATH_INVALID: 1350 /* 1351 * ATIO rejected by the firmware due to disabled lun. 1352 */ 1353 isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for disabled lun %d", lun); 1354 break; 1355 case AT_NOCAP: 1356 /* 1357 * Requested Capability not available 1358 * We sent an ATIO that overflowed the firmware's 1359 * command resource count. 1360 */ 1361 isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for lun %d- command count overflow", lun); 1362 break; 1363 1364 case AT_BDR_MSG: 1365 /* 1366 * If we send an ATIO to the firmware to increment 1367 * its command resource count, and the firmware is 1368 * recovering from a Bus Device Reset, it returns 1369 * the ATIO with this status. We set the command 1370 * resource count in the Enable Lun entry and no 1371 * not increment it. Therefore we should never get 1372 * this status here. 1373 */ 1374 isp_prt(isp, ISP_LOGERR, atiocope, lun, 0); 1375 break; 1376 1377 case AT_CDB: /* Got a CDB */ 1378 /* 1379 * Punt to platform specific layer. 1380 */ 1381 isp_async(isp, ISPASYNC_TARGET_ACTION, aep); 1382 break; 1383 1384 case AT_RESET: 1385 /* 1386 * A bus reset came along an blew away this command. Why 1387 * they do this in addition the async event code stuff, 1388 * I dunno. 1389 * 1390 * Ignore it because the async event will clear things 1391 * up for us. 1392 */ 1393 isp_prt(isp, ISP_LOGERR, atior, lun, iid, 0); 1394 break; 1395 1396 1397 default: 1398 isp_prt(isp, ISP_LOGERR, "Unknown ATIO2 status 0x%x from loopid %d for lun %d", aep->at_status, iid, lun); 1399 (void) isp_target_put_atio(isp, aep); 1400 break; 1401 } 1402} 1403 1404static void 1405isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct) 1406{ 1407 void *xs; 1408 int pl = ISP_LOGTDEBUG2; 1409 char *fmsg = NULL; 1410 1411 if (ct->ct_syshandle) { 1412 xs = isp_find_xs_tgt(isp, ct->ct_syshandle); 1413 if (xs == NULL) { 1414 pl = ISP_LOGALL; 1415 } 1416 } else { 1417 xs = NULL; 1418 } 1419 1420 switch (ct->ct_status & ~QLTM_SVALID) { 1421 case CT_OK: 1422 /* 1423 * There are generally 3 possibilities as to why we'd get 1424 * this condition: 1425 * We disconnected after receiving a CDB. 1426 * We sent or received data. 1427 * We sent status & command complete. 1428 */ 1429 1430 if (ct->ct_flags & CT_SENDSTATUS) { 1431 break; 1432 } else if ((ct->ct_flags & CT_DATAMASK) == CT_NO_DATA) { 1433 /* 1434 * Nothing to do in this case. 1435 */ 1436 isp_prt(isp, pl, "CTIO- iid %d disconnected OK", ct->ct_iid); 1437 return; 1438 } 1439 break; 1440 1441 case CT_BDR_MSG: 1442 /* 1443 * Bus Device Reset message received or the SCSI Bus has 1444 * been Reset; the firmware has gone to Bus Free. 1445 * 1446 * The firmware generates an async mailbox interrupt to 1447 * notify us of this and returns outstanding CTIOs with this 1448 * status. These CTIOs are handled in that same way as 1449 * CT_ABORTED ones, so just fall through here. 1450 */ 1451 fmsg = "Bus Device Reset"; 1452 /*FALLTHROUGH*/ 1453 case CT_RESET: 1454 if (fmsg == NULL) 1455 fmsg = "Bus Reset"; 1456 /*FALLTHROUGH*/ 1457 case CT_ABORTED: 1458 /* 1459 * When an Abort message is received the firmware goes to 1460 * Bus Free and returns all outstanding CTIOs with the status 1461 * set, then sends us an Immediate Notify entry. 1462 */ 1463 if (fmsg == NULL) 1464 fmsg = "ABORT TAG message sent by Initiator"; 1465 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO destroyed by %s", fmsg); 1466 break; 1467 1468 case CT_INVAL: 1469 /* 1470 * CTIO rejected by the firmware due to disabled lun. 1471 * "Cannot Happen". 1472 */ 1473 isp_prt(isp, ISP_LOGERR, "Firmware rejected CTIO for disabled lun %d", ct->ct_lun); 1474 break; 1475 1476 case CT_NOPATH: 1477 /* 1478 * CTIO rejected by the firmware due "no path for the 1479 * nondisconnecting nexus specified". This means that 1480 * we tried to access the bus while a non-disconnecting 1481 * command is in process. 1482 */ 1483 isp_prt(isp, ISP_LOGERR, "Firmware rejected CTIO for bad nexus %d/%d/%d", ct->ct_iid, ct->ct_tgt, ct->ct_lun); 1484 break; 1485 1486 case CT_RSELTMO: 1487 fmsg = "Reselection"; 1488 /*FALLTHROUGH*/ 1489 case CT_TIMEOUT: 1490 if (fmsg == NULL) 1491 fmsg = "Command"; 1492 isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg); 1493 break; 1494 1495 case CT_PANIC: 1496 if (fmsg == NULL) 1497 fmsg = "Unrecoverable Error"; 1498 /*FALLTHROUGH*/ 1499 case CT_ERR: 1500 if (fmsg == NULL) 1501 fmsg = "Completed with Error"; 1502 /*FALLTHROUGH*/ 1503 case CT_PHASE_ERROR: 1504 if (fmsg == NULL) 1505 fmsg = "Phase Sequence Error"; 1506 /*FALLTHROUGH*/ 1507 case CT_TERMINATED: 1508 if (fmsg == NULL) 1509 fmsg = "terminated by TERMINATE TRANSFER"; 1510 /*FALLTHROUGH*/ 1511 case CT_NOACK: 1512 if (fmsg == NULL) 1513 fmsg = "unacknowledged Immediate Notify pending"; 1514 isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg); 1515 break; 1516 default: 1517 isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x", ct->ct_status & ~QLTM_SVALID); 1518 break; 1519 } 1520 1521 if (xs == NULL) { 1522 /* 1523 * There may be more than one CTIO for a data transfer, 1524 * or this may be a status CTIO we're not monitoring. 1525 * 1526 * The assumption is that they'll all be returned in the 1527 * order we got them. 1528 */ 1529 if (ct->ct_syshandle == 0) { 1530 if ((ct->ct_flags & CT_SENDSTATUS) == 0) { 1531 isp_prt(isp, pl, "intermediate CTIO completed ok"); 1532 } else { 1533 isp_prt(isp, pl, "unmonitored CTIO completed ok"); 1534 } 1535 } else { 1536 isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); 1537 } 1538 } else { 1539 /* 1540 * Final CTIO completed. Release DMA resources and 1541 * notify platform dependent layers. 1542 */ 1543 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) { 1544 ISP_DMAFREE(isp, xs, ct->ct_syshandle); 1545 } 1546 isp_prt(isp, pl, "final CTIO complete"); 1547 /* 1548 * The platform layer will destroy the handle if appropriate. 1549 */ 1550 isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1551 } 1552} 1553 1554static void 1555isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct) 1556{ 1557 void *xs; 1558 int pl = ISP_LOGTDEBUG2; 1559 char *fmsg = NULL; 1560 1561 if (ct->ct_syshandle) { 1562 xs = isp_find_xs_tgt(isp, ct->ct_syshandle); 1563 if (xs == NULL) { 1564 pl = ISP_LOGALL; 1565 } 1566 } else { 1567 xs = NULL; 1568 } 1569 1570 switch (ct->ct_status & ~QLTM_SVALID) { 1571 case CT_BUS_ERROR: 1572 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error"); 1573 /* FALL Through */ 1574 case CT_DATA_OVER: 1575 case CT_DATA_UNDER: 1576 case CT_OK: 1577 /* 1578 * There are generally 2 possibilities as to why we'd get 1579 * this condition: 1580 * We sent or received data. 1581 * We sent status & command complete. 1582 */ 1583 1584 break; 1585 1586 case CT_BDR_MSG: 1587 /* 1588 * Target Reset function received. 1589 * 1590 * The firmware generates an async mailbox interrupt to 1591 * notify us of this and returns outstanding CTIOs with this 1592 * status. These CTIOs are handled in that same way as 1593 * CT_ABORTED ones, so just fall through here. 1594 */ 1595 fmsg = "TARGET RESET"; 1596 /*FALLTHROUGH*/ 1597 case CT_RESET: 1598 if (fmsg == NULL) 1599 fmsg = "LIP Reset"; 1600 /*FALLTHROUGH*/ 1601 case CT_ABORTED: 1602 /* 1603 * When an Abort message is received the firmware goes to 1604 * Bus Free and returns all outstanding CTIOs with the status 1605 * set, then sends us an Immediate Notify entry. 1606 */ 1607 if (fmsg == NULL) { 1608 fmsg = "ABORT"; 1609 } 1610 1611 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); 1612 break; 1613 1614 case CT_INVAL: 1615 /* 1616 * CTIO rejected by the firmware - invalid data direction. 1617 */ 1618 isp_prt(isp, ISP_LOGERR, "CTIO2 had wrong data direction"); 1619 break; 1620 1621 case CT_RSELTMO: 1622 fmsg = "failure to reconnect to initiator"; 1623 /*FALLTHROUGH*/ 1624 case CT_TIMEOUT: 1625 if (fmsg == NULL) 1626 fmsg = "command"; 1627 isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg); 1628 break; 1629 1630 case CT_ERR: 1631 fmsg = "Completed with Error"; 1632 /*FALLTHROUGH*/ 1633 case CT_LOGOUT: 1634 if (fmsg == NULL) 1635 fmsg = "Port Logout"; 1636 /*FALLTHROUGH*/ 1637 case CT_PORTUNAVAIL: 1638 if (fmsg == NULL) 1639 fmsg = "Port not available"; 1640 /*FALLTHROUGH*/ 1641 case CT_PORTCHANGED: 1642 if (fmsg == NULL) 1643 fmsg = "Port Changed"; 1644 /*FALLTHROUGH*/ 1645 case CT_NOACK: 1646 if (fmsg == NULL) 1647 fmsg = "unacknowledged Immediate Notify pending"; 1648 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg); 1649 break; 1650 1651 case CT_INVRXID: 1652 /* 1653 * CTIO rejected by the firmware because an invalid RX_ID. 1654 * Just print a message. 1655 */ 1656 isp_prt(isp, ISP_LOGWARN, "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid); 1657 break; 1658 1659 default: 1660 isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x", ct->ct_status & ~QLTM_SVALID); 1661 break; 1662 } 1663 1664 if (xs == NULL) { 1665 /* 1666 * There may be more than one CTIO for a data transfer, 1667 * or this may be a status CTIO we're not monitoring. 1668 * 1669 * The assumption is that they'll all be returned in the 1670 * order we got them. 1671 */ 1672 if (ct->ct_syshandle == 0) { 1673 if ((ct->ct_flags & CT2_SENDSTATUS) == 0) { 1674 isp_prt(isp, pl, "intermediate CTIO completed ok"); 1675 } else { 1676 isp_prt(isp, pl, "unmonitored CTIO completed ok"); 1677 } 1678 } else { 1679 isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); 1680 } 1681 } else { 1682 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) { 1683 ISP_DMAFREE(isp, xs, ct->ct_syshandle); 1684 } 1685 if (ct->ct_flags & CT2_SENDSTATUS) { 1686 /* 1687 * Sent status and command complete. 1688 * 1689 * We're now really done with this command, so we 1690 * punt to the platform dependent layers because 1691 * only there can we do the appropriate command 1692 * complete thread synchronization. 1693 */ 1694 isp_prt(isp, pl, "status CTIO complete"); 1695 } else { 1696 /* 1697 * Final CTIO completed. Release DMA resources and 1698 * notify platform dependent layers. 1699 */ 1700 isp_prt(isp, pl, "data CTIO complete"); 1701 } 1702 isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1703 /* 1704 * The platform layer will destroy the handle if appropriate. 1705 */ 1706 } 1707} 1708 1709static void 1710isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct) 1711{ 1712 void *xs; 1713 int pl = ISP_LOGTDEBUG2; 1714 char *fmsg = NULL; 1715 1716 if (ct->ct_syshandle) { 1717 xs = isp_find_xs_tgt(isp, ct->ct_syshandle); 1718 if (xs == NULL) { 1719 pl = ISP_LOGALL; 1720 } 1721 } else { 1722 xs = NULL; 1723 } 1724 1725 switch (ct->ct_nphdl) { 1726 case CT7_BUS_ERROR: 1727 isp_prt(isp, ISP_LOGERR, "PCI DMA Bus Error"); 1728 /* FALL Through */ 1729 case CT7_DATA_OVER: 1730 case CT7_DATA_UNDER: 1731 case CT7_OK: 1732 /* 1733 * There are generally 2 possibilities as to why we'd get 1734 * this condition: 1735 * We sent or received data. 1736 * We sent status & command complete. 1737 */ 1738 1739 break; 1740 1741 case CT7_RESET: 1742 if (fmsg == NULL) { 1743 fmsg = "LIP Reset"; 1744 } 1745 /*FALLTHROUGH*/ 1746 case CT7_ABORTED: 1747 /* 1748 * When an Abort message is received the firmware goes to 1749 * Bus Free and returns all outstanding CTIOs with the status 1750 * set, then sends us an Immediate Notify entry. 1751 */ 1752 if (fmsg == NULL) { 1753 fmsg = "ABORT"; 1754 } 1755 isp_prt(isp, ISP_LOGTDEBUG0, "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); 1756 break; 1757 1758 case CT7_TIMEOUT: 1759 if (fmsg == NULL) { 1760 fmsg = "command"; 1761 } 1762 isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg); 1763 break; 1764 1765 case CT7_ERR: 1766 fmsg = "Completed with Error"; 1767 /*FALLTHROUGH*/ 1768 case CT7_LOGOUT: 1769 if (fmsg == NULL) { 1770 fmsg = "Port Logout"; 1771 } 1772 /*FALLTHROUGH*/ 1773 case CT7_PORTUNAVAIL: 1774 if (fmsg == NULL) { 1775 fmsg = "Port not available"; 1776 } 1777 /*FALLTHROUGH*/ 1778 case CT7_PORTCHANGED: 1779 if (fmsg == NULL) { 1780 fmsg = "Port Changed"; 1781 } 1782 isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg); 1783 break; 1784 1785 case CT7_INVRXID: 1786 /* 1787 * CTIO rejected by the firmware because an invalid RX_ID. 1788 * Just print a message. 1789 */ 1790 isp_prt(isp, ISP_LOGWARN, "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid); 1791 break; 1792 1793 case CT7_REASSY_ERR: 1794 isp_prt(isp, ISP_LOGWARN, "reassembly error"); 1795 break; 1796 1797 case CT7_SRR:
|
1774 isp_prt(isp, ISP_LOGWARN, "SRR received");
| 1798 isp_prt(isp, ISP_LOGTDEBUG0, "SRR received");
|
1775 break; 1776 1777 default: 1778 isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x", ct->ct_nphdl); 1779 break; 1780 } 1781 1782 if (xs == NULL) { 1783 /* 1784 * There may be more than one CTIO for a data transfer, 1785 * or this may be a status CTIO we're not monitoring. 1786 * 1787 * The assumption is that they'll all be returned in the 1788 * order we got them. 1789 */ 1790 if (ct->ct_syshandle == 0) { 1791 if (ct->ct_flags & CT7_TERMINATE) {
| 1799 break; 1800 1801 default: 1802 isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x", ct->ct_nphdl); 1803 break; 1804 } 1805 1806 if (xs == NULL) { 1807 /* 1808 * There may be more than one CTIO for a data transfer, 1809 * or this may be a status CTIO we're not monitoring. 1810 * 1811 * The assumption is that they'll all be returned in the 1812 * order we got them. 1813 */ 1814 if (ct->ct_syshandle == 0) { 1815 if (ct->ct_flags & CT7_TERMINATE) {
|
1792 isp_prt(isp, ISP_LOGINFO, "termination of 0x%x complete", ct->ct_rxid);
| 1816 isp_prt(isp, ISP_LOGINFO, "termination of [RX_ID 0x%x] complete", ct->ct_rxid);
|
1793 } else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) { 1794 isp_prt(isp, pl, "intermediate CTIO completed ok"); 1795 } else { 1796 isp_prt(isp, pl, "unmonitored CTIO completed ok"); 1797 } 1798 } else { 1799 isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_nphdl); 1800 } 1801 } else { 1802 if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) { 1803 ISP_DMAFREE(isp, xs, ct->ct_syshandle); 1804 } 1805 if (ct->ct_flags & CT7_SENDSTATUS) { 1806 /* 1807 * Sent status and command complete. 1808 * 1809 * We're now really done with this command, so we 1810 * punt to the platform dependent layers because 1811 * only there can we do the appropriate command 1812 * complete thread synchronization. 1813 */ 1814 isp_prt(isp, pl, "status CTIO complete"); 1815 } else { 1816 /* 1817 * Final CTIO completed. Release DMA resources and 1818 * notify platform dependent layers. 1819 */ 1820 isp_prt(isp, pl, "data CTIO complete"); 1821 } 1822 isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1823 /* 1824 * The platform layer will destroy the handle if appropriate. 1825 */ 1826 } 1827} 1828 1829static void 1830isp_handle_24xx_inotify(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx) 1831{ 1832 uint8_t ochan, chan, lochan, hichan; 1833 1834 /* 1835 * Check to see whether we got a wildcard channel. 1836 * If so, we have to iterate over all channels. 1837 */ 1838 ochan = chan = ISP_GET_VPIDX(isp, inot_24xx->in_vpidx); 1839 if (chan == 0xff) { 1840 lochan = 0; 1841 hichan = isp->isp_nchan; 1842 } else { 1843 if (chan >= isp->isp_nchan) { 1844 char buf[64]; 1845 ISP_SNPRINTF(buf, sizeof buf, "%s: bad channel %d for status 0x%x", __func__, chan, inot_24xx->in_status); 1846 isp_print_bytes(isp, buf, QENTRY_LEN, inot_24xx);
| 1817 } else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) { 1818 isp_prt(isp, pl, "intermediate CTIO completed ok"); 1819 } else { 1820 isp_prt(isp, pl, "unmonitored CTIO completed ok"); 1821 } 1822 } else { 1823 isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_nphdl); 1824 } 1825 } else { 1826 if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) { 1827 ISP_DMAFREE(isp, xs, ct->ct_syshandle); 1828 } 1829 if (ct->ct_flags & CT7_SENDSTATUS) { 1830 /* 1831 * Sent status and command complete. 1832 * 1833 * We're now really done with this command, so we 1834 * punt to the platform dependent layers because 1835 * only there can we do the appropriate command 1836 * complete thread synchronization. 1837 */ 1838 isp_prt(isp, pl, "status CTIO complete"); 1839 } else { 1840 /* 1841 * Final CTIO completed. Release DMA resources and 1842 * notify platform dependent layers. 1843 */ 1844 isp_prt(isp, pl, "data CTIO complete"); 1845 } 1846 isp_async(isp, ISPASYNC_TARGET_ACTION, ct); 1847 /* 1848 * The platform layer will destroy the handle if appropriate. 1849 */ 1850 } 1851} 1852 1853static void 1854isp_handle_24xx_inotify(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx) 1855{ 1856 uint8_t ochan, chan, lochan, hichan; 1857 1858 /* 1859 * Check to see whether we got a wildcard channel. 1860 * If so, we have to iterate over all channels. 1861 */ 1862 ochan = chan = ISP_GET_VPIDX(isp, inot_24xx->in_vpidx); 1863 if (chan == 0xff) { 1864 lochan = 0; 1865 hichan = isp->isp_nchan; 1866 } else { 1867 if (chan >= isp->isp_nchan) { 1868 char buf[64]; 1869 ISP_SNPRINTF(buf, sizeof buf, "%s: bad channel %d for status 0x%x", __func__, chan, inot_24xx->in_status); 1870 isp_print_bytes(isp, buf, QENTRY_LEN, inot_24xx);
|
1847 (void) isp_notify_ack(isp, inot_24xx);
| 1871 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_24xx);
|
1848 return; 1849 } 1850 lochan = chan; 1851 hichan = chan + 1; 1852 } 1853 isp_prt(isp, ISP_LOGTDEBUG1, "%s: Immediate Notify Channels %d..%d status=0x%x seqid=0x%x", __func__, lochan, hichan-1, inot_24xx->in_status, inot_24xx->in_rxid); 1854 for (chan = lochan; chan < hichan; chan++) { 1855 switch (inot_24xx->in_status) { 1856 case IN24XX_LIP_RESET: 1857 case IN24XX_LINK_RESET: 1858 case IN24XX_PORT_LOGOUT: 1859 case IN24XX_PORT_CHANGED: 1860 case IN24XX_LINK_FAILED: 1861 case IN24XX_SRR_RCVD: 1862 case IN24XX_ELS_RCVD:
| 1872 return; 1873 } 1874 lochan = chan; 1875 hichan = chan + 1; 1876 } 1877 isp_prt(isp, ISP_LOGTDEBUG1, "%s: Immediate Notify Channels %d..%d status=0x%x seqid=0x%x", __func__, lochan, hichan-1, inot_24xx->in_status, inot_24xx->in_rxid); 1878 for (chan = lochan; chan < hichan; chan++) { 1879 switch (inot_24xx->in_status) { 1880 case IN24XX_LIP_RESET: 1881 case IN24XX_LINK_RESET: 1882 case IN24XX_PORT_LOGOUT: 1883 case IN24XX_PORT_CHANGED: 1884 case IN24XX_LINK_FAILED: 1885 case IN24XX_SRR_RCVD: 1886 case IN24XX_ELS_RCVD:
|
| 1887 inot_24xx->in_reserved = 0; /* clear this for later usage */
|
1863 inot_24xx->in_vpidx = chan; 1864 isp_async(isp, ISPASYNC_TARGET_ACTION, inot_24xx); 1865 break; 1866 default: 1867 isp_prt(isp, ISP_LOGINFO, "%s: unhandled status (0x%x) for chan %d", __func__, inot_24xx->in_status, chan);
| 1888 inot_24xx->in_vpidx = chan; 1889 isp_async(isp, ISPASYNC_TARGET_ACTION, inot_24xx); 1890 break; 1891 default: 1892 isp_prt(isp, ISP_LOGINFO, "%s: unhandled status (0x%x) for chan %d", __func__, inot_24xx->in_status, chan);
|
1868 (void) isp_notify_ack(isp, inot_24xx);
| 1893 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_24xx);
|
1869 break; 1870 } 1871 } 1872 inot_24xx->in_vpidx = ochan; 1873} 1874#endif
| 1894 break; 1895 } 1896 } 1897 inot_24xx->in_vpidx = ochan; 1898} 1899#endif
|