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