static int st_scsibus_match(device_t parent, cfdata_t match, void *aux) { struct scsipibus_attach_args *sa = aux; int priority; if (SCSIPI_BUSTYPE_TYPE(scsipi_periph_bustype(sa->sa_periph)) != SCSIPI_BUSTYPE_SCSI) return 0; (void)scsipi_inqmatch(&sa->sa_inqbuf, st_scsibus_patterns, sizeof(st_scsibus_patterns)/sizeof(st_scsibus_patterns[0]), sizeof(st_scsibus_patterns[0]), &priority); return priority; }
Static void umass_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg) { struct scsipi_adapter *adapt = chan->chan_adapter; struct scsipi_periph *periph; struct scsipi_xfer *xs; struct umass_softc *sc = device_private(adapt->adapt_dev); struct umass_scsipi_softc *scbus = (struct umass_scsipi_softc *)sc->bus; struct scsipi_generic *cmd; int cmdlen; int dir; #ifdef UMASS_DEBUG microtime(&sc->tv); #endif switch(req) { case ADAPTER_REQ_RUN_XFER: xs = arg; periph = xs->xs_periph; DIF(UDMASS_UPPER, periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS); DPRINTF(UDMASS_CMD, ("%s: umass_scsi_cmd: at %"PRIu64".%06"PRIu64": %d:%d " "xs=%p cmd=0x%02x datalen=%d (quirks=0x%x, poll=%d)\n", device_xname(sc->sc_dev), sc->tv.tv_sec, (uint64_t)sc->tv.tv_usec, periph->periph_target, periph->periph_lun, xs, xs->cmd->opcode, xs->datalen, periph->periph_quirks, xs->xs_control & XS_CTL_POLL)); #if defined(UMASS_DEBUG) && defined(SCSIPI_DEBUG) if (umassdebug & UDMASS_SCSI) show_scsipi_xs(xs); else if (umassdebug & ~UDMASS_CMD) show_scsipi_cmd(xs); #endif if (sc->sc_dying) { xs->error = XS_DRIVER_STUFFUP; goto done; } #ifdef UMASS_DEBUG if (SCSIPI_BUSTYPE_TYPE(chan->chan_bustype->bustype_type) == SCSIPI_BUSTYPE_ATAPI ? periph->periph_target != UMASS_ATAPI_DRIVE : periph->periph_target == chan->chan_id) { DPRINTF(UDMASS_SCSI, ("%s: wrong SCSI ID %d\n", device_xname(sc->sc_dev), periph->periph_target)); xs->error = XS_DRIVER_STUFFUP; goto done; } #endif cmd = xs->cmd; cmdlen = xs->cmdlen; dir = DIR_NONE; if (xs->datalen) { switch (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) { case XS_CTL_DATA_IN: dir = DIR_IN; break; case XS_CTL_DATA_OUT: dir = DIR_OUT; break; } } if (xs->datalen > UMASS_MAX_TRANSFER_SIZE) { printf("umass_cmd: large datalen, %d\n", xs->datalen); xs->error = XS_DRIVER_STUFFUP; goto done; } if (xs->xs_control & XS_CTL_POLL) { /* Use sync transfer. XXX Broken! */ DPRINTF(UDMASS_SCSI, ("umass_scsi_cmd: sync dir=%d\n", dir)); scbus->sc_sync_status = USBD_INVAL; sc->sc_methods->wire_xfer(sc, periph->periph_lun, cmd, cmdlen, xs->data, xs->datalen, dir, xs->timeout, USBD_SYNCHRONOUS, 0, xs); DPRINTF(UDMASS_SCSI, ("umass_scsi_cmd: done err=%d\n", scbus->sc_sync_status)); switch (scbus->sc_sync_status) { case USBD_NORMAL_COMPLETION: xs->error = XS_NOERROR; break; case USBD_TIMEOUT: xs->error = XS_TIMEOUT; break; default: xs->error = XS_DRIVER_STUFFUP; break; } goto done; } else { DPRINTF(UDMASS_SCSI, ("umass_scsi_cmd: async dir=%d, cmdlen=%d" " datalen=%d\n", dir, cmdlen, xs->datalen)); sc->sc_methods->wire_xfer(sc, periph->periph_lun, cmd, cmdlen, xs->data, xs->datalen, dir, xs->timeout, 0, umass_scsipi_cb, xs); return; } /* Return if command finishes early. */ done: KERNEL_LOCK(1, curlwp); scsipi_done(xs); KERNEL_UNLOCK_ONE(curlwp); return; default: /* Not supported, nothing to do. */ ; } }