diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2005-08-23 23:38:01 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2005-08-23 23:38:01 +0000 |
commit | a9074045d5504c7dbb7754824573fdd5f298751d (patch) | |
tree | 646c7d61ac234fa6f324d7e5a3308494e08f27bd /sys | |
parent | 4fba21dffa291590a638137e2d4cd0a13ed878ce (diff) |
Move uses of struct scsi_mode_sense_buf (255 bytes each) from the
stack into malloc'd memory.
ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/scsi/cd.c | 141 | ||||
-rw-r--r-- | sys/scsi/ch.c | 17 | ||||
-rw-r--r-- | sys/scsi/sd.c | 27 | ||||
-rw-r--r-- | sys/scsi/st.c | 110 |
4 files changed, 183 insertions, 112 deletions
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c index 1b36e21938f..c49411c5741 100644 --- a/sys/scsi/cd.c +++ b/sys/scsi/cd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd.c,v 1.86 2005/08/03 23:37:07 krw Exp $ */ +/* $OpenBSD: cd.c,v 1.87 2005/08/23 23:38:00 krw Exp $ */ /* $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */ /* @@ -1364,29 +1364,33 @@ cd_setchan(cd, p0, p1, p2, p3, flags) struct cd_softc *cd; int p0, p1, p2, p3, flags; { - struct scsi_mode_sense_buf data; + struct scsi_mode_sense_buf *data; struct cd_audio_page *audio = NULL; int error, big; - error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, &data, - (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, &big); - if (error != 0) - return (error); - if (audio == NULL) - return (EIO); + data = malloc(sizeof(*data), M_TEMP, M_NOWAIT); + if (data == NULL) + return (ENOMEM); - audio->port[LEFT_PORT].channels = p0; - audio->port[RIGHT_PORT].channels = p1; - audio->port[2].channels = p2; - audio->port[3].channels = p3; + error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, data, + (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, &big); + if (error == 0 && audio == NULL) + error = EIO; - if (big) - error = scsi_mode_select_big(cd->sc_link, SMS_PF, - &data.headers.hdr_big, flags, 20000); - else - error = scsi_mode_select(cd->sc_link, SMS_PF, &data.headers.hdr, - flags, 20000); + if (error == 0) { + audio->port[LEFT_PORT].channels = p0; + audio->port[RIGHT_PORT].channels = p1; + audio->port[2].channels = p2; + audio->port[3].channels = p3; + if (big) + error = scsi_mode_select_big(cd->sc_link, SMS_PF, + &data->headers.hdr_big, flags, 20000); + else + error = scsi_mode_select(cd->sc_link, SMS_PF, + &data->headers.hdr, flags, 20000); + } + free(data, M_TEMP); return (error); } @@ -1396,22 +1400,27 @@ cd_getvol(cd, arg, flags) struct ioc_vol *arg; int flags; { - struct scsi_mode_sense_buf data; + struct scsi_mode_sense_buf *data; struct cd_audio_page *audio = NULL; int error; - error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, &data, + data = malloc(sizeof(*data), M_TEMP, M_NOWAIT); + if (data == NULL) + return (ENOMEM); + + error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, data, (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, NULL); - if (error != 0) - return (error); - if (audio == NULL) - return (EIO); - - arg->vol[0] = audio->port[0].volume; - arg->vol[1] = audio->port[1].volume; - arg->vol[2] = audio->port[2].volume; - arg->vol[3] = audio->port[3].volume; + if (error == 0 && audio == NULL) + error = EIO; + + if (error == 0) { + arg->vol[0] = audio->port[0].volume; + arg->vol[1] = audio->port[1].volume; + arg->vol[2] = audio->port[2].volume; + arg->vol[3] = audio->port[3].volume; + } + free(data, M_TEMP); return (0); } @@ -1421,30 +1430,38 @@ cd_setvol(cd, arg, flags) const struct ioc_vol *arg; int flags; { - struct scsi_mode_sense_buf data; + struct scsi_mode_sense_buf *data; struct cd_audio_page *audio = NULL; u_int8_t mask_volume[4]; int error, big; + data = malloc(sizeof(*data), M_TEMP, M_NOWAIT); + if (data == NULL) + return (ENOMEM); + error = scsi_do_mode_sense(cd->sc_link, - AUDIO_PAGE | SMS_PAGE_CTRL_CHANGEABLE, &data, (void **)&audio, NULL, + AUDIO_PAGE | SMS_PAGE_CTRL_CHANGEABLE, data, (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, NULL); - if (error != 0) + if (error == 0 && audio == NULL) + error = EIO; + if (error != 0) { + free(data, M_TEMP); return (error); - if (audio == NULL) - return (EIO); + } mask_volume[0] = audio->port[0].volume; mask_volume[1] = audio->port[1].volume; mask_volume[2] = audio->port[2].volume; mask_volume[3] = audio->port[3].volume; - error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, &data, + error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, data, (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, &big); - if (error != 0) + if (error == 0 && audio == NULL) + error = EIO; + if (error != 0) { + free(data, M_TEMP); return (error); - if (audio == NULL) - return (EIO); + } audio->port[0].volume = arg->vol[0] & mask_volume[0]; audio->port[1].volume = arg->vol[1] & mask_volume[1]; @@ -1453,11 +1470,12 @@ cd_setvol(cd, arg, flags) if (big) error = scsi_mode_select_big(cd->sc_link, SMS_PF, - &data.headers.hdr_big, flags, 20000); + &data->headers.hdr_big, flags, 20000); else - error = scsi_mode_select(cd->sc_link, SMS_PF, &data.headers.hdr, - flags, 20000); + error = scsi_mode_select(cd->sc_link, SMS_PF, + &data->headers.hdr, flags, 20000); + free(data, M_TEMP); return (error); } @@ -1482,7 +1500,7 @@ cd_set_pa_immed(cd, flags) struct cd_softc *cd; int flags; { - struct scsi_mode_sense_buf data; + struct scsi_mode_sense_buf *data; struct cd_audio_page *audio = NULL; int error, oflags, big; @@ -1490,26 +1508,31 @@ cd_set_pa_immed(cd, flags) /* XXX Noop? */ return (0); - error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, &data, + data = malloc(sizeof(*data), M_TEMP, M_NOWAIT); + if (data == NULL) + return (ENOMEM); + + error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, data, (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, &big); - if (error != 0) - return (error); - if (audio == NULL) - return (EIO); - - oflags = audio->flags; - audio->flags &= ~CD_PA_SOTC; - audio->flags |= CD_PA_IMMED; - if (audio->flags == oflags) - return (0); + if (error == 0 && audio == NULL) + error = EIO; - if (big) - error = scsi_mode_select_big(cd->sc_link, SMS_PF, - &data.headers.hdr_big, flags, 20000); - else - error = scsi_mode_select(cd->sc_link, SMS_PF, &data.headers.hdr, - flags, 20000); + if (error == 0) { + oflags = audio->flags; + audio->flags &= ~CD_PA_SOTC; + audio->flags |= CD_PA_IMMED; + if (audio->flags != oflags) { + if (big) + error = scsi_mode_select_big(cd->sc_link, + SMS_PF, &data->headers.hdr_big, flags, + 20000); + else + error = scsi_mode_select(cd->sc_link, SMS_PF, + &data->headers.hdr, flags, 20000); + } + } + free(data, M_TEMP); return (error); } diff --git a/sys/scsi/ch.c b/sys/scsi/ch.c index 4995c4c32da..13c2ba5c58a 100644 --- a/sys/scsi/ch.c +++ b/sys/scsi/ch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ch.c,v 1.21 2005/08/13 17:56:34 krw Exp $ */ +/* $OpenBSD: ch.c,v 1.22 2005/08/23 23:38:00 krw Exp $ */ /* $NetBSD: ch.c,v 1.26 1997/02/21 22:06:52 thorpej Exp $ */ /* @@ -613,22 +613,27 @@ ch_get_params(sc, flags) struct ch_softc *sc; int flags; { - struct scsi_mode_sense_buf data; + struct scsi_mode_sense_buf *data; struct page_element_address_assignment *ea; struct page_device_capabilities *cap; int error, from; u_int8_t *moves, *exchanges; + data = malloc(sizeof(*data), M_TEMP, M_NOWAIT); + if (data == NULL) + return (ENOMEM); + /* * Grab info from the element address assignment page (0x1d). */ - error = scsi_do_mode_sense(sc->sc_link, 0x1d, &data, + error = scsi_do_mode_sense(sc->sc_link, 0x1d, data, (void **)&ea, NULL, NULL, NULL, sizeof(*ea), flags, NULL); - if (ea == NULL) + if (error == 0 && ea == NULL) error = EIO; if (error != 0) { printf("%s: could not sense element address page\n", sc->sc_dev.dv_xname); + free(data, M_TEMP); return (error); } @@ -646,13 +651,14 @@ ch_get_params(sc, flags) /* * Grab info from the capabilities page (0x1f). */ - error = scsi_do_mode_sense(sc->sc_link, 0x1f, &data, + error = scsi_do_mode_sense(sc->sc_link, 0x1f, data, (void **)&cap, NULL, NULL, NULL, sizeof(*cap), flags, NULL); if (cap == NULL) error = EIO; if (error != 0) { printf("%s: could not sense capabilities page\n", sc->sc_dev.dv_xname); + free(data, M_TEMP); return (error); } @@ -666,6 +672,7 @@ ch_get_params(sc, flags) } sc->sc_link->flags |= SDEV_MEDIA_LOADED; + free(data, M_TEMP); return (0); } diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index 07577206cea..57513481242 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sd.c,v 1.87 2005/08/23 23:31:04 krw Exp $ */ +/* $OpenBSD: sd.c,v 1.88 2005/08/23 23:38:00 krw Exp $ */ /* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */ /*- @@ -1328,15 +1328,19 @@ sd_get_parms(sd, dp, flags) struct disk_parms *dp; int flags; { - struct scsi_mode_sense_buf buf; - struct page_rigid_geometry *rigid; - struct page_flex_geometry *flex; - struct page_reduced_geometry *reduced; + struct scsi_mode_sense_buf *buf; + struct page_rigid_geometry *rigid; + struct page_flex_geometry *flex; + struct page_reduced_geometry *reduced; u_int32_t heads = 0, sectors = 0, cyls = 0, blksize, ssblksize; u_int16_t rpm = 0; dp->disksize = scsi_size(sd->sc_link, flags, &ssblksize); + buf = malloc(sizeof(*buf) ,M_TEMP, M_NOWAIT); + if (buf == NULL) + goto validate; + switch (sd->sc_link->inqdata.device & SID_TYPE) { case T_OPTICAL: /* No more information needed or available. */ @@ -1344,7 +1348,7 @@ sd_get_parms(sd, dp, flags) case T_RDIRECT: /* T_RDIRECT supports only PAGE_REDUCED_GEOMETRY (6). */ - scsi_do_mode_sense(sd->sc_link, PAGE_REDUCED_GEOMETRY, &buf, + scsi_do_mode_sense(sd->sc_link, PAGE_REDUCED_GEOMETRY, buf, (void **)&reduced, NULL, NULL, &blksize, sizeof(*reduced), flags | SCSI_SILENT, NULL); if (DISK_PGCODE(reduced, PAGE_REDUCED_GEOMETRY)) { @@ -1367,7 +1371,7 @@ sd_get_parms(sd, dp, flags) if (((sd->sc_link->flags & SDEV_ATAPI) == 0) || ((sd->sc_link->flags & SDEV_REMOVABLE) == 0)) scsi_do_mode_sense(sd->sc_link, PAGE_RIGID_GEOMETRY, - &buf, (void **)&rigid, NULL, NULL, &blksize, + buf, (void **)&rigid, NULL, NULL, &blksize, sizeof(*rigid) - 4, flags | SCSI_SILENT, NULL); if (DISK_PGCODE(rigid, PAGE_RIGID_GEOMETRY)) { heads = rigid->nheads; @@ -1377,7 +1381,7 @@ sd_get_parms(sd, dp, flags) sectors = dp->disksize / (heads * cyls); } else { scsi_do_mode_sense(sd->sc_link, PAGE_FLEX_GEOMETRY, - &buf, (void **)&flex, NULL, NULL, &blksize, + buf, (void **)&flex, NULL, NULL, &blksize, sizeof(*flex) - 4, flags | SCSI_SILENT, NULL); if (DISK_PGCODE(flex, PAGE_FLEX_GEOMETRY)) { sectors = flex->ph_sec_tr; @@ -1393,8 +1397,11 @@ sd_get_parms(sd, dp, flags) break; } - if (dp->disksize == 0) +validate: + if (dp->disksize == 0) { + free(buf, M_TEMP); return (SDGP_RESULT_OFFLINE); + } if (ssblksize > 0) dp->blksize = ssblksize; else @@ -1416,6 +1423,7 @@ sd_get_parms(sd, dp, flags) default: SC_DEBUG(sd->sc_link, SDEV_DB1, ("sd_get_parms: bad blksize: %#x\n", dp->blksize)); + free(buf, M_TEMP); return (SDGP_RESULT_OFFLINE); } @@ -1437,6 +1445,7 @@ sd_get_parms(sd, dp, flags) dp->cyls = (cyls == 0) ? dp->disksize / (dp->heads * dp->sectors) : cyls; + free(buf, M_TEMP); return (SDGP_RESULT_OK); } diff --git a/sys/scsi/st.c b/sys/scsi/st.c index 2d0c2accc2d..22233566c0d 100644 --- a/sys/scsi/st.c +++ b/sys/scsi/st.c @@ -1,4 +1,4 @@ -/* $OpenBSD: st.c,v 1.48 2005/06/24 20:48:25 krw Exp $ */ +/* $OpenBSD: st.c,v 1.49 2005/08/23 23:38:00 krw Exp $ */ /* $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $ */ /* @@ -1421,7 +1421,7 @@ st_mode_sense(st, flags) struct st_softc *st; int flags; { - struct scsi_mode_sense_buf data; + struct scsi_mode_sense_buf *data; struct scsi_link *sc_link = st->sc_link; u_int64_t block_count; u_int32_t density, block_size; @@ -1429,20 +1429,26 @@ st_mode_sense(st, flags) u_int8_t dev_spec; int error, big; + data = malloc(sizeof(*data), M_TEMP, M_NOWAIT); + if (data == NULL) + return (ENOMEM); + /* * Ask for page 0 (vendor specific) mode sense data. */ - error = scsi_do_mode_sense(sc_link, 0, &data, (void **)&page0, + error = scsi_do_mode_sense(sc_link, 0, data, (void **)&page0, &density, &block_count, &block_size, 1, flags | SCSI_SILENT, &big); - if (error != 0) + if (error != 0) { + free(data, M_TEMP); return (error); + } /* It is valid for no page0 to be available. */ if (big) - dev_spec = data.headers.hdr_big.dev_spec; + dev_spec = data->headers.hdr_big.dev_spec; else - dev_spec = data.headers.hdr.dev_spec; + dev_spec = data->headers.hdr.dev_spec; if (dev_spec & SMH_DSP_WRITE_PROT) st->flags |= ST_READONLY; @@ -1461,8 +1467,9 @@ st_mode_sense(st, flags) ("%sbuffered\n", dev_spec & SMH_DSP_BUFF_MODE ? "" : "un")); sc_link->flags |= SDEV_MEDIA_LOADED; - - return 0; + + free(data, M_TEMP); + return (0); } /* @@ -1474,12 +1481,21 @@ st_mode_select(st, flags) struct st_softc *st; int flags; { - struct scsi_mode_sense_buf inbuf, outbuf; + struct scsi_mode_sense_buf *inbuf, *outbuf; struct scsi_blk_desc general; struct scsi_link *sc_link = st->sc_link; u_int8_t *page0 = NULL; int error, big, page0_size; + inbuf = malloc(sizeof(*inbuf), M_TEMP, M_NOWAIT); + if (inbuf == NULL) + return (ENOMEM); + outbuf = malloc(sizeof(*outbuf), M_TEMP, M_NOWAIT); + if (outbuf == NULL) { + free(inbuf, M_TEMP); + return (ENOMEM); + } + /* * This quirk deals with drives that have only one valid mode and think * this gives them license to reject all mode selects, even if the @@ -1489,13 +1505,18 @@ st_mode_select(st, flags) SC_DEBUG(sc_link, SDEV_DB3, ("not setting density 0x%x blksize 0x%x\n", st->density, st->blksize)); - return 0; + free(inbuf, M_TEMP); + free(outbuf, M_TEMP); + return (0); } - if (sc_link->flags & SDEV_ATAPI) - return 0; + if (sc_link->flags & SDEV_ATAPI) { + free(inbuf, M_TEMP); + free(outbuf, M_TEMP); + return (0); + } - bzero(&outbuf, sizeof(outbuf)); + bzero(outbuf, sizeof(*outbuf)); bzero(&general, sizeof(general)); general.density = st->density; @@ -1505,25 +1526,29 @@ st_mode_select(st, flags) /* * Ask for page 0 (vendor specific) mode sense data. */ - error = scsi_do_mode_sense(sc_link, 0, &inbuf, (void **)&page0, NULL, + error = scsi_do_mode_sense(sc_link, 0, inbuf, (void **)&page0, NULL, NULL, NULL, 1, flags | SCSI_SILENT, &big); - if (error != 0) + if (error != 0) { + free(inbuf, M_TEMP); + free(outbuf, M_TEMP); return (error); + } if (page0 == NULL) { page0_size = 0; } else if (big == 0) { - page0_size = inbuf.headers.hdr.data_length + - sizeof(inbuf.headers.hdr.data_length) - - sizeof(inbuf.headers.hdr) - inbuf.headers.hdr.blk_desc_len; - memcpy(&outbuf.headers.buf[sizeof(outbuf.headers.hdr)+ + page0_size = inbuf->headers.hdr.data_length + + sizeof(inbuf->headers.hdr.data_length) - + sizeof(inbuf->headers.hdr) - + inbuf->headers.hdr.blk_desc_len; + memcpy(&outbuf->headers.buf[sizeof(outbuf->headers.hdr)+ sizeof(general)], page0, page0_size); } else { - page0_size = _2btol(inbuf.headers.hdr_big.data_length) + - sizeof(inbuf.headers.hdr_big.data_length) - - sizeof(inbuf.headers.hdr_big) - - _2btol(inbuf.headers.hdr_big.blk_desc_len); - memcpy(&outbuf.headers.buf[sizeof(outbuf.headers.hdr_big) + + page0_size = _2btol(inbuf->headers.hdr_big.data_length) + + sizeof(inbuf->headers.hdr_big.data_length) - + sizeof(inbuf->headers.hdr_big) - + _2btol(inbuf->headers.hdr_big.blk_desc_len); + memcpy(&outbuf->headers.buf[sizeof(outbuf->headers.hdr_big) + sizeof(general)], page0, page0_size); } @@ -1531,29 +1556,36 @@ st_mode_select(st, flags) * Set up for a mode select. */ if (big == 0) { - outbuf.headers.hdr.data_length = sizeof(outbuf.headers.hdr) + + outbuf->headers.hdr.data_length = sizeof(outbuf->headers.hdr) + sizeof(general) + page0_size - - sizeof(outbuf.headers.hdr.data_length); + sizeof(outbuf->headers.hdr.data_length); if ((st->flags & ST_DONTBUFFER) == 0) - outbuf.headers.hdr.dev_spec = SMH_DSP_BUFF_MODE_ON; - outbuf.headers.hdr.blk_desc_len = sizeof(general); - memcpy(&outbuf.headers.buf[sizeof(outbuf.headers.hdr)], + outbuf->headers.hdr.dev_spec = SMH_DSP_BUFF_MODE_ON; + outbuf->headers.hdr.blk_desc_len = sizeof(general); + memcpy(&outbuf->headers.buf[sizeof(outbuf->headers.hdr)], &general, sizeof(general)); - return (scsi_mode_select(st->sc_link, 0, &outbuf.headers.hdr, - flags, ST_CTL_TIME)); + error = scsi_mode_select(st->sc_link, 0, &outbuf->headers.hdr, + flags, ST_CTL_TIME); + free(inbuf, M_TEMP); + free(outbuf, M_TEMP); + return (error); } /* MODE SENSE (10) header was returned, so use MODE SELECT (10). */ - _lto2b((sizeof(outbuf.headers.hdr_big) + sizeof(general) + page0_size - - sizeof(outbuf.headers.hdr_big.data_length)), - outbuf.headers.hdr_big.data_length); + _lto2b((sizeof(outbuf->headers.hdr_big) + sizeof(general) + page0_size - + sizeof(outbuf->headers.hdr_big.data_length)), + outbuf->headers.hdr_big.data_length); if ((st->flags & ST_DONTBUFFER) == 0) - outbuf.headers.hdr_big.dev_spec = SMH_DSP_BUFF_MODE_ON; - _lto2b(sizeof(general), outbuf.headers.hdr_big.blk_desc_len); - memcpy(&outbuf.headers.buf[sizeof(outbuf.headers.hdr_big)], &general, + outbuf->headers.hdr_big.dev_spec = SMH_DSP_BUFF_MODE_ON; + _lto2b(sizeof(general), outbuf->headers.hdr_big.blk_desc_len); + memcpy(&outbuf->headers.buf[sizeof(outbuf->headers.hdr_big)], &general, sizeof(general)); - return (scsi_mode_select_big(st->sc_link, 0, &outbuf.headers.hdr_big, - flags, ST_CTL_TIME)); + + error = scsi_mode_select_big(st->sc_link, 0, &outbuf->headers.hdr_big, + flags, ST_CTL_TIME); + free(inbuf, M_TEMP); + free(outbuf, M_TEMP); + return (error); } /* |