1 /* $NetBSD: iopsp.c,v 1.17 2002/12/06 11:22:25 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Raw SCSI device support for I2O. IOPs present SCSI devices individually; 41 * we group them by controlling port. 42 */ 43 44 #include <sys/cdefs.h> 45 __KERNEL_RCSID(0, "$NetBSD: iopsp.c,v 1.17 2002/12/06 11:22:25 ad Exp $"); 46 47 #include "opt_i2o.h" 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/kernel.h> 52 #include <sys/device.h> 53 #include <sys/queue.h> 54 #include <sys/proc.h> 55 #include <sys/buf.h> 56 #include <sys/endian.h> 57 #include <sys/malloc.h> 58 #include <sys/scsiio.h> 59 #include <sys/lock.h> 60 61 #include <machine/bswap.h> 62 #include <machine/bus.h> 63 64 #include <dev/scsipi/scsi_all.h> 65 #include <dev/scsipi/scsi_disk.h> 66 #include <dev/scsipi/scsipi_all.h> 67 #include <dev/scsipi/scsiconf.h> 68 #include <dev/scsipi/scsi_message.h> 69 70 #include <dev/i2o/i2o.h> 71 #include <dev/i2o/iopio.h> 72 #include <dev/i2o/iopvar.h> 73 #include <dev/i2o/iopspvar.h> 74 75 static void iopsp_adjqparam(struct device *, int); 76 static void iopsp_attach(struct device *, struct device *, void *); 77 static void iopsp_intr(struct device *, struct iop_msg *, void *); 78 static int iopsp_ioctl(struct scsipi_channel *, u_long, 79 caddr_t, int, struct proc *); 80 static int iopsp_match(struct device *, struct cfdata *, void *); 81 static int iopsp_rescan(struct iopsp_softc *); 82 static int iopsp_reconfig(struct device *); 83 static void iopsp_scsipi_request(struct scsipi_channel *, 84 scsipi_adapter_req_t, void *); 85 86 CFATTACH_DECL(iopsp, sizeof(struct iopsp_softc), 87 iopsp_match, iopsp_attach, NULL, NULL); 88 89 /* 90 * Match a supported device. 91 */ 92 static int 93 iopsp_match(struct device *parent, struct cfdata *match, void *aux) 94 { 95 struct iop_attach_args *ia; 96 struct { 97 struct i2o_param_op_results pr; 98 struct i2o_param_read_results prr; 99 struct i2o_param_hba_ctlr_info ci; 100 } __attribute__ ((__packed__)) param; 101 102 ia = aux; 103 104 if (ia->ia_class != I2O_CLASS_BUS_ADAPTER_PORT) 105 return (0); 106 107 if (iop_field_get_all((struct iop_softc *)parent, ia->ia_tid, 108 I2O_PARAM_HBA_CTLR_INFO, ¶m, sizeof(param), NULL) != 0) 109 return (0); 110 111 return (param.ci.bustype == I2O_HBA_BUS_SCSI || 112 param.ci.bustype == I2O_HBA_BUS_FCA); 113 } 114 115 /* 116 * Attach a supported device. 117 */ 118 static void 119 iopsp_attach(struct device *parent, struct device *self, void *aux) 120 { 121 struct iop_attach_args *ia; 122 struct iopsp_softc *sc; 123 struct iop_softc *iop; 124 struct { 125 struct i2o_param_op_results pr; 126 struct i2o_param_read_results prr; 127 union { 128 struct i2o_param_hba_ctlr_info ci; 129 struct i2o_param_hba_scsi_ctlr_info sci; 130 struct i2o_param_hba_scsi_port_info spi; 131 } p; 132 } __attribute__ ((__packed__)) param; 133 int fc, rv; 134 #ifdef I2OVERBOSE 135 int size; 136 #endif 137 138 ia = (struct iop_attach_args *)aux; 139 sc = (struct iopsp_softc *)self; 140 iop = (struct iop_softc *)parent; 141 142 /* Register us as an initiator. */ 143 sc->sc_ii.ii_dv = self; 144 sc->sc_ii.ii_intr = iopsp_intr; 145 sc->sc_ii.ii_flags = 0; 146 sc->sc_ii.ii_tid = ia->ia_tid; 147 sc->sc_ii.ii_reconfig = iopsp_reconfig; 148 sc->sc_ii.ii_adjqparam = iopsp_adjqparam; 149 iop_initiator_register(iop, &sc->sc_ii); 150 151 rv = iop_field_get_all(iop, ia->ia_tid, I2O_PARAM_HBA_CTLR_INFO, 152 ¶m, sizeof(param), NULL); 153 if (rv != 0) 154 goto bad; 155 156 fc = (param.p.ci.bustype == I2O_HBA_BUS_FCA); 157 158 /* 159 * Say what the device is. If we can find out what the controling 160 * device is, say what that is too. 161 */ 162 printf(": SCSI port"); 163 iop_print_ident(iop, ia->ia_tid); 164 printf("\n"); 165 166 rv = iop_field_get_all(iop, ia->ia_tid, I2O_PARAM_HBA_SCSI_CTLR_INFO, 167 ¶m, sizeof(param), NULL); 168 if (rv != 0) 169 goto bad; 170 171 #ifdef I2OVERBOSE 172 printf("%s: ", sc->sc_dv.dv_xname); 173 if (fc) 174 printf("FC"); 175 else 176 printf("%d-bit", param.p.sci.maxdatawidth); 177 printf(", max sync rate %dMHz, initiator ID %d\n", 178 (u_int32_t)le64toh(param.p.sci.maxsyncrate) / 1000, 179 le32toh(param.p.sci.initiatorid)); 180 #endif 181 182 sc->sc_adapter.adapt_dev = &sc->sc_dv; 183 sc->sc_adapter.adapt_nchannels = 1; 184 sc->sc_adapter.adapt_openings = 1; 185 sc->sc_adapter.adapt_max_periph = 1; 186 sc->sc_adapter.adapt_ioctl = iopsp_ioctl; 187 sc->sc_adapter.adapt_minphys = minphys; 188 sc->sc_adapter.adapt_request = iopsp_scsipi_request; 189 190 memset(&sc->sc_channel, 0, sizeof(sc->sc_channel)); 191 sc->sc_channel.chan_adapter = &sc->sc_adapter; 192 sc->sc_channel.chan_bustype = &scsi_bustype; 193 sc->sc_channel.chan_channel = 0; 194 sc->sc_channel.chan_ntargets = fc ? 195 IOPSP_MAX_FC_TARGET : param.p.sci.maxdatawidth; 196 sc->sc_channel.chan_nluns = IOPSP_MAX_LUN; 197 sc->sc_channel.chan_id = le32toh(param.p.sci.initiatorid); 198 sc->sc_channel.chan_flags = SCSIPI_CHAN_NOSETTLE; 199 200 #ifdef I2OVERBOSE 201 /* 202 * Allocate the target map. Currently used for informational 203 * purposes only. 204 */ 205 size = sc->sc_channel.chan_ntargets * sizeof(struct iopsp_target); 206 sc->sc_targetmap = malloc(size, M_DEVBUF, M_NOWAIT|M_ZERO); 207 #endif 208 209 /* Build the two maps, and attach to scsipi. */ 210 if (iopsp_reconfig(self) != 0) { 211 printf("%s: configure failed\n", sc->sc_dv.dv_xname); 212 goto bad; 213 } 214 config_found(self, &sc->sc_channel, scsiprint); 215 return; 216 217 bad: 218 iop_initiator_unregister(iop, &sc->sc_ii); 219 } 220 221 /* 222 * Scan the LCT to determine which devices we control, and enter them into 223 * the maps. 224 */ 225 static int 226 iopsp_reconfig(struct device *dv) 227 { 228 struct iopsp_softc *sc; 229 struct iop_softc *iop; 230 struct i2o_lct_entry *le; 231 struct scsipi_channel *sc_chan; 232 struct { 233 struct i2o_param_op_results pr; 234 struct i2o_param_read_results prr; 235 struct i2o_param_scsi_device_info sdi; 236 } __attribute__ ((__packed__)) param; 237 u_int tid, nent, i, targ, lun, size, s, rv, bptid; 238 u_short *tidmap; 239 #ifdef I2OVERBOSE 240 struct iopsp_target *it; 241 int syncrate; 242 #endif 243 244 sc = (struct iopsp_softc *)dv; 245 iop = (struct iop_softc *)sc->sc_dv.dv_parent; 246 sc_chan = &sc->sc_channel; 247 248 /* Anything to do? */ 249 if (iop->sc_chgind == sc->sc_chgind) 250 return (0); 251 252 /* 253 * Allocate memory for the target/LUN -> TID map. Use zero to 254 * denote absent targets (zero is the TID of the I2O executive, 255 * and we never address that here). 256 */ 257 size = sc_chan->chan_ntargets * (IOPSP_MAX_LUN) * sizeof(u_short); 258 if ((tidmap = malloc(size, M_DEVBUF, M_WAITOK|M_ZERO)) == NULL) 259 return (ENOMEM); 260 261 #ifdef I2OVERBOSE 262 for (i = 0; i < sc_chan->chan_ntargets; i++) 263 sc->sc_targetmap[i].it_flags &= ~IT_PRESENT; 264 #endif 265 266 /* 267 * A quick hack to handle Intel's stacked bus port arrangement. 268 */ 269 bptid = sc->sc_ii.ii_tid; 270 nent = iop->sc_nlctent; 271 for (le = iop->sc_lct->entry; nent != 0; nent--, le++) 272 if ((le16toh(le->classid) & 4095) == 273 I2O_CLASS_BUS_ADAPTER_PORT && 274 (le32toh(le->usertid) & 4095) == bptid) { 275 bptid = le16toh(le->localtid) & 4095; 276 break; 277 } 278 279 nent = iop->sc_nlctent; 280 for (i = 0, le = iop->sc_lct->entry; i < nent; i++, le++) { 281 if ((le16toh(le->classid) & 4095) != I2O_CLASS_SCSI_PERIPHERAL) 282 continue; 283 if (((le32toh(le->usertid) >> 12) & 4095) != bptid) 284 continue; 285 tid = le16toh(le->localtid) & 4095; 286 287 rv = iop_field_get_all(iop, tid, I2O_PARAM_SCSI_DEVICE_INFO, 288 ¶m, sizeof(param), NULL); 289 if (rv != 0) 290 continue; 291 targ = le32toh(param.sdi.identifier); 292 lun = param.sdi.luninfo[1]; 293 #if defined(DIAGNOSTIC) || defined(I2ODEBUG) 294 if (targ >= sc_chan->chan_ntargets || 295 lun >= sc_chan->chan_nluns) { 296 printf("%s: target %d,%d (tid %d): bad target/LUN\n", 297 sc->sc_dv.dv_xname, targ, lun, tid); 298 continue; 299 } 300 #endif 301 302 #ifdef I2OVERBOSE 303 /* 304 * If we've already described this target, and nothing has 305 * changed, then don't describe it again. 306 */ 307 it = &sc->sc_targetmap[targ]; 308 it->it_flags |= IT_PRESENT; 309 syncrate = ((int)le64toh(param.sdi.negsyncrate) + 500) / 1000; 310 if (it->it_width != param.sdi.negdatawidth || 311 it->it_offset != param.sdi.negoffset || 312 it->it_syncrate != syncrate) { 313 it->it_width = param.sdi.negdatawidth; 314 it->it_offset = param.sdi.negoffset; 315 it->it_syncrate = syncrate; 316 317 printf("%s: target %d (tid %d): %d-bit, ", 318 sc->sc_dv.dv_xname, targ, tid, it->it_width); 319 if (it->it_syncrate == 0) 320 printf("asynchronous\n"); 321 else 322 printf("synchronous at %dMHz, offset 0x%x\n", 323 it->it_syncrate, it->it_offset); 324 } 325 #endif 326 327 /* Ignore the device if it's in use by somebody else. */ 328 if ((le32toh(le->usertid) & 4095) != I2O_TID_NONE) { 329 #ifdef I2OVERBOSE 330 if (sc->sc_tidmap == NULL || 331 IOPSP_TIDMAP(sc->sc_tidmap, targ, lun) != 332 IOPSP_TID_INUSE) 333 printf("%s: target %d,%d (tid %d): in use by" 334 " tid %d\n", sc->sc_dv.dv_xname, 335 targ, lun, tid, 336 le32toh(le->usertid) & 4095); 337 #endif 338 IOPSP_TIDMAP(tidmap, targ, lun) = IOPSP_TID_INUSE; 339 } else 340 IOPSP_TIDMAP(tidmap, targ, lun) = (u_short)tid; 341 } 342 343 #ifdef I2OVERBOSE 344 for (i = 0; i < sc_chan->chan_ntargets; i++) 345 if ((sc->sc_targetmap[i].it_flags & IT_PRESENT) == 0) 346 sc->sc_targetmap[i].it_width = 0; 347 #endif 348 349 /* Swap in the new map and return. */ 350 s = splbio(); 351 if (sc->sc_tidmap != NULL) 352 free(sc->sc_tidmap, M_DEVBUF); 353 sc->sc_tidmap = tidmap; 354 splx(s); 355 sc->sc_chgind = iop->sc_chgind; 356 return (0); 357 } 358 359 /* 360 * Re-scan the bus; to be called from a higher level (e.g. scsipi). 361 */ 362 static int 363 iopsp_rescan(struct iopsp_softc *sc) 364 { 365 struct iop_softc *iop; 366 struct iop_msg *im; 367 struct i2o_hba_bus_scan mf; 368 int rv; 369 370 iop = (struct iop_softc *)sc->sc_dv.dv_parent; 371 372 rv = lockmgr(&iop->sc_conflock, LK_EXCLUSIVE, NULL); 373 if (rv != 0) { 374 #ifdef I2ODEBUG 375 printf("iopsp_rescan: unable to acquire lock\n"); 376 #endif 377 return (rv); 378 } 379 380 im = iop_msg_alloc(iop, IM_WAIT); 381 382 mf.msgflags = I2O_MSGFLAGS(i2o_hba_bus_scan); 383 mf.msgfunc = I2O_MSGFUNC(sc->sc_ii.ii_tid, I2O_HBA_BUS_SCAN); 384 mf.msgictx = sc->sc_ii.ii_ictx; 385 mf.msgtctx = im->im_tctx; 386 387 rv = iop_msg_post(iop, im, &mf, 5*60*1000); 388 iop_msg_free(iop, im); 389 if (rv != 0) 390 printf("%s: bus rescan failed (error %d)\n", 391 sc->sc_dv.dv_xname, rv); 392 393 if ((rv = iop_lct_get(iop)) == 0) 394 rv = iopsp_reconfig(&sc->sc_dv); 395 396 lockmgr(&iop->sc_conflock, LK_RELEASE, NULL); 397 return (rv); 398 } 399 400 /* 401 * Start a SCSI command. 402 */ 403 static void 404 iopsp_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 405 void *arg) 406 { 407 struct scsipi_xfer *xs; 408 struct scsipi_periph *periph; 409 struct iopsp_softc *sc; 410 struct iop_msg *im; 411 struct iop_softc *iop; 412 struct i2o_scsi_scb_exec *mf; 413 int error, flags, tid, s; 414 u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)]; 415 416 sc = (void *)chan->chan_adapter->adapt_dev; 417 iop = (struct iop_softc *)sc->sc_dv.dv_parent; 418 419 switch (req) { 420 case ADAPTER_REQ_RUN_XFER: 421 xs = arg; 422 periph = xs->xs_periph; 423 flags = xs->xs_control; 424 425 SC_DEBUG(periph, SCSIPI_DB2, ("iopsp_scsi_request run_xfer\n")); 426 427 tid = IOPSP_TIDMAP(sc->sc_tidmap, periph->periph_target, 428 periph->periph_lun); 429 if (tid == IOPSP_TID_ABSENT || tid == IOPSP_TID_INUSE) { 430 xs->error = XS_SELTIMEOUT; 431 scsipi_done(xs); 432 return; 433 } 434 435 /* Need to reset the target? */ 436 if ((flags & XS_CTL_RESET) != 0) { 437 if (iop_simple_cmd(iop, tid, I2O_SCSI_DEVICE_RESET, 438 sc->sc_ii.ii_ictx, 1, 30*1000) != 0) { 439 #ifdef I2ODEBUG 440 printf("%s: reset failed\n", 441 sc->sc_dv.dv_xname); 442 #endif 443 xs->error = XS_DRIVER_STUFFUP; 444 } else 445 xs->error = XS_NOERROR; 446 447 scsipi_done(xs); 448 return; 449 } 450 451 #if defined(I2ODEBUG) || defined(SCSIDEBUG) 452 if (xs->cmdlen > sizeof(mf->cdb)) 453 panic("%s: CDB too large", sc->sc_dv.dv_xname); 454 #endif 455 456 im = iop_msg_alloc(iop, IM_POLL_INTR | 457 IM_NOSTATUS | ((flags & XS_CTL_POLL) != 0 ? IM_POLL : 0)); 458 im->im_dvcontext = xs; 459 460 mf = (struct i2o_scsi_scb_exec *)mb; 461 mf->msgflags = I2O_MSGFLAGS(i2o_scsi_scb_exec); 462 mf->msgfunc = I2O_MSGFUNC(tid, I2O_SCSI_SCB_EXEC); 463 mf->msgictx = sc->sc_ii.ii_ictx; 464 mf->msgtctx = im->im_tctx; 465 mf->flags = xs->cmdlen | I2O_SCB_FLAG_ENABLE_DISCONNECT | 466 I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE; 467 mf->datalen = xs->datalen; 468 memcpy(mf->cdb, xs->cmd, xs->cmdlen); 469 470 switch (xs->xs_tag_type) { 471 case MSG_ORDERED_Q_TAG: 472 mf->flags |= I2O_SCB_FLAG_ORDERED_QUEUE_TAG; 473 break; 474 case MSG_SIMPLE_Q_TAG: 475 mf->flags |= I2O_SCB_FLAG_SIMPLE_QUEUE_TAG; 476 break; 477 case MSG_HEAD_OF_Q_TAG: 478 mf->flags |= I2O_SCB_FLAG_HEAD_QUEUE_TAG; 479 break; 480 default: 481 break; 482 } 483 484 if (xs->datalen != 0) { 485 error = iop_msg_map_bio(iop, im, mb, xs->data, 486 xs->datalen, (flags & XS_CTL_DATA_OUT) == 0); 487 if (error) { 488 xs->error = XS_DRIVER_STUFFUP; 489 iop_msg_free(iop, im); 490 scsipi_done(xs); 491 return; 492 } 493 if ((flags & XS_CTL_DATA_IN) == 0) 494 mf->flags |= I2O_SCB_FLAG_XFER_TO_DEVICE; 495 else 496 mf->flags |= I2O_SCB_FLAG_XFER_FROM_DEVICE; 497 } 498 499 s = splbio(); 500 sc->sc_curqd++; 501 splx(s); 502 503 if (iop_msg_post(iop, im, mb, xs->timeout)) { 504 s = splbio(); 505 sc->sc_curqd--; 506 splx(s); 507 if (xs->datalen != 0) 508 iop_msg_unmap(iop, im); 509 iop_msg_free(iop, im); 510 xs->error = XS_DRIVER_STUFFUP; 511 scsipi_done(xs); 512 } 513 break; 514 515 case ADAPTER_REQ_GROW_RESOURCES: 516 /* 517 * Not supported. 518 */ 519 break; 520 521 case ADAPTER_REQ_SET_XFER_MODE: 522 /* 523 * The DDM takes care of this, and we can't modify its 524 * behaviour. 525 */ 526 break; 527 } 528 } 529 530 #ifdef notyet 531 /* 532 * Abort the specified I2O_SCSI_SCB_EXEC message and its associated SCB. 533 */ 534 static int 535 iopsp_scsi_abort(struct iopsp_softc *sc, int atid, struct iop_msg *aim) 536 { 537 struct iop_msg *im; 538 struct i2o_scsi_scb_abort mf; 539 struct iop_softc *iop; 540 int rv, s; 541 542 iop = (struct iop_softc *)sc->sc_dv.dv_parent; 543 im = iop_msg_alloc(iop, IM_POLL); 544 545 mf.msgflags = I2O_MSGFLAGS(i2o_scsi_scb_abort); 546 mf.msgfunc = I2O_MSGFUNC(atid, I2O_SCSI_SCB_ABORT); 547 mf.msgictx = sc->sc_ii.ii_ictx; 548 mf.msgtctx = im->im_tctx; 549 mf.tctxabort = aim->im_tctx; 550 551 s = splbio(); 552 rv = iop_msg_post(iop, im, &mf, 30000); 553 splx(s); 554 iop_msg_free(iop, im); 555 return (rv); 556 } 557 #endif 558 559 /* 560 * We have a message which has been processed and replied to by the IOP - 561 * deal with it. 562 */ 563 static void 564 iopsp_intr(struct device *dv, struct iop_msg *im, void *reply) 565 { 566 struct scsipi_xfer *xs; 567 struct iopsp_softc *sc; 568 struct i2o_scsi_reply *rb; 569 struct iop_softc *iop; 570 u_int sl; 571 572 sc = (struct iopsp_softc *)dv; 573 xs = (struct scsipi_xfer *)im->im_dvcontext; 574 iop = (struct iop_softc *)dv->dv_parent; 575 rb = reply; 576 577 SC_DEBUG(xs->xs_periph, SCSIPI_DB2, ("iopsp_intr\n")); 578 579 if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0) { 580 xs->error = XS_DRIVER_STUFFUP; 581 xs->resid = xs->datalen; 582 } else { 583 if (rb->hbastatus != I2O_SCSI_DSC_SUCCESS) { 584 switch (rb->hbastatus) { 585 case I2O_SCSI_DSC_ADAPTER_BUSY: 586 case I2O_SCSI_DSC_SCSI_BUS_RESET: 587 case I2O_SCSI_DSC_BUS_BUSY: 588 xs->error = XS_BUSY; 589 break; 590 case I2O_SCSI_DSC_SELECTION_TIMEOUT: 591 xs->error = XS_SELTIMEOUT; 592 break; 593 case I2O_SCSI_DSC_COMMAND_TIMEOUT: 594 case I2O_SCSI_DSC_DEVICE_NOT_PRESENT: 595 case I2O_SCSI_DSC_LUN_INVALID: 596 case I2O_SCSI_DSC_SCSI_TID_INVALID: 597 xs->error = XS_TIMEOUT; 598 break; 599 default: 600 xs->error = XS_DRIVER_STUFFUP; 601 break; 602 } 603 printf("%s: HBA status 0x%02x\n", sc->sc_dv.dv_xname, 604 rb->hbastatus); 605 } else if (rb->scsistatus != SCSI_OK) { 606 switch (rb->scsistatus) { 607 case SCSI_CHECK: 608 xs->error = XS_SENSE; 609 sl = le32toh(rb->senselen); 610 if (sl > sizeof(xs->sense.scsi_sense)) 611 sl = sizeof(xs->sense.scsi_sense); 612 memcpy(&xs->sense.scsi_sense, rb->sense, sl); 613 break; 614 case SCSI_QUEUE_FULL: 615 case SCSI_BUSY: 616 xs->error = XS_BUSY; 617 break; 618 default: 619 xs->error = XS_DRIVER_STUFFUP; 620 break; 621 } 622 } else 623 xs->error = XS_NOERROR; 624 625 xs->resid = xs->datalen - le32toh(rb->datalen); 626 xs->status = rb->scsistatus; 627 } 628 629 /* Free the message wrapper and pass the news to scsipi. */ 630 if (xs->datalen != 0) 631 iop_msg_unmap(iop, im); 632 iop_msg_free(iop, im); 633 634 if (--sc->sc_curqd == sc->sc_adapter.adapt_openings) 635 wakeup(&sc->sc_curqd); 636 637 scsipi_done(xs); 638 } 639 640 /* 641 * ioctl hook; used here only to initiate low-level rescans. 642 */ 643 static int 644 iopsp_ioctl(struct scsipi_channel *chan, u_long cmd, caddr_t data, int flag, 645 struct proc *p) 646 { 647 int rv; 648 649 switch (cmd) { 650 case SCBUSIOLLSCAN: 651 /* 652 * If it's boot time, the bus will have been scanned and the 653 * maps built. Locking would stop re-configuration, but we 654 * want to fake success. 655 */ 656 if (p != &proc0) 657 rv = iopsp_rescan( 658 (struct iopsp_softc *)chan->chan_adapter->adapt_dev); 659 else 660 rv = 0; 661 break; 662 663 default: 664 rv = ENOTTY; 665 break; 666 } 667 668 return (rv); 669 } 670 671 /* 672 * The number of openings available to us has changed, so inform scsipi. 673 */ 674 static void 675 iopsp_adjqparam(struct device *dv, int mpi) 676 { 677 struct iopsp_softc *sc; 678 int s; 679 680 sc = (struct iopsp_softc *)dv; 681 682 s = splbio(); 683 sc->sc_adapter.adapt_openings = mpi; 684 if (mpi < sc->sc_curqd) 685 tsleep(&sc->sc_curqd, PWAIT, "iopspdrn", 0); 686 splx(s); 687 } 688