-/* $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 $ */
/*
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
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);
}
/*
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);
}
/*
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);
}
/*
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);
}
/*
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);
}
/*
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
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);
}
}
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));
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)
-/* $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 $ */
/*
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;
/*
/*
* 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
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;
/*
/*
* 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
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;
/*
/*
* 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);
}
/*
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
-/* $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 <dlg@openbsd.org>
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);
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
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"
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;
}
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:
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 */
-/* $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 $ */
/*
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;
/*
* 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));
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));
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);
}
/*
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;
*/
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;
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);
}
/*
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);
}
/*
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
*/
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));
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
*/
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));
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));
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));
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));
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)
{
-/* $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 $ */
/*
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,
-/* $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 <dlg@openbsd.org>
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);
}
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);
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);
-/* $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 $ */
/*
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);
}
/*
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);
}
/*
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);
}
/*
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) {
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;
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;
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;
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);
}
/*
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;