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