diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2005-05-25 20:52:42 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2005-05-25 20:52:42 +0000 |
commit | 8864d54939803f5c472b21b73056f2f8de3d31c2 (patch) | |
tree | f48986aba38da3c117de4a5896d88caaf539aad5 /sys/scsi/sd_scsi.c | |
parent | 5c433857e84069e8f66922a2975b92e208971563 (diff) |
Introduce safer, more general mode sense capability. Transparently use
both 10 byte and 6 byte MODE SENSE commands and just return error
checked values.
Convert sd_scsi.c to use new mechanism for non-optical drives. USB
umass devices will now display actual mode sense info if it is
available via a 10 byte MODE SENSE. Which may mean 0 heads, etc. is
shown until cosmetics are finalized.
ok marco@ 'that is pretty cool' deraadt@
Diffstat (limited to 'sys/scsi/sd_scsi.c')
-rw-r--r-- | sys/scsi/sd_scsi.c | 148 |
1 files changed, 72 insertions, 76 deletions
diff --git a/sys/scsi/sd_scsi.c b/sys/scsi/sd_scsi.c index 74b46567254..47785001fc4 100644 --- a/sys/scsi/sd_scsi.c +++ b/sys/scsi/sd_scsi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sd_scsi.c,v 1.11 2005/05/24 20:48:43 krw Exp $ */ +/* $OpenBSD: sd_scsi.c,v 1.12 2005/05/25 20:52:41 krw Exp $ */ /* $NetBSD: sd_scsi.c,v 1.8 1998/10/08 20:21:13 thorpej Exp $ */ /*- @@ -138,9 +138,10 @@ sd_scsibus_get_parms(sd, dp, flags) int flags; { struct sd_scsibus_mode_sense_data scsi_sense; - union scsi_disk_pages *sense_pages; - u_int16_t rpm; - int page, error; + struct scsi_mode_sense_buf buf; + union scsi_disk_pages *sense_pages = NULL; + u_int16_t rpm = 0; + int page, error, blksize; dp->rot_rate = 3600; @@ -151,103 +152,98 @@ sd_scsibus_get_parms(sd, dp, flags) if (sd->type == T_OPTICAL) return (sd_scsibus_get_optparms(sd, dp, flags)); - error = scsi_mode_sense(sd->sc_link, 0, page = 4, - (struct scsi_mode_header *)&scsi_sense, sizeof(scsi_sense), - flags | SCSI_SILENT, 6000); + error = scsi_do_mode_sense(sd->sc_link, page = 4, &buf, + (void **)&sense_pages, NULL, NULL, &blksize, + sizeof(sense_pages->rigid_geometry), flags | SCSI_SILENT); if (error == 0) { - sense_pages = (union scsi_disk_pages *) - ((char *)&scsi_sense.blk_desc + - (size_t)scsi_sense.header.blk_desc_len); - SC_DEBUG(sd->sc_link, SDEV_DB3, - ("%d cyls, %d heads, %d precomp, %d red_write," - " %d land_zone\n", - _3btol(sense_pages->rigid_geometry.ncyl), - sense_pages->rigid_geometry.nheads, - _2btol(sense_pages->rigid_geometry.st_cyl_wp), - _2btol(sense_pages->rigid_geometry.st_cyl_rwc), - _2btol(sense_pages->rigid_geometry.land_zone))); - - /* - * KLUDGE!! (for zone recorded disks) - * give a number of sectors so that sec * trks * cyls - * is <= disk_size - * can lead to wasted space! THINK ABOUT THIS ! - */ - dp->heads = sense_pages->rigid_geometry.nheads; - dp->cyls = _3btol(sense_pages->rigid_geometry.ncyl); - rpm = _2btol(scsi_sense.pages.rigid_geometry.rpm); - if (rpm) - dp->rot_rate = rpm; - if (scsi_sense.header.blk_desc_len >= 8) - dp->blksize = _3btol(scsi_sense.blk_desc.blklen); - else - dp->blksize = 0; + if (sense_pages) { + SC_DEBUG(sd->sc_link, SDEV_DB3, + ("%d cyls, %d heads, %d precomp, %d red_write," + " %d land_zone\n", + _3btol(sense_pages->rigid_geometry.ncyl), + sense_pages->rigid_geometry.nheads, + _2btol(sense_pages->rigid_geometry.st_cyl_wp), + _2btol(sense_pages->rigid_geometry.st_cyl_rwc), + _2btol(sense_pages->rigid_geometry.land_zone))); + /* + * KLUDGE!! (for zone recorded disks) + * give a number of sectors so that sec * trks * cyls + * is <= disk_size + * can lead to wasted space! THINK ABOUT THIS ! + */ + dp->heads = sense_pages->rigid_geometry.nheads; + dp->cyls = _3btol(sense_pages->rigid_geometry.ncyl); + rpm = _2btol(sense_pages->rigid_geometry.rpm); + } + dp->disksize = scsi_size(sd->sc_link, flags); - if (dp->heads == 0 || dp->cyls == 0) + if (dp->disksize == 0 || dp->heads == 0 || dp->cyls == 0) goto fake_it; - if (dp->blksize == 0) - dp->blksize = 512; - - dp->disksize = scsi_size(sd->sc_link, flags); - if (dp->disksize == 0) - return (SDGP_RESULT_OFFLINE); - /* XXX dubious on SCSI */ dp->sectors = dp->disksize / (dp->heads * dp->cyls); + if (rpm) + dp->rot_rate = rpm; + + dp->blksize = (blksize == 0) ? 512 : blksize; + return (SDGP_RESULT_OK); } - error = scsi_mode_sense(sd->sc_link, 0, page = 5, - (struct scsi_mode_header *)&scsi_sense, sizeof(scsi_sense), - flags | SCSI_SILENT, 6000); + error = scsi_do_mode_sense(sd->sc_link, page = 5, &buf, + (void **)&sense_pages, NULL, NULL, &blksize, + sizeof(sense_pages->flex_geometry), flags | SCSI_SILENT); if (error == 0) { - sense_pages = (union scsi_disk_pages *) - ((char *)&scsi_sense.blk_desc + - (size_t)scsi_sense.header.blk_desc_len); - dp->heads = sense_pages->flex_geometry.nheads; - dp->cyls = _2btol(sense_pages->flex_geometry.ncyl); - rpm = _2btol(scsi_sense.pages.flex_geometry.rpm); - if (rpm) - dp->rot_rate = rpm; - if (scsi_sense.header.blk_desc_len >= 8) - dp->blksize = _3btol(scsi_sense.blk_desc.blklen); - else + if (sense_pages) { + dp->heads = sense_pages->flex_geometry.nheads; + dp->cyls = _2btol(sense_pages->flex_geometry.ncyl); + dp->sectors = sense_pages->flex_geometry.ph_sec_tr; dp->blksize = _2btol(sense_pages->flex_geometry.bytes_s); - dp->sectors = sense_pages->flex_geometry.ph_sec_tr; - dp->disksize = dp->heads * dp->cyls * dp->sectors; - if (dp->disksize == 0) + rpm = _2btol(scsi_sense.pages.flex_geometry.rpm); + } + if (dp->cyls == 0 || dp->heads == 0 || dp->cyls == 0) goto fake_it; - if (dp->blksize == 0) + + dp->disksize = dp->heads * dp->cyls * dp->sectors; + + if (rpm) + dp->rot_rate = rpm; + + if (blksize) + dp->blksize = blksize; + else if (dp->blksize == 0) dp->blksize = 512; + return (SDGP_RESULT_OK); } - /* T_RDIRECT define page 6. */ - error = scsi_mode_sense(sd->sc_link, 0, page = 6, - (struct scsi_mode_header *)&scsi_sense, sizeof(scsi_sense), - flags | SCSI_SILENT, 6000); + /* T_RDIRECT defines page 6. */ + if (sd->type != T_RDIRECT) + goto fake_it; + + error = scsi_do_mode_sense(sd->sc_link, page = 6, &buf, + (void **)&sense_pages, NULL, NULL, &blksize, + sizeof(sense_pages->reduced_geometry), flags | SCSI_SILENT); if (error == 0) { - sense_pages = (union scsi_disk_pages *) - ((char *)&scsi_sense.blk_desc + - (size_t)scsi_sense.header.blk_desc_len); dp->heads = 64; dp->sectors = 32; - dp->disksize = - _4btol(sense_pages->reduced_geometry.sectors+1); - dp->cyls = dp->disksize / (64 * 32); - if (scsi_sense.header.blk_desc_len >= 8) - dp->blksize = _3btol(scsi_sense.blk_desc.blklen); - else + if (sense_pages) { + dp->disksize = + _4btol(sense_pages->reduced_geometry.sectors+1); dp->blksize = _2btol(sense_pages->reduced_geometry.bytes_s); - - if (dp->disksize == 0 || - sense_pages->reduced_geometry.sectors[0] != 0) + dp->sectors = sense_pages->reduced_geometry.sectors[0]; + } + if (dp->disksize == 0 || dp->sectors == 0) goto fake_it; + dp->cyls = dp->disksize / (dp->heads * dp->sectors); + + if (blksize) + dp->blksize = blksize; + if (dp->blksize == 0) dp->blksize = 512; |