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