From f8bbb75a5d441f866edd45f8cae2ce27b7f80455 Mon Sep 17 00:00:00 2001 From: krw Date: Thu, 22 Jul 2010 00:31:06 +0000 Subject: [PATCH] Eliminate scsi_scsi_cmd() now that ss(4) is gone and with it the last bastardized sync and buf call through scsi_scsi_cmd(). Flatten code to call scsi_xs_sync() directly for all commands. Airplane typos shaken out by various. ok dlg@ matthew@ deraadt@ --- sys/scsi/cd.c | 628 +++++++++++++++++++++++++++---------------- sys/scsi/ch.c | 133 +++++---- sys/scsi/safte.c | 180 +++++++------ sys/scsi/scsi_base.c | 372 ++++++++++++++----------- sys/scsi/scsiconf.h | 5 +- sys/scsi/ses.c | 131 +++++---- sys/scsi/st.c | 211 +++++++++------ 7 files changed, 990 insertions(+), 670 deletions(-) diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c index fdcb74671c5..e283ebd4adf 100644 --- a/sys/scsi/cd.c +++ b/sys/scsi/cd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd.c,v 1.175 2010/07/01 05:11:18 krw Exp $ */ +/* $OpenBSD: cd.c,v 1.176 2010/07/22 00:31:06 krw Exp $ */ /* $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */ /* @@ -1346,15 +1346,25 @@ cd_setvol(struct cd_softc *sc, const struct ioc_vol *arg, int flags) int cd_load_unload(struct cd_softc *sc, int options, int slot) { - struct scsi_load_unload cmd; + struct scsi_load_unload *cmd; + struct scsi_xfer *xs; + int error; + + xs = scsi_xs_get(sc->sc_link, 0); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = LOAD_UNLOAD; + xs->cmdlen = sizeof(*cmd); + xs->timeout = 200000; - bzero(&cmd, sizeof(cmd)); - cmd.opcode = LOAD_UNLOAD; - cmd.options = options; /* ioctl uses ATAPI values */ - cmd.slot = slot; + cmd = (struct scsi_load_unload *)xs->cmd; + cmd->options = options; /* ioctl uses ATAPI values */ + cmd->slot = slot; - return (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), 0, 0, SCSI_RETRIES, 200000, NULL, 0)); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } int @@ -1401,15 +1411,25 @@ cd_set_pa_immed(struct cd_softc *sc, int flags) int cd_play(struct cd_softc *sc, int blkno, int nblks) { - struct scsi_play scsi_cmd; - - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = PLAY; - _lto4b(blkno, scsi_cmd.blk_addr); - _lto2b(nblks, scsi_cmd.xfer_len); - return (scsi_scsi_cmd(sc->sc_link, - (struct scsi_generic *)&scsi_cmd, sizeof(scsi_cmd), - 0, 0, SCSI_RETRIES, 200000, NULL, 0)); + struct scsi_play *cmd; + struct scsi_xfer *xs; + int error; + + xs = scsi_xs_get(sc->sc_link, 0); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = PLAY; + xs->cmdlen = sizeof(*cmd); + xs->timeout = 200000; + + cmd = (struct scsi_play *)xs->cmd; + _lto4b(blkno, cmd->blk_addr); + _lto2b(nblks, cmd->xfer_len); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } /* @@ -1478,19 +1498,29 @@ int cd_play_msf(struct cd_softc *sc, int startm, int starts, int startf, int endm, int ends, int endf) { - struct scsi_play_msf scsi_cmd; - - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = PLAY_MSF; - scsi_cmd.start_m = startm; - scsi_cmd.start_s = starts; - scsi_cmd.start_f = startf; - scsi_cmd.end_m = endm; - scsi_cmd.end_s = ends; - scsi_cmd.end_f = endf; - return (scsi_scsi_cmd(sc->sc_link, - (struct scsi_generic *)&scsi_cmd, sizeof(scsi_cmd), - 0, 0, SCSI_RETRIES, 20000, NULL, 0)); + struct scsi_play_msf *cmd; + struct scsi_xfer *xs; + int error; + + xs = scsi_xs_get(sc->sc_link, 0); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = PLAY_MSF; + xs->cmdlen = sizeof(*cmd); + xs->timeout = 20000; + + cmd = (struct scsi_play_msf *)xs->cmd; + cmd->start_m = startm; + cmd->start_s = starts; + cmd->start_f = startf; + cmd->end_m = endm; + cmd->end_s = ends; + cmd->end_f = endf; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } /* @@ -1499,13 +1529,24 @@ cd_play_msf(struct cd_softc *sc, int startm, int starts, int startf, int endm, int cd_pause(struct cd_softc *sc, int go) { - struct scsi_pause scsi_cmd; + struct scsi_pause *cmd; + struct scsi_xfer *xs; + int error; + + xs = scsi_xs_get(sc->sc_link, 0); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = PAUSE; + xs->cmdlen = sizeof(*cmd); + xs->timeout = 2000; + + cmd = (struct scsi_pause *)xs->cmd; + cmd->resume = go; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = PAUSE; - scsi_cmd.resume = go; - return scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&scsi_cmd, - sizeof(scsi_cmd), 0, 0, SCSI_RETRIES, 2000, NULL, 0); + return (error); } /* @@ -1514,8 +1555,19 @@ cd_pause(struct cd_softc *sc, int go) int cd_reset(struct cd_softc *sc) { - return scsi_scsi_cmd(sc->sc_link, 0, 0, 0, 0, SCSI_RETRIES, 2000, NULL, - SCSI_RESET); + struct scsi_xfer *xs; + int error; + + xs = scsi_xs_get(sc->sc_link, SCSI_RESET); + if (xs == NULL) + return (ENOMEM); + + xs->timeout = 2000; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } /* @@ -1525,19 +1577,30 @@ int cd_read_subchannel(struct cd_softc *sc, int mode, int format, int track, struct cd_sub_channel_info *data, int len) { - struct scsi_read_subchannel scsi_cmd; + struct scsi_read_subchannel *cmd; + struct scsi_xfer *xs; + int error; + + xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN | SCSI_SILENT); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = READ_SUBCHANNEL; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)data; + xs->datalen = len; + xs->timeout = 5000; - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = READ_SUBCHANNEL; if (mode == CD_MSF_FORMAT) - scsi_cmd.byte2 |= CD_MSF; - scsi_cmd.byte3 = SRS_SUBQ; - scsi_cmd.subchan_format = format; - scsi_cmd.track = track; - _lto2b(len, scsi_cmd.data_len); - return scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&scsi_cmd, - sizeof(struct scsi_read_subchannel), (u_char *)data, len, - SCSI_RETRIES, 5000, NULL, SCSI_DATA_IN|SCSI_SILENT); + cmd->byte2 |= CD_MSF; + cmd->byte3 = SRS_SUBQ; + cmd->subchan_format = format; + cmd->track = track; + _lto2b(len, cmd->data_len); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } /* @@ -1547,21 +1610,34 @@ int cd_read_toc(struct cd_softc *sc, int mode, int start, void *data, int len, int control) { - struct scsi_read_toc scsi_cmd; + struct scsi_read_toc *cmd; + struct scsi_xfer *xs; + int error; + + xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN | + SCSI_IGNORE_ILLEGAL_REQUEST); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = READ_TOC; + xs->cmdlen = sizeof(*cmd); + xs->data = data; + xs->datalen = len; + xs->timeout = 5000; - bzero(&scsi_cmd, sizeof(scsi_cmd)); bzero(data, len); - scsi_cmd.opcode = READ_TOC; + cmd = (struct scsi_read_toc *)xs->cmd; + if (mode == CD_MSF_FORMAT) - scsi_cmd.byte2 |= CD_MSF; - scsi_cmd.from_track = start; - _lto2b(len, scsi_cmd.data_len); - scsi_cmd.control = control; - - return scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&scsi_cmd, - sizeof(struct scsi_read_toc), (u_char *)data, len, SCSI_RETRIES, - 5000, NULL, SCSI_DATA_IN | SCSI_IGNORE_ILLEGAL_REQUEST); + cmd->byte2 |= CD_MSF; + cmd->from_track = start; + _lto2b(len, cmd->data_len); + cmd->control = control; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } int @@ -1632,138 +1708,165 @@ cddump(dev_t dev, daddr64_t blkno, caddr_t va, size_t size) int dvd_auth(struct cd_softc *sc, union dvd_authinfo *a) { - struct scsi_generic cmd; + struct scsi_generic *cmd; + struct scsi_xfer *xs; u_int8_t buf[20]; int error; - bzero(cmd.bytes, sizeof(cmd.bytes)); + xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmdlen = sizeof(*cmd); + xs->timeout = 30000; + xs->data = (void *)&buf; + bzero(buf, sizeof(buf)); switch (a->type) { case DVD_LU_SEND_AGID: - cmd.opcode = GPCMD_REPORT_KEY; - cmd.bytes[8] = 8; - cmd.bytes[9] = 0 | (0 << 6); - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, 8, - SCSI_RETRIES, 30000, NULL, SCSI_DATA_IN); - if (error) - return (error); - a->lsa.agid = buf[7] >> 6; - return (0); + xs->cmd->opcode = GPCMD_REPORT_KEY; + xs->cmd->bytes[8] = 8; + xs->cmd->bytes[9] = 0 | (0 << 6); + xs->datalen = 8; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error == 0) + a->lsa.agid = buf[7] >> 6; + return (error); case DVD_LU_SEND_CHALLENGE: - cmd.opcode = GPCMD_REPORT_KEY; - cmd.bytes[8] = 16; - cmd.bytes[9] = 1 | (a->lsc.agid << 6); - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, 16, - SCSI_RETRIES, 30000, NULL, SCSI_DATA_IN); - if (error) - return (error); - dvd_copy_challenge(a->lsc.chal, &buf[4]); - return (0); + xs->cmd->opcode = GPCMD_REPORT_KEY; + xs->cmd->bytes[8] = 16; + xs->cmd->bytes[9] = 1 | (a->lsc.agid << 6); + xs->datalen = 16; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + if (error == 0) + dvd_copy_challenge(a->lsc.chal, &buf[4]); + return (error); case DVD_LU_SEND_KEY1: - cmd.opcode = GPCMD_REPORT_KEY; - cmd.bytes[8] = 12; - cmd.bytes[9] = 2 | (a->lsk.agid << 6); - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, 12, - SCSI_RETRIES, 30000, NULL, SCSI_DATA_IN); - if (error) - return (error); - dvd_copy_key(a->lsk.key, &buf[4]); - return (0); + xs->cmd->opcode = GPCMD_REPORT_KEY; + xs->cmd->bytes[8] = 12; + xs->cmd->bytes[9] = 2 | (a->lsk.agid << 6); + xs->datalen = 12; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error == 0) + dvd_copy_key(a->lsk.key, &buf[4]); + return (error); case DVD_LU_SEND_TITLE_KEY: - cmd.opcode = GPCMD_REPORT_KEY; - _lto4b(a->lstk.lba, &cmd.bytes[1]); - cmd.bytes[8] = 12; - cmd.bytes[9] = 4 | (a->lstk.agid << 6); - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, 12, - SCSI_RETRIES, 30000, NULL, SCSI_DATA_IN); - if (error) - return (error); - a->lstk.cpm = (buf[4] >> 7) & 1; - a->lstk.cp_sec = (buf[4] >> 6) & 1; - a->lstk.cgms = (buf[4] >> 4) & 3; - dvd_copy_key(a->lstk.title_key, &buf[5]); - return (0); + xs->cmd->opcode = GPCMD_REPORT_KEY; + _lto4b(a->lstk.lba, &xs->cmd->bytes[1]); + xs->cmd->bytes[8] = 12; + xs->cmd->bytes[9] = 4 | (a->lstk.agid << 6); + xs->datalen = 12; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error == 0) { + a->lstk.cpm = (buf[4] >> 7) & 1; + a->lstk.cp_sec = (buf[4] >> 6) & 1; + a->lstk.cgms = (buf[4] >> 4) & 3; + dvd_copy_key(a->lstk.title_key, &buf[5]); + } + return (error); case DVD_LU_SEND_ASF: - cmd.opcode = GPCMD_REPORT_KEY; - cmd.bytes[8] = 8; - cmd.bytes[9] = 5 | (a->lsasf.agid << 6); - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, 8, - SCSI_RETRIES, 30000, NULL, SCSI_DATA_IN); - if (error) - return (error); - a->lsasf.asf = buf[7] & 1; - return (0); + xs->cmd->opcode = GPCMD_REPORT_KEY; + xs->cmd->bytes[8] = 8; + xs->cmd->bytes[9] = 5 | (a->lsasf.agid << 6); + xs->datalen = 8; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error == 0) + a->lsasf.asf = buf[7] & 1; + return (error); case DVD_HOST_SEND_CHALLENGE: - cmd.opcode = GPCMD_SEND_KEY; - cmd.bytes[8] = 16; - cmd.bytes[9] = 1 | (a->hsc.agid << 6); + xs->cmd->opcode = GPCMD_SEND_KEY; + xs->cmd->bytes[8] = 16; + xs->cmd->bytes[9] = 1 | (a->hsc.agid << 6); buf[1] = 14; dvd_copy_challenge(&buf[4], a->hsc.chal); - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, 16, - SCSI_RETRIES, 30000, NULL, SCSI_DATA_OUT); - if (error) - return (error); - a->type = DVD_LU_SEND_KEY1; - return (0); + xs->datalen = 16; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error == 0) + a->type = DVD_LU_SEND_KEY1; + return (error); case DVD_HOST_SEND_KEY2: - cmd.opcode = GPCMD_SEND_KEY; - cmd.bytes[8] = 12; - cmd.bytes[9] = 3 | (a->hsk.agid << 6); + xs->cmd->opcode = GPCMD_SEND_KEY; + xs->cmd->bytes[8] = 12; + xs->cmd->bytes[9] = 3 | (a->hsk.agid << 6); buf[1] = 10; dvd_copy_key(&buf[4], a->hsk.key); - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, 12, - SCSI_RETRIES, 30000, NULL, SCSI_DATA_OUT); - if (error) { + xs->datalen = 12; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error == 0) + a->type = DVD_AUTH_ESTABLISHED; + else a->type = DVD_AUTH_FAILURE; - return (error); - } - a->type = DVD_AUTH_ESTABLISHED; - return (0); + return (error); case DVD_INVALIDATE_AGID: - cmd.opcode = GPCMD_REPORT_KEY; - cmd.bytes[9] = 0x3f | (a->lsa.agid << 6); - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, 16, - SCSI_RETRIES, 30000, NULL, 0); - if (error) - return (error); - return (0); + xs->cmd->opcode = GPCMD_REPORT_KEY; + xs->cmd->bytes[9] = 0x3f | (a->lsa.agid << 6); + xs->datalen = 16; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); case DVD_LU_SEND_RPC_STATE: - cmd.opcode = GPCMD_REPORT_KEY; - cmd.bytes[8] = 8; - cmd.bytes[9] = 8 | (0 << 6); - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, 8, - SCSI_RETRIES, 30000, NULL, SCSI_DATA_IN); - if (error) - return (error); - a->lrpcs.type = (buf[4] >> 6) & 3; - a->lrpcs.vra = (buf[4] >> 3) & 7; - a->lrpcs.ucca = (buf[4]) & 7; - a->lrpcs.region_mask = buf[5]; - a->lrpcs.rpc_scheme = buf[6]; - return (0); + xs->cmd->opcode = GPCMD_REPORT_KEY; + xs->cmd->bytes[8] = 8; + xs->cmd->bytes[9] = 8 | (0 << 6); + xs->datalen = 8; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error == 0) { + a->lrpcs.type = (buf[4] >> 6) & 3; + a->lrpcs.vra = (buf[4] >> 3) & 7; + a->lrpcs.ucca = (buf[4]) & 7; + a->lrpcs.region_mask = buf[5]; + a->lrpcs.rpc_scheme = buf[6]; + } + return (error); case DVD_HOST_SEND_RPC_STATE: - cmd.opcode = GPCMD_SEND_KEY; - cmd.bytes[8] = 8; - cmd.bytes[9] = 6 | (0 << 6); + xs->cmd->opcode = GPCMD_SEND_KEY; + xs->cmd->bytes[8] = 8; + xs->cmd->bytes[9] = 6 | (0 << 6); buf[1] = 6; buf[4] = a->hrpcs.pdrc; - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, 8, - SCSI_RETRIES, 30000, NULL, SCSI_DATA_OUT); - if (error) - return (error); - return (0); + xs->datalen = 8; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); default: + scsi_xs_put(xs); return (ENOTTY); } } @@ -1771,86 +1874,118 @@ dvd_auth(struct cd_softc *sc, union dvd_authinfo *a) int dvd_read_physical(struct cd_softc *sc, union dvd_struct *s) { - struct scsi_generic cmd; - u_int8_t buf[4 + 4 * 20], *bufp; - int error; + struct scsi_generic *cmd; struct dvd_layer *layer; - int i; + struct scsi_xfer *xs; + u_int8_t buf[4 + 4 * 20], *bufp; + int error, i; + + xs = scsi_xs_get(xs->sc_link, SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = GPCMD_READ_DVD_STRUCTURE; + xs->cmdlen = sizeof(*cmd); + xs->data = buf; + xs->datalen = sizeof(buf); + xs->timeout = 30000; - bzero(cmd.bytes, sizeof(cmd.bytes)); bzero(buf, sizeof(buf)); - cmd.opcode = GPCMD_READ_DVD_STRUCTURE; - cmd.bytes[6] = s->type; - _lto2b(sizeof(buf), &cmd.bytes[7]); - - cmd.bytes[5] = s->physical.layer_num; - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, sizeof(buf), - SCSI_RETRIES, 30000, NULL, SCSI_DATA_IN); - if (error) - return (error); - for (i = 0, bufp = &buf[4], layer = &s->physical.layer[0]; i < 4; - i++, bufp += 20, layer++) { - bzero(layer, sizeof(*layer)); - layer->book_version = bufp[0] & 0xf; - layer->book_type = bufp[0] >> 4; - layer->min_rate = bufp[1] & 0xf; - layer->disc_size = bufp[1] >> 4; - layer->layer_type = bufp[2] & 0xf; - layer->track_path = (bufp[2] >> 4) & 1; - layer->nlayers = (bufp[2] >> 5) & 3; - layer->track_density = bufp[3] & 0xf; - layer->linear_density = bufp[3] >> 4; - layer->start_sector = _4btol(&bufp[4]); - layer->end_sector = _4btol(&bufp[8]); - layer->end_sector_l0 = _4btol(&bufp[12]); - layer->bca = bufp[16] >> 7; + + xs->cmd->bytes[6] = s->type; + _lto2b(sizeof(buf), &xs->cmd->bytes[7]); + + xs->cmd->bytes[5] = s->physical.layer_num; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error == 0) { + for (i = 0, bufp = &buf[4], layer = &s->physical.layer[0]; + i < 4; i++, bufp += 20, layer++) { + bzero(layer, sizeof(*layer)); + layer->book_version = bufp[0] & 0xf; + layer->book_type = bufp[0] >> 4; + layer->min_rate = bufp[1] & 0xf; + layer->disc_size = bufp[1] >> 4; + layer->layer_type = bufp[2] & 0xf; + layer->track_path = (bufp[2] >> 4) & 1; + layer->nlayers = (bufp[2] >> 5) & 3; + layer->track_density = bufp[3] & 0xf; + layer->linear_density = bufp[3] >> 4; + layer->start_sector = _4btol(&bufp[4]); + layer->end_sector = _4btol(&bufp[8]); + layer->end_sector_l0 = _4btol(&bufp[12]); + layer->bca = bufp[16] >> 7; + } } - return (0); + return (error); } int dvd_read_copyright(struct cd_softc *sc, union dvd_struct *s) { - struct scsi_generic cmd; + struct scsi_generic *cmd; + struct scsi_xfer *xs; u_int8_t buf[8]; int error; - bzero(cmd.bytes, sizeof(cmd.bytes)); + xs = scsi_xs_get(sc->sc_link, 0); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = GPCMD_READ_DVD_STRUCTURE; + xs->cmdlen = sizeof(*cmd); + xs->data = buf; + xs->datalen = sizeof(buf); + xs->timeout = 30000; + bzero(buf, sizeof(buf)); - cmd.opcode = GPCMD_READ_DVD_STRUCTURE; - cmd.bytes[6] = s->type; - _lto2b(sizeof(buf), &cmd.bytes[7]); - - cmd.bytes[5] = s->copyright.layer_num; - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, sizeof(buf), - SCSI_RETRIES, 30000, NULL, SCSI_DATA_IN); - if (error) - return (error); - s->copyright.cpst = buf[4]; - s->copyright.rmi = buf[5]; - return (0); + + xs->cmd->bytes[6] = s->type; + _lto2b(sizeof(buf), &xs->cmd->bytes[7]); + + xs->cmd->bytes[5] = s->copyright.layer_num; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error) { + s->copyright.cpst = buf[4]; + s->copyright.rmi = buf[5]; + } + + return (error); } int dvd_read_disckey(struct cd_softc *sc, union dvd_struct *s) { - struct scsi_read_dvd_structure cmd; struct scsi_read_dvd_structure_data *buf; + struct scsi_read_dvd_structure *cmd; + struct scsi_xfer *xs; int error; + xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = GPCMD_READ_DVD_STRUCTURE; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)buf; + xs->datalen = sizeof(*buf); + xs->timeout = 30000; + buf = malloc(sizeof(*buf), M_TEMP, M_WAITOK | M_ZERO); - if (buf == NULL) + if (buf == NULL) { + scsi_xs_put(xs); return (ENOMEM); + } - bzero(&cmd, sizeof(cmd)); - cmd.opcode = GPCMD_READ_DVD_STRUCTURE; - cmd.format = s->type; - cmd.agid = s->disckey.agid << 6; - _lto2b(sizeof(*buf), cmd.length); + cmd->format = s->type; + cmd->agid = s->disckey.agid << 6; + _lto2b(sizeof(*buf), cmd->length); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); - error = scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), (u_char *)buf, sizeof(*buf), SCSI_RETRIES, 30000, NULL, - SCSI_DATA_IN); if (error == 0) bcopy(buf->data, s->disckey.value, sizeof(s->disckey.value)); @@ -1861,46 +1996,67 @@ dvd_read_disckey(struct cd_softc *sc, union dvd_struct *s) int dvd_read_bca(struct cd_softc *sc, union dvd_struct *s) { - struct scsi_generic cmd; + struct scsi_generic *cmd; + struct scsi_xfer *xs; u_int8_t buf[4 + 188]; int error; - bzero(cmd.bytes, sizeof(cmd.bytes)); + xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = GPCMD_READ_DVD_STRUCTURE; + xs->cmdlen = sizeof(*cmd); + xs->data = buf; + xs->datalen = sizeof(buf); + xs->timeout = 30000; + bzero(buf, sizeof(buf)); - cmd.opcode = GPCMD_READ_DVD_STRUCTURE; - cmd.bytes[6] = s->type; - _lto2b(sizeof(buf), &cmd.bytes[7]); - error = scsi_scsi_cmd(sc->sc_link, &cmd, sizeof(cmd), buf, sizeof(buf), - SCSI_RETRIES, 30000, NULL, SCSI_DATA_IN); - if (error) - return (error); - s->bca.len = _2btol(&buf[0]); - if (s->bca.len < 12 || s->bca.len > 188) - return (EIO); - bcopy(&buf[4], s->bca.value, s->bca.len); - return (0); + xs->cmd->bytes[6] = s->type; + _lto2b(sizeof(buf), &xs->cmd->bytes[7]); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error == 0) { + s->bca.len = _2btol(&buf[0]); + if (s->bca.len < 12 || s->bca.len > 188) + return (EIO); + bcopy(&buf[4], s->bca.value, s->bca.len); + } + return (error); } int dvd_read_manufact(struct cd_softc *sc, union dvd_struct *s) { - struct scsi_read_dvd_structure cmd; struct scsi_read_dvd_structure_data *buf; + struct scsi_read_dvd_structure *cmd; + struct scsi_xfer *xs; int error; + xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = GPCMD_READ_DVD_STRUCTURE; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)buf; + xs->datalen = sizeof(*buf); + xs->timeout = 30000; + buf = malloc(sizeof(*buf), M_TEMP, M_WAITOK | M_ZERO); - if (buf == NULL) + if (buf == NULL) { + scsi_xs_put(xs); return (ENOMEM); + } - bzero(&cmd, sizeof(cmd)); - cmd.opcode = GPCMD_READ_DVD_STRUCTURE; - cmd.format = s->type; - _lto2b(sizeof(*buf), cmd.length); + cmd = (struct scsi_read_dvd_structure *)xs->cmd; + cmd->format = s->type; + _lto2b(sizeof(*buf), cmd->length); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); - error = scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), (u_char *)buf, sizeof(*buf), SCSI_RETRIES, 30000, NULL, - SCSI_DATA_IN); if (error == 0) { s->manufact.len = _2btol(buf->len); if (s->manufact.len >= 0 && s->manufact.len <= 2048) diff --git a/sys/scsi/ch.c b/sys/scsi/ch.c index 6a9b82ab874..0d6a1a435eb 100644 --- a/sys/scsi/ch.c +++ b/sys/scsi/ch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ch.c,v 1.40 2010/07/01 05:11:18 krw Exp $ */ +/* $OpenBSD: ch.c,v 1.41 2010/07/22 00:31:06 krw Exp $ */ /* $NetBSD: ch.c,v 1.26 1997/02/21 22:06:52 thorpej Exp $ */ /* @@ -348,7 +348,9 @@ ch_move(sc, cm) struct ch_softc *sc; struct changer_move *cm; { - struct scsi_move_medium cmd; + struct scsi_move_medium *cmd; + struct scsi_xfer *xs; + int error; u_int16_t fromelem, toelem; /* @@ -375,19 +377,24 @@ ch_move(sc, cm) /* * Build the SCSI command. */ - bzero(&cmd, sizeof(cmd)); - cmd.opcode = MOVE_MEDIUM; - _lto2b(sc->sc_picker, cmd.tea); - _lto2b(fromelem, cmd.src); - _lto2b(toelem, cmd.dst); + xs = scsi_xs_get(sc->sc_link, 0); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = MOVE_MEDIUM; + xs->cmdlen = sizeof(*cmd); + xs->retries = CHRETRIES; + xs->timeout = 100000; + + _lto2b(sc->sc_picker, cmd->tea); + _lto2b(fromelem, cmd->src); + _lto2b(toelem, cmd->dst); if (cm->cm_flags & CM_INVERT) - cmd.flags |= MOVE_MEDIUM_INVERT; + cmd->flags |= MOVE_MEDIUM_INVERT; - /* - * Send command to changer. - */ - return (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), NULL, 0, CHRETRIES, 100000, NULL, 0)); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } int @@ -395,7 +402,9 @@ ch_exchange(sc, ce) struct ch_softc *sc; struct changer_exchange *ce; { - struct scsi_exchange_medium cmd; + struct scsi_exchange_medium *cmd; + struct scsi_xfer *xs; + int error; u_int16_t src, dst1, dst2; /* @@ -428,22 +437,27 @@ ch_exchange(sc, ce) /* * Build the SCSI command. */ - bzero(&cmd, sizeof(cmd)); - cmd.opcode = EXCHANGE_MEDIUM; - _lto2b(sc->sc_picker, cmd.tea); - _lto2b(src, cmd.src); - _lto2b(dst1, cmd.fdst); - _lto2b(dst2, cmd.sdst); + xs = scsi_xs_get(sc->sc_link, 0); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = EXCHANGE_MEDIUM; + xs->cmdlen = sizeof(*cmd); + xs->retries = CHRETRIES; + xs->timeout = 100000; + + _lto2b(sc->sc_picker, cmd->tea); + _lto2b(src, cmd->src); + _lto2b(dst1, cmd->fdst); + _lto2b(dst2, cmd->sdst); if (ce->ce_flags & CE_INVERT1) - cmd.flags |= EXCHANGE_MEDIUM_INV1; + cmd->flags |= EXCHANGE_MEDIUM_INV1; if (ce->ce_flags & CE_INVERT2) - cmd.flags |= EXCHANGE_MEDIUM_INV2; + cmd->flags |= EXCHANGE_MEDIUM_INV2; - /* - * Send command to changer. - */ - return (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), NULL, 0, CHRETRIES, 100000, NULL, 0)); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } int @@ -451,7 +465,9 @@ ch_position(sc, cp) struct ch_softc *sc; struct changer_position *cp; { - struct scsi_position_to_element cmd; + struct scsi_position_to_element *cmd; + struct scsi_xfer *xs; + int error; u_int16_t dst; /* @@ -470,18 +486,23 @@ ch_position(sc, cp) /* * Build the SCSI command. */ - bzero(&cmd, sizeof(cmd)); - cmd.opcode = POSITION_TO_ELEMENT; - _lto2b(sc->sc_picker, cmd.tea); - _lto2b(dst, cmd.dst); + xs = scsi_xs_get(sc->sc_link, 0); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = POSITION_TO_ELEMENT; + xs->cmdlen = sizeof(*cmd); + xs->retries = CHRETRIES; + xs->timeout = 100000; + + _lto2b(sc->sc_picker, cmd->tea); + _lto2b(dst, cmd->dst); if (cp->cp_flags & CP_INVERT) - cmd.flags |= POSITION_TO_ELEMENT_INVERT; + cmd->flags |= POSITION_TO_ELEMENT_INVERT; - /* - * Send command to changer. - */ - return (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), NULL, 0, CHRETRIES, 100000, NULL, 0)); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } /* @@ -624,27 +645,35 @@ ch_getelemstatus(sc, first, count, data, datalen, voltag) size_t datalen; int voltag; { - struct scsi_read_element_status cmd; + struct scsi_read_element_status *cmd; + struct scsi_xfer *xs; + int error; /* * Build SCSI command. */ - bzero(&cmd, sizeof(cmd)); - cmd.opcode = READ_ELEMENT_STATUS; - _lto2b(first, cmd.sea); - _lto2b(count, cmd.count); - _lto3b(datalen, cmd.len); + xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = READ_ELEMENT_STATUS; + xs->cmdlen = sizeof(*cmd); + xs->data = data; + xs->datalen = datalen; + xs->retries = CHRETRIES; + xs->timeout = 100000; + + cmd = (struct scsi_read_element_status *)xs->cmd; + _lto2b(first, cmd->sea); + _lto2b(count, cmd->count); + _lto3b(datalen, cmd->len); if (voltag) - cmd.byte2 |= READ_ELEMENT_STATUS_VOLTAG; + cmd->byte2 |= READ_ELEMENT_STATUS_VOLTAG; - /* - * Send command to changer. - */ - return (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), (u_char *)data, datalen, CHRETRIES, 100000, NULL, - SCSI_DATA_IN)); -} + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + return (error); +} /* * Ask the device about itself and fill in the parameters in our diff --git a/sys/scsi/safte.c b/sys/scsi/safte.c index 95462f95249..f2baaf66b62 100644 --- a/sys/scsi/safte.c +++ b/sys/scsi/safte.c @@ -1,4 +1,4 @@ -/* $OpenBSD: safte.c,v 1.40 2009/01/20 21:46:42 kettenis Exp $ */ +/* $OpenBSD: safte.c,v 1.41 2010/07/22 00:31:06 krw Exp $ */ /* * Copyright (c) 2005 David Gwynne @@ -108,12 +108,15 @@ int64_t safte_temp2uK(u_int8_t, int); int safte_match(struct device *parent, void *match, void *aux) { - struct scsi_attach_args *sa = aux; - struct scsi_inquiry_data *inq = sa->sa_inqbuf; - struct scsi_inquiry_data inqbuf; - struct scsi_inquiry cmd; - struct safte_inq *si = (struct safte_inq *)&inqbuf.extra; - int length, flags; + struct scsi_inquiry_data inqbuf; + struct scsi_attach_args *sa = aux; + struct scsi_inquiry_data *inq = sa->sa_inqbuf; + struct scsi_inquiry *cmd; + struct scsi_xfer *xs; + struct safte_inq *si; + int error, flags = 0, length; + + si = (struct safte_inq *)&inqbuf.extra; if (inq == NULL) return (0); @@ -134,26 +137,33 @@ safte_match(struct device *parent, void *match, void *aux) if (length > sizeof(inqbuf)) length = sizeof(inqbuf); - memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = INQUIRY; - _lto2b(length, cmd.length); + if (cold) + flags |= SCSI_AUTOCONF; + xs = scsi_xs_get(sa->sa_sc_link, flags | SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = INQUIRY; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)&inqbuf; + xs->datalen = length; + xs->retries = 2; + xs->timeout = 10000; + + cmd = (struct scsi_inquiry *)xs->cmd; + _lto2b(length, cmd->length); memset(&inqbuf, 0, sizeof(inqbuf)); memset(&inqbuf.extra, ' ', sizeof(inqbuf.extra)); - flags = SCSI_DATA_IN; - if (cold) - flags |= SCSI_AUTOCONF; + error = scsi_xs_sync(xs); + scsi_xs_put(xs); - if (scsi_scsi_cmd(sa->sa_sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), (u_char *)&inqbuf, length, 2, 10000, NULL, - flags) != 0) - return (0); - - if (memcmp(si->ident, SAFTE_IDENT, sizeof(si->ident)) == 0) - return (2); + if (error == 0) { + if (memcmp(si->ident, SAFTE_IDENT, sizeof(si->ident)) == 0) + return (2); + } - return (0); + return (error); } void @@ -248,27 +258,33 @@ safte_detach(struct device *self, int flags) int safte_read_config(struct safte_softc *sc) { - struct safte_readbuf_cmd cmd; - struct safte_config config; - struct safte_sensor *s; - int flags, i, j; - - memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = READ_BUFFER; - cmd.flags |= SAFTE_RD_MODE; - cmd.bufferid = SAFTE_RD_CONFIG; - cmd.length = htobe16(sizeof(config)); - flags = SCSI_DATA_IN; -#ifndef SCSIDEBUG - flags |= SCSI_SILENT; -#endif + struct safte_config config; + struct safte_readbuf_cmd *cmd; + struct safte_sensor *s; + struct scsi_xfer *xs; + int error, flags = 0, i, j; if (cold) flags |= SCSI_AUTOCONF; - - if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), (u_char *)&config, sizeof(config), 2, 30000, NULL, - flags) != 0) + xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT); + if (xs == NULL) + return (1); + xs->cmd->opcode = READ_BUFFER; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)&config; + xs->datalen = sizeof(config); + xs->retries = 2; + xs->timeout = 30000; + + cmd = (struct safte_readbuf_cmd *)xs->cmd; + cmd->flags |= SAFTE_RD_MODE; + cmd->bufferid = SAFTE_RD_CONFIG; + cmd->length = htobe16(sizeof(config)); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error != 0) return (1); DPRINTF(("%s: nfans: %d npwrsup: %d nslots: %d doorlock: %d ntemps: %d" @@ -379,30 +395,36 @@ safte_read_config(struct safte_softc *sc) void safte_read_encstat(void *arg) { - struct safte_softc *sc = (struct safte_softc *)arg; - struct safte_readbuf_cmd cmd; - int flags, i; - struct safte_sensor *s; - u_int16_t oot; + struct safte_readbuf_cmd *cmd; + struct safte_sensor*s; + struct safte_softc *sc = (struct safte_softc *)arg; + struct scsi_xfer *xs; + int error, i, flags = 0; + u_int16_t oot; rw_enter_write(&sc->sc_lock); - memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = READ_BUFFER; - cmd.flags |= SAFTE_RD_MODE; - cmd.bufferid = SAFTE_RD_ENCSTAT; - cmd.length = htobe16(sc->sc_encbuflen); - flags = SCSI_DATA_IN; -#ifndef SCSIDEBUG - flags |= SCSI_SILENT; -#endif - if (cold) flags |= SCSI_AUTOCONF; - - if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), sc->sc_encbuf, sc->sc_encbuflen, 2, 30000, NULL, - flags) != 0) { + xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT); + if (xs == NULL) + return; + xs->cmd->opcode = READ_BUFFER; + xs->cmdlen = sizeof(*cmd); + xs->data = sc->sc_encbuf; + xs->datalen = sc->sc_encbuflen; + xs->retries = 2; + xs->timeout = 30000; + + cmd = (struct safte_readbuf_cmd *)xs->cmd; + cmd->flags |= SAFTE_RD_MODE; + cmd->bufferid = SAFTE_RD_ENCSTAT; + cmd->length = htobe16(sc->sc_encbuflen); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error != 0) { rw_exit_write(&sc->sc_lock); return; } @@ -532,11 +554,10 @@ safte_ioctl(struct device *dev, u_long cmd, caddr_t addr) int safte_bio_blink(struct safte_softc *sc, struct bioc_blink *blink) { - struct safte_writebuf_cmd cmd; - struct safte_slotop *op; - int slot; - int flags; - int wantblink; + struct safte_writebuf_cmd *cmd; + struct safte_slotop *op; + struct scsi_xfer *xs; + int error, slot, flags = 0, wantblink; switch (blink->bb_status) { case BIOC_SBBLINK: @@ -565,27 +586,32 @@ safte_bio_blink(struct safte_softc *sc, struct bioc_blink *blink) op->slot = slot; op->flags |= wantblink ? SAFTE_SLOTOP_IDENTIFY : 0; - memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = WRITE_BUFFER; - cmd.flags |= SAFTE_WR_MODE; - cmd.length = htobe16(sizeof(struct safte_slotop)); - flags = SCSI_DATA_OUT; -#ifndef SCSIDEBUG - flags |= SCSI_SILENT; -#endif if (cold) flags |= SCSI_AUTOCONF; - - if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), (u_char *)op, sizeof(struct safte_slotop), - 2, 30000, NULL, flags) != 0) { + xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_OUT | SCSI_SILENT); + if (xs == NULL) { free(op, M_TEMP); - return (EIO); + return (ENOMEM); } + xs->cmd->opcode = WRITE_BUFFER; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)op; + xs->datalen = sizeof(*op); + xs->retries = 2; + xs->timeout = 30000; + + cmd->flags |= SAFTE_WR_MODE; + cmd->length = htobe16(sizeof(struct safte_slotop)); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + if (error != 0) { + error = EIO; + } free(op, M_TEMP); - return (0); + return (error); } #endif /* NBIO > 0 */ diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c index 3e172fdf084..1519ab24bc9 100644 --- a/sys/scsi/scsi_base.c +++ b/sys/scsi/scsi_base.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scsi_base.c,v 1.183 2010/07/06 01:07:28 krw Exp $ */ +/* $OpenBSD: scsi_base.c,v 1.184 2010/07/22 00:31:06 krw Exp $ */ /* $NetBSD: scsi_base.c,v 1.43 1997/04/02 02:29:36 mycroft Exp $ */ /* @@ -626,10 +626,11 @@ scsi_xs_put(struct scsi_xfer *xs) daddr64_t scsi_size(struct scsi_link *sc_link, int flags, u_int32_t *blksize) { - struct scsi_read_capacity_16 rc16; - struct scsi_read_capacity rc; struct scsi_read_cap_data_16 *rdcap16; + struct scsi_read_capacity_16 *cmd; struct scsi_read_cap_data *rdcap; + struct scsi_read_capacity *cmd10; + struct scsi_xfer *xs; daddr64_t max_addr; int error; @@ -641,17 +642,27 @@ scsi_size(struct scsi_link *sc_link, int flags, u_int32_t *blksize) /* * Start with a READ CAPACITY(10). */ - bzero(&rc, sizeof(rc)); - bzero(&rdcap, sizeof(rdcap)); - rc.opcode = READ_CAPACITY; - rdcap = malloc(sizeof(*rdcap), M_TEMP, ((flags & SCSI_NOSLEEP) ? M_NOWAIT : M_WAITOK) | M_ZERO); if (rdcap == NULL) return (0); - error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)&rc, sizeof(rc), - (u_char *)rdcap, sizeof(*rdcap), SCSI_RETRIES, 20000, NULL, - flags | SCSI_DATA_IN | SCSI_SILENT); + + xs = scsi_xs_get(sc_link, flags | SCSI_DATA_IN | SCSI_SILENT); + if (xs == NULL) { + free(rdcap, M_TEMP); + return (0); + } + xs->cmd->opcode = READ_CAPACITY; + xs->cmdlen = sizeof(*cmd10); + xs->data = (void *)rdcap; + xs->datalen = sizeof(*rdcap); + xs->timeout = 20000; + + bzero(rdcap, sizeof(*rdcap)); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + if (error) { SC_DEBUG(sc_link, SDEV_DB1, ("READ CAPACITY error (%#x)\n", error)); @@ -668,22 +679,33 @@ scsi_size(struct scsi_link *sc_link, int flags, u_int32_t *blksize) goto exit; /* - * SCSI-3 devices, or devices reporting more than 2^32-1 sectors can try - * READ CAPACITY(16). + * SCSI-3 devices, or devices reporting more than 2^32-1 sectors can + * try READ CAPACITY(16). */ - bzero(&rc16, sizeof(rc16)); - bzero(&rdcap16, sizeof(rdcap16)); - rc16.opcode = READ_CAPACITY_16; - rc16.byte2 = SRC16_SERVICE_ACTION; - _lto4b(sizeof(*rdcap16), rc16.length); - rdcap16 = malloc(sizeof(*rdcap16), M_TEMP, ((flags & SCSI_NOSLEEP) ? M_NOWAIT : M_WAITOK) | M_ZERO); if (rdcap16 == NULL) goto exit; - error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)&rc16, - sizeof(rc16), (u_char *)rdcap16, sizeof(*rdcap16), SCSI_RETRIES, - 20000, NULL, flags | SCSI_DATA_IN | SCSI_SILENT); + + xs = scsi_xs_get(sc_link, flags | SCSI_DATA_IN | SCSI_SILENT); + if (xs == NULL) { + free(rdcap16, M_TEMP); + goto exit; + } + xs->cmd->opcode = READ_CAPACITY_16; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)rdcap16; + xs->datalen = sizeof(*rdcap16); + xs->timeout = 20000; + + bzero(rdcap16, sizeof(*rdcap16)); + + cmd = (struct scsi_read_capacity_16 *)xs->cmd; + cmd->byte2 = SRC16_SERVICE_ACTION; + _lto4b(sizeof(*rdcap16), cmd->length); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); if (error) { SC_DEBUG(sc_link, SDEV_DB1, ("READ CAPACITY 16 error (%#x)\n", error)); @@ -714,13 +736,22 @@ exit: int scsi_test_unit_ready(struct scsi_link *sc_link, int retries, int flags) { - struct scsi_test_unit_ready scsi_cmd; + struct scsi_test_unit_ready *cmd; + struct scsi_xfer *xs; + int error; - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = TEST_UNIT_READY; + xs = scsi_xs_get(sc_link, flags); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = TEST_UNIT_READY; + xs->cmdlen = sizeof(*cmd); + xs->retries = retries; + xs->timeout = 10000; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); - return (scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd, - sizeof(scsi_cmd), 0, 0, retries, 10000, NULL, flags)); + return (error); } /* @@ -731,8 +762,8 @@ int scsi_inquire(struct scsi_link *link, struct scsi_inquiry_data *inqbuf, int flags) { + struct scsi_inquiry *cmd; struct scsi_xfer *xs; - struct scsi_inquiry *cdb; size_t length; int error; @@ -746,11 +777,11 @@ scsi_inquire(struct scsi_link *link, struct scsi_inquiry_data *inqbuf, */ length = SID_INQUIRY_HDR + SID_SCSI2_ALEN; - cdb = (struct scsi_inquiry *)xs->cmd; - cdb->opcode = INQUIRY; - _lto2b(length, cdb->length); + cmd = (struct scsi_inquiry *)xs->cmd; + cmd->opcode = INQUIRY; + _lto2b(length, cmd->length); - xs->cmdlen = sizeof(*cdb); + xs->cmdlen = sizeof(*cmd); xs->flags |= SCSI_DATA_IN; xs->data = (void *)inqbuf; @@ -776,27 +807,34 @@ int scsi_inquire_vpd(struct scsi_link *sc_link, void *buf, u_int buflen, u_int8_t page, int flags) { - struct scsi_inquiry scsi_cmd; + struct scsi_inquiry *cmd; + struct scsi_xfer *xs; int error; - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = INQUIRY; - scsi_cmd.flags = SI_EVPD; - scsi_cmd.pagecode = page; - _lto2b(buflen, scsi_cmd.length); + if (sc_link->flags & SDEV_UMASS) + error = EJUSTRETURN; + + xs = scsi_xs_get(sc_link, flags | SCSI_DATA_IN | SCSI_SILENT); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = INQUIRY; + xs->cmdlen = sizeof(*cmd); + xs->data = buf; + xs->datalen = buflen; + xs->retries = 2; + xs->timeout = 10000; + + cmd = (struct scsi_inquiry *)xs->cmd; + cmd->flags = SI_EVPD; + cmd->pagecode = page; + _lto2b(buflen, cmd->length); bzero(buf, buflen); - if (sc_link->flags & SDEV_UMASS) { - /* do nothing, just return */ - error = EJUSTRETURN; - } else - error = scsi_scsi_cmd(sc_link, - (struct scsi_generic *)&scsi_cmd, - sizeof(scsi_cmd), buf, buflen, 2, 10000, NULL, - SCSI_DATA_IN | SCSI_SILENT | flags); - - return (error); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } /* @@ -805,17 +843,28 @@ scsi_inquire_vpd(struct scsi_link *sc_link, void *buf, u_int buflen, int scsi_prevent(struct scsi_link *sc_link, int type, int flags) { - struct scsi_prevent scsi_cmd; + struct scsi_prevent *cmd; + struct scsi_xfer *xs; + int error; if (sc_link->quirks & ADEV_NODOORLOCK) return (0); - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = PREVENT_ALLOW; - scsi_cmd.how = type; + xs = scsi_xs_get(sc_link, flags); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = PREVENT_ALLOW; + xs->cmdlen = sizeof(*cmd); + xs->retries = 2; + xs->timeout = 5000; + + cmd = (struct scsi_prevent *)xs->cmd; + cmd->how = type; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); - return (scsi_scsi_cmd(sc_link, (struct scsi_generic *)&scsi_cmd, - sizeof(scsi_cmd), 0, 0, 2, 5000, NULL, flags)); + return (error); } /* @@ -824,24 +873,43 @@ scsi_prevent(struct scsi_link *sc_link, int type, int flags) int scsi_start(struct scsi_link *sc_link, int type, int flags) { - struct scsi_start_stop scsi_cmd; + struct scsi_start_stop *cmd; + struct scsi_xfer *xs; + int error; + + xs = scsi_xs_get(sc_link, flags); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = START_STOP; + xs->cmdlen = sizeof(*cmd); + xs->retries = 2; + xs->timeout = (type == SSS_START) ? 30000 : 10000; - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = START_STOP; - scsi_cmd.byte2 = 0x00; - scsi_cmd.how = type; + cmd = (struct scsi_start_stop *)xs->cmd; + cmd->how = type; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); - return (scsi_scsi_cmd(sc_link, (struct scsi_generic *)&scsi_cmd, - sizeof(scsi_cmd), 0, 0, 2, - type == SSS_START ? 30000 : 10000, NULL, flags)); + return (error); } int scsi_mode_sense(struct scsi_link *sc_link, int byte2, int page, struct scsi_mode_header *data, size_t len, int flags, int timeout) { - struct scsi_mode_sense scsi_cmd; - int error; + struct scsi_mode_sense *cmd; + struct scsi_xfer *xs; + int error; + + xs = scsi_xs_get(sc_link, flags | SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = MODE_SENSE; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)data; + xs->datalen = len; + xs->timeout = timeout; /* * Make sure the sense buffer is clean before we do the mode sense, so @@ -850,18 +918,16 @@ scsi_mode_sense(struct scsi_link *sc_link, int byte2, int page, */ bzero(data, len); - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = MODE_SENSE; - scsi_cmd.byte2 = byte2; - scsi_cmd.page = page; + cmd = (struct scsi_mode_sense *)xs->cmd; + cmd->byte2 = byte2; + cmd->page = page; if (len > 0xff) len = 0xff; - scsi_cmd.length = len; + cmd->length = len; - error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)&scsi_cmd, - sizeof(scsi_cmd), (u_char *)data, len, SCSI_RETRIES, timeout, NULL, - flags | SCSI_DATA_IN); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); SC_DEBUG(sc_link, SDEV_DB2, ("scsi_mode_sense: page %#x, error = %d\n", page, error)); @@ -873,8 +939,18 @@ int scsi_mode_sense_big(struct scsi_link *sc_link, int byte2, int page, struct scsi_mode_header_big *data, size_t len, int flags, int timeout) { - struct scsi_mode_sense_big scsi_cmd; - int error; + struct scsi_mode_sense_big *cmd; + struct scsi_xfer *xs; + int error; + + xs = scsi_xs_get(sc_link, flags | SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = MODE_SENSE_BIG; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)data; + xs->datalen = len; + xs->timeout = timeout; /* * Make sure the sense buffer is clean before we do the mode sense, so @@ -883,18 +959,16 @@ scsi_mode_sense_big(struct scsi_link *sc_link, int byte2, int page, */ bzero(data, len); - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = MODE_SENSE_BIG; - scsi_cmd.byte2 = byte2; - scsi_cmd.page = page; + cmd = (struct scsi_mode_sense_big *)xs->cmd; + cmd->byte2 = byte2; + cmd->page = page; if (len > 0xffff) len = 0xffff; - _lto2b(len, scsi_cmd.length); + _lto2b(len, cmd->length); - error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)&scsi_cmd, - sizeof(scsi_cmd), (u_char *)data, len, SCSI_RETRIES, timeout, NULL, - flags | SCSI_DATA_IN); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); SC_DEBUG(sc_link, SDEV_DB2, ("scsi_mode_sense_big: page %#x, error = %d\n", page, error)); @@ -1038,20 +1112,31 @@ int scsi_mode_select(struct scsi_link *sc_link, int byte2, struct scsi_mode_header *data, int flags, int timeout) { - struct scsi_mode_select scsi_cmd; - int error; + struct scsi_mode_select *cmd; + struct scsi_xfer *xs; + u_int32_t len; + int error; + + len = data->data_length + 1; /* 1 == sizeof(data_length) */ + + xs = scsi_xs_get(sc_link, flags | SCSI_DATA_OUT); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = MODE_SELECT; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)data; + xs->datalen = len; + xs->timeout = timeout; - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = MODE_SELECT; - scsi_cmd.byte2 = byte2; - scsi_cmd.length = data->data_length + 1; /* 1 == sizeof(data_length) */ + cmd = (struct scsi_mode_select *)xs->cmd; + cmd->byte2 = byte2; + cmd->length = len; /* Length is reserved when doing mode select so zero it. */ data->data_length = 0; - error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)&scsi_cmd, - sizeof(scsi_cmd), (u_char *)data, scsi_cmd.length, SCSI_RETRIES, - timeout, NULL, flags | SCSI_DATA_OUT); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); SC_DEBUG(sc_link, SDEV_DB2, ("scsi_mode_select: error = %d\n", error)); @@ -1062,23 +1147,31 @@ int scsi_mode_select_big(struct scsi_link *sc_link, int byte2, struct scsi_mode_header_big *data, int flags, int timeout) { - struct scsi_mode_select_big scsi_cmd; - u_int32_t len; - int error; + struct scsi_mode_select_big *cmd; + struct scsi_xfer *xs; + u_int32_t len; + int error; - len = _2btol(data->data_length) + 2; /* 2 == sizeof data->data_length */ + len = _2btol(data->data_length) + 2; /* 2 == sizeof data_length */ - bzero(&scsi_cmd, sizeof(scsi_cmd)); - scsi_cmd.opcode = MODE_SELECT_BIG; - scsi_cmd.byte2 = byte2; - _lto2b(len, scsi_cmd.length); + xs = scsi_xs_get(sc_link, flags | SCSI_DATA_OUT); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = MODE_SELECT_BIG; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)data; + xs->datalen = len; + xs->timeout = timeout; + + cmd = (struct scsi_mode_select_big *)xs->cmd; + cmd->byte2 = byte2; + _lto2b(len, cmd->length); /* Length is reserved when doing mode select so zero it. */ _lto2b(0, data->data_length); - error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)&scsi_cmd, - sizeof(scsi_cmd), (u_char *)data, len, SCSI_RETRIES, timeout, NULL, - flags | SCSI_DATA_OUT); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); SC_DEBUG(sc_link, SDEV_DB2, ("scsi_mode_select_big: error = %d\n", error)); @@ -1091,19 +1184,27 @@ scsi_report_luns(struct scsi_link *sc_link, int selectreport, struct scsi_report_luns_data *data, u_int32_t datalen, int flags, int timeout) { - struct scsi_report_luns scsi_cmd; + struct scsi_report_luns *cmd; + struct scsi_xfer *xs; int error; - bzero(&scsi_cmd, sizeof(scsi_cmd)); + xs = scsi_xs_get(sc_link, flags | SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = REPORT_LUNS; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)data; + xs->datalen = datalen; + xs->timeout = timeout; + bzero(data, datalen); - scsi_cmd.opcode = REPORT_LUNS; - scsi_cmd.selectreport = selectreport; - _lto4b(datalen, scsi_cmd.length); + cmd = (struct scsi_report_luns *)xs->cmd; + cmd->selectreport = selectreport; + _lto4b(datalen, cmd->length); - error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)&scsi_cmd, - sizeof(scsi_cmd), (u_char *)data, datalen, SCSI_RETRIES, timeout, - NULL, flags | SCSI_DATA_IN); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); SC_DEBUG(sc_link, SDEV_DB2, ("scsi_report_luns: error = %d\n", error)); @@ -1200,59 +1301,6 @@ scsi_xs_sync_done(struct scsi_xfer *xs) mtx_leave(cookie); } -/* - * ask the scsi driver to perform a command for us. - * tell it where to read/write the data, and how - * long the data is supposed to be. If we have a buf - * to associate with the transfer, we need that too. - */ -int -scsi_scsi_cmd(struct scsi_link *link, struct scsi_generic *scsi_cmd, - int cmdlen, u_char *data_addr, int datalen, int retries, int timeout, - struct buf *bp, int flags) -{ - struct scsi_xfer *xs; - int error; - int s; - -#ifdef DIAGNOSTIC - if (bp != NULL && (flags & SCSI_NOSLEEP) == 0) - panic("scsi_scsi_cmd: buffer without nosleep"); -#endif - - xs = scsi_xs_get(link, flags); - if (xs == NULL) - return (ENOMEM); - - memcpy(xs->cmd, scsi_cmd, cmdlen); - xs->cmdlen = cmdlen; - xs->data = data_addr; - xs->datalen = datalen; - xs->retries = retries; - xs->timeout = timeout; - xs->bp = bp; - - error = scsi_xs_sync(xs); - - if (bp != NULL) { - bp->b_error = error; - if (bp->b_error) { - SET(bp->b_flags, B_ERROR); - bp->b_resid = bp->b_bcount; - } else { - CLR(bp->b_flags, B_ERROR); - bp->b_resid = xs->resid; - } - s = splbio(); - biodone(bp); - splx(s); - } - - scsi_xs_put(xs); - - return (error); -} - int scsi_xs_error(struct scsi_xfer *xs) { diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h index e3a3db133ff..86128367257 100644 --- a/sys/scsi/scsiconf.h +++ b/sys/scsi/scsiconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: scsiconf.h,v 1.131 2010/07/13 00:30:30 krw Exp $ */ +/* $OpenBSD: scsiconf.h,v 1.132 2010/07/22 00:31:06 krw Exp $ */ /* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */ /* @@ -563,9 +563,6 @@ int scsi_mode_select(struct scsi_link *, int, struct scsi_mode_header *, int scsi_mode_select_big(struct scsi_link *, int, struct scsi_mode_header_big *, int, int); void scsi_done(struct scsi_xfer *); -int scsi_scsi_cmd(struct scsi_link *, struct scsi_generic *, - int cmdlen, u_char *data_addr, int datalen, int retries, - int timeout, struct buf *bp, int flags); int scsi_do_ioctl(struct scsi_link *, u_long, caddr_t, int); void sc_print_addr(struct scsi_link *); int scsi_report_luns(struct scsi_link *, int, diff --git a/sys/scsi/ses.c b/sys/scsi/ses.c index e8d6992d083..b6674ada864 100644 --- a/sys/scsi/ses.c +++ b/sys/scsi/ses.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ses.c,v 1.47 2007/09/16 01:30:24 krw Exp $ */ +/* $OpenBSD: ses.c,v 1.48 2010/07/22 00:31:06 krw Exp $ */ /* * Copyright (c) 2005 David Gwynne @@ -257,45 +257,52 @@ ses_detach(struct device *self, int flags) int ses_read_config(struct ses_softc *sc) { - struct ses_scsi_diag cmd; - int flags; - - u_char *buf, *p; - - struct ses_config_hdr *cfg; - struct ses_enc_hdr *enc; + struct ses_scsi_diag *cmd; + struct ses_config_hdr *cfg; + struct ses_type_desc *tdh, *tdlist; #ifdef SES_DEBUG - struct ses_enc_desc *desc; + struct ses_enc_desc *desc; #endif - struct ses_type_desc *tdh, *tdlist; - - int i, ntypes = 0, nelems = 0; + struct ses_enc_hdr *enc; + struct scsi_xfer *xs; + u_char *buf, *p; + int error, i; + int flags = 0, ntypes = 0, nelems = 0; buf = malloc(SES_BUFLEN, M_DEVBUF, M_NOWAIT | M_ZERO); if (buf == NULL) return (1); - memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = RECEIVE_DIAGNOSTIC; - cmd.flags |= SES_DIAG_PCV; - cmd.pgcode = SES_PAGE_CONFIG; - cmd.length = htobe16(SES_BUFLEN); - flags = SCSI_DATA_IN; -#ifndef SCSIDEBUG - flags |= SCSI_SILENT; -#endif - if (cold) flags |= SCSI_AUTOCONF; - - if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), buf, SES_BUFLEN, 2, 3000, NULL, flags) != 0) { + xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT); + if (xs == NULL) { + free(buf, M_DEVBUF); + return (1); + } + xs->cmd->opcode = RECEIVE_DIAGNOSTIC; + xs->cmdlen = sizeof(*cmd); + xs->data = buf; + xs->datalen = SES_BUFLEN; + xs->retries = 2; + xs->timeout = 3000; + + cmd = (struct ses_scsi_diag *)xs->cmd; + cmd->flags |= SES_DIAG_PCV; + cmd->pgcode = SES_PAGE_CONFIG; + cmd->length = htobe16(SES_BUFLEN); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error) { free(buf, M_DEVBUF); return (1); } cfg = (struct ses_config_hdr *)buf; - if (cfg->pgcode != cmd.pgcode || betoh16(cfg->length) > SES_BUFLEN) { + if (cfg->pgcode != cmd->pgcode || betoh16(cfg->length) > + SES_BUFLEN) { free(buf, M_DEVBUF); return (1); } @@ -360,23 +367,31 @@ ses_read_config(struct ses_softc *sc) int ses_read_status(struct ses_softc *sc) { - struct ses_scsi_diag cmd; - int flags; - - memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = RECEIVE_DIAGNOSTIC; - cmd.flags |= SES_DIAG_PCV; - cmd.pgcode = SES_PAGE_STATUS; - cmd.length = htobe16(sc->sc_buflen); - flags = SCSI_DATA_IN; -#ifndef SCSIDEBUG - flags |= SCSI_SILENT; -#endif + struct ses_scsi_diag *cmd; + struct scsi_xfer *xs; + int error, flags = 0; + if (cold) flags |= SCSI_AUTOCONF; - - if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), sc->sc_buf, sc->sc_buflen, 2, 3000, NULL, flags) != 0) + xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT); + if (xs == NULL) + return (1); + xs->cmd->opcode = RECEIVE_DIAGNOSTIC; + xs->cmdlen = sizeof(*cmd); + xs->data = sc->sc_buf; + xs->datalen = sc->sc_buflen; + xs->retries = 2; + xs->timeout = 3000; + + cmd = (struct ses_scsi_diag *)xs->cmd; + cmd->flags |= SES_DIAG_PCV; + cmd->pgcode = SES_PAGE_STATUS; + cmd->length = htobe16(sc->sc_buflen); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error != 0) return (1); return (0); @@ -582,23 +597,31 @@ ses_ioctl(struct device *dev, u_long cmd, caddr_t addr) int ses_write_config(struct ses_softc *sc) { - struct ses_scsi_diag cmd; - int flags; - - memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = SEND_DIAGNOSTIC; - cmd.flags |= SES_DIAG_PF; - cmd.length = htobe16(sc->sc_buflen); - flags = SCSI_DATA_OUT; -#ifndef SCSIDEBUG - flags |= SCSI_SILENT; -#endif + struct ses_scsi_diag *cmd; + struct scsi_xfer *xs; + int error, flags = 0; if (cold) flags |= SCSI_AUTOCONF; - if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), sc->sc_buf, sc->sc_buflen, 2, 3000, NULL, flags) != 0) + xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_OUT | SCSI_SILENT); + if (xs == NULL) + return (1); + xs->cmd->opcode = SEND_DIAGNOSTIC; + xs->cmdlen = sizeof(*cmd); + xs->data = sc->sc_buf; + xs->datalen = sc->sc_buflen; + xs->retries = 2; + xs->timeout = 3000; + + cmd = (struct ses_scsi_diag *)xs->cmd; + cmd->flags |= SES_DIAG_PF; + cmd->length = htobe16(sc->sc_buflen); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + if (error != 0) return (1); return (0); diff --git a/sys/scsi/st.c b/sys/scsi/st.c index 10102d0a0e7..694ea6cc5b4 100644 --- a/sys/scsi/st.c +++ b/sys/scsi/st.c @@ -1,4 +1,4 @@ -/* $OpenBSD: st.c,v 1.104 2010/07/01 05:11:18 krw Exp $ */ +/* $OpenBSD: st.c,v 1.105 2010/07/22 00:31:06 krw Exp $ */ /* $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $ */ /* @@ -1372,24 +1372,35 @@ done: int st_read(struct st_softc *st, char *buf, int size, int flags) { - struct scsi_rw_tape cmd; + struct scsi_rw_tape *cmd; + struct scsi_xfer *xs; + int error; - /* - * If it's a null transfer, return immediately - */ if (size == 0) return 0; - bzero(&cmd, sizeof(cmd)); - cmd.opcode = READ; + + xs = scsi_xs_get(st->sc_link, flags | SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = READ; + xs->cmdlen = sizeof(*cmd); + xs->data = buf; + xs->datalen = size; + xs->retries = 0; + xs->timeout = ST_IO_TIME; + + cmd = (struct scsi_rw_tape *)xs->cmd; if (st->flags & ST_FIXEDBLOCKS) { - cmd.byte2 |= SRW_FIXED; + cmd->byte2 |= SRW_FIXED; _lto3b(size / (st->blksize ? st->blksize : DEF_FIXED_BSIZE), - cmd.len); + cmd->len); } else - _lto3b(size, cmd.len); - return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, - sizeof(cmd), (u_char *) buf, size, 0, ST_IO_TIME, NULL, - flags | SCSI_DATA_IN); + _lto3b(size, cmd->len); + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } /* @@ -1398,38 +1409,35 @@ st_read(struct st_softc *st, char *buf, int size, int flags) int st_read_block_limits(struct st_softc *st, int flags) { - struct scsi_block_limits cmd; struct scsi_block_limits_data block_limits; + struct scsi_block_limits *cmd; struct scsi_link *sc_link = st->sc_link; + struct scsi_xfer *xs; int error; - /* - * First check if we have it all loaded - */ if ((sc_link->flags & SDEV_MEDIA_LOADED)) - return 0; + return (0); - /* - * do a 'Read Block Limits' - */ - bzero(&cmd, sizeof(cmd)); - cmd.opcode = READ_BLOCK_LIMITS; + xs = scsi_xs_get(sc_link, flags | SCSI_DATA_IN); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = READ_BLOCK_LIMITS; + xs->cmdlen = sizeof(*cmd); + xs->data = (void *)&block_limits; + xs->datalen = sizeof(block_limits); + xs->timeout = ST_CTL_TIME; - /* - * do the command, update the global values - */ - error = scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd, - sizeof(cmd), (u_char *) &block_limits, sizeof(block_limits), - SCSI_RETRIES, ST_CTL_TIME, NULL, flags | SCSI_DATA_IN); - if (error) - return error; + error = scsi_xs_sync(xs); + scsi_xs_put(xs); - st->blkmin = _2btol(block_limits.min_length); - st->blkmax = _3btol(block_limits.max_length); + if (error == 0) { + st->blkmin = _2btol(block_limits.min_length); + st->blkmax = _3btol(block_limits.max_length); + SC_DEBUG(sc_link, SDEV_DB3, + ("(%d <= blksize <= %d)\n", st->blkmin, st->blkmax)); + } - SC_DEBUG(sc_link, SDEV_DB3, - ("(%d <= blksize <= %d)\n", st->blkmin, st->blkmax)); - return 0; + return (error); } /* @@ -1613,30 +1621,38 @@ st_mode_select(struct st_softc *st, int flags) int st_erase(struct st_softc *st, int full, int flags) { - struct scsi_erase cmd; - int tmo; + struct scsi_erase *cmd; + struct scsi_xfer *xs; + int error; + + xs = scsi_xs_get(st->sc_link, flags); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = ERASE; + xs->cmdlen = sizeof(*cmd); /* * Full erase means set LONG bit in erase command, which asks * the drive to erase the entire unit. Without this bit, we're * asking the drive to write an erase gap. */ - bzero(&cmd, sizeof(cmd)); - cmd.opcode = ERASE; + cmd = (struct scsi_erase *)xs->cmd; if (full) { - cmd.byte2 = SE_IMMED|SE_LONG; - tmo = ST_SPC_TIME; + cmd->byte2 = SE_IMMED|SE_LONG; + xs->timeout = ST_SPC_TIME; } else { - cmd.byte2 = SE_IMMED; - tmo = ST_IO_TIME; + cmd->byte2 = SE_IMMED; + xs->timeout = ST_IO_TIME; } /* * XXX We always do this asynchronously, for now. How long should * we wait if we want to (eventually) to it synchronously? */ - return (scsi_scsi_cmd(st->sc_link, (struct scsi_generic *)&cmd, - sizeof(cmd), 0, 0, SCSI_RETRIES, tmo, NULL, flags)); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); + + return (error); } /* @@ -1645,7 +1661,8 @@ st_erase(struct st_softc *st, int full, int flags) int st_space(struct st_softc *st, int number, u_int what, int flags) { - struct scsi_space cmd; + struct scsi_space *cmd; + struct scsi_xfer *xs; int error; switch (what) { @@ -1708,13 +1725,19 @@ st_space(struct st_softc *st, int number, u_int what, int flags) if (number == 0) return 0; - bzero(&cmd, sizeof(cmd)); - cmd.opcode = SPACE; - cmd.byte2 = what; - _lto3b(number, cmd.number); + xs = scsi_xs_get(st->sc_link, flags); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = SPACE; - error = scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, - sizeof(cmd), 0, 0, 0, ST_SPC_TIME, NULL, flags); + cmd = (struct scsi_space *)xs->cmd; + cmd->byte2 = what; + _lto3b(number, cmd->number); + xs->cmdlen = sizeof(*cmd); + xs->timeout = ST_SPC_TIME; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); if (error != 0) { st->media_fileno = -1; @@ -1750,15 +1773,20 @@ st_space(struct st_softc *st, int number, u_int what, int flags) int st_write_filemarks(struct st_softc *st, int number, int flags) { - struct scsi_write_filemarks cmd; + struct scsi_write_filemarks *cmd; + struct scsi_xfer *xs; int error; - /* - * It's hard to write a negative number of file marks. - * Don't try. - */ if (number < 0) - return EINVAL; + return (EINVAL); + + xs = scsi_xs_get(st->sc_link, flags); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = WRITE_FILEMARKS; + xs->cmdlen = sizeof(*cmd); + xs->timeout = ST_IO_TIME * 4; + switch (number) { case 0: /* really a command to sync the drive's buffers */ break; @@ -1771,14 +1799,14 @@ st_write_filemarks(struct st_softc *st, int number, int flags) break; default: st->flags &= ~(ST_PER_ACTION | ST_WRITTEN); + break; } - bzero(&cmd, sizeof(cmd)); - cmd.opcode = WRITE_FILEMARKS; - _lto3b(number, cmd.number); + cmd = (struct scsi_write_filemarks *)xs->cmd; + _lto3b(number, cmd->number); - error = scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, - sizeof(cmd), 0, 0, 0, ST_IO_TIME * 4, NULL, flags); + error = scsi_xs_sync(xs); + scsi_xs_put(xs); if (error != 0) { st->media_fileno = -1; @@ -1827,36 +1855,44 @@ st_check_eod(struct st_softc *st, int position, int *nmarks, int flags) int st_load(struct st_softc *st, u_int type, int flags) { - struct scsi_load cmd; + struct scsi_load *cmd; + struct scsi_xfer *xs; + int error, nmarks; st->media_fileno = -1; st->media_blkno = -1; if (type != LD_LOAD) { - int error; - int nmarks; - error = st_check_eod(st, FALSE, &nmarks, flags); if (error) - return error; + return (error); } + if (st->quirks & ST_Q_IGNORE_LOADS) { if (type == LD_LOAD) { /* * If we ignore loads, at least we should try a rewind. */ - return st_rewind(st, 0, flags); + return (st_rewind(st, 0, flags)); } return (0); } - bzero(&cmd, sizeof(cmd)); - cmd.opcode = LOAD; - cmd.how = type; + xs = scsi_xs_get(st->sc_link, flags); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = LOAD; + xs->cmdlen = sizeof(*cmd); + xs->timeout = ST_SPC_TIME; + + cmd = (struct scsi_load *)xs->cmd; + cmd->how = type; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); - return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, - sizeof(cmd), 0, 0, SCSI_RETRIES, ST_SPC_TIME, NULL, flags); + return (error); } /* @@ -1865,22 +1901,27 @@ st_load(struct st_softc *st, u_int type, int flags) int st_rewind(struct st_softc *st, u_int immediate, int flags) { - struct scsi_rewind cmd; - int error; - int nmarks; + struct scsi_rewind *cmd; + struct scsi_xfer *xs; + int error, nmarks; error = st_check_eod(st, FALSE, &nmarks, flags); if (error) - return error; + return (error); st->flags &= ~ST_PER_ACTION; - bzero(&cmd, sizeof(cmd)); - cmd.opcode = REWIND; - cmd.byte2 = immediate; + xs = scsi_xs_get(st->sc_link, flags); + if (xs == NULL) + return (ENOMEM); + xs->cmd->opcode = REWIND; + xs->cmdlen = sizeof(*cmd); + xs->timeout = immediate ? ST_CTL_TIME : ST_SPC_TIME; - error = scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd, - sizeof(cmd), 0, 0, SCSI_RETRIES, - immediate ? ST_CTL_TIME: ST_SPC_TIME, NULL, flags); + cmd = (struct scsi_rewind *)xs->cmd; + cmd->byte2 = immediate; + + error = scsi_xs_sync(xs); + scsi_xs_put(xs); if (error == 0) { st->media_fileno = 0; -- 2.20.1