summaryrefslogtreecommitdiffstats
path: root/sys/scsi
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1997-12-29 07:49:31 +0000
committerjulian <julian@FreeBSD.org>1997-12-29 07:49:31 +0000
commita13419db88e50802188382f3b17472bbe150ac38 (patch)
tree4aa10509ce4c3cf510f08e1e5a39d238ce8ee58a /sys/scsi
parentab8e3efb1c245337feb2531e75ec5961a37154d6 (diff)
downloadFreeBSD-src-a13419db88e50802188382f3b17472bbe150ac38.zip
FreeBSD-src-a13419db88e50802188382f3b17472bbe150ac38.tar.gz
If available, use the device's LOGICAL blocksize as reported by
the "READ_CAPACITY" command, rather than the physical blocksize reported in the physical geometry code-page. Also don't print out worrying bogus messages when probing a device that has no media. There's no point in printing out something that is unknowable. It just confuses things. Move the check for valid blocksize out of 'open()' to the subroutine that actually finds this out, thus probe/attach can also report and act on the problem.
Diffstat (limited to 'sys/scsi')
-rw-r--r--sys/scsi/sd.c122
1 files changed, 69 insertions, 53 deletions
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index 233d423..0d5200c 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -15,7 +15,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
*
- * $Id: sd.c,v 1.116 1997/12/06 14:27:56 bde Exp $
+ * $Id: sd.c,v 1.118 1997/12/28 09:10:37 julian Exp $
*/
#include "opt_bounce.h"
@@ -71,7 +71,7 @@ static errval sd_get_parms __P((int unit, int flags));
#if 0
static errval sd_reassign_blocks __P((int unit, int block));
#endif
-static u_int32_t sd_size __P((int unit, int flags));
+static int sd_size(int unit, u_int32_t *sizep, u_int16_t *secsizep, int flags);
static void sdstrategy1 __P((struct buf *));
static int sd_sense_handler __P((struct scsi_xfer *));
@@ -197,29 +197,30 @@ sdattach(struct scsi_link *sc_link)
/*
* Use the subdriver to request information regarding
* the drive. We cannot use interrupts yet, so the
- * request must specify this.
+ * request must specify this. This may fail with removable media.
*/
- sd_get_parms(unit, SCSI_NOSLEEP | SCSI_NOMASK);
- /*
- * if we don't have actual parameters, assume 512 bytes/sec
- * (could happen on removable media - MOD)
- * -- this avoids the division below from falling over
- */
- if(dp->secsiz == 0) dp->secsiz = SECSIZE;
- printf("%ldMB (%ld %d byte sectors)",
- dp->disksize / ((1024L * 1024L) / dp->secsiz),
- dp->disksize,
- dp->secsiz);
+ if (sd_get_parms(unit, SCSI_NOSLEEP | SCSI_NOMASK) == 0) {
+ /*
+ * if we don't have actual parameters, assume 512 bytes/sec
+ * (could happen on removable media - MOD)
+ * -- this avoids the division below from falling over
+ */
+ printf("%ldMB (%ld %d byte sectors)",
+ dp->disksize / ((1024L * 1024L) / dp->secsiz),
+ dp->disksize,
+ dp->secsiz);
#ifndef SCSI_REPORT_GEOMETRY
- if ( (sc_link->flags & SDEV_BOOTVERBOSE) )
+ if ( (sc_link->flags & SDEV_BOOTVERBOSE) )
#endif
- {
- sc_print_addr(sc_link);
- printf("with %d cyls, %d heads, and an average %d sectors/track",
- dp->cyls, dp->heads, dp->sectors);
+ {
+ sc_print_addr(sc_link);
+ printf("with %d cyls, %d heads, and an average %d sectors/track",
+ dp->cyls, dp->heads, dp->sectors);
+ }
+ } else {
+ printf("Media parameters not available");
}
-
sd->flags |= SDINIT;
sd_registerdev(unit);
@@ -318,18 +319,6 @@ sd_open(dev, mode, fmt, p, sc_link)
*/
if(errcode = sd_get_parms(unit, 0)) /* sets SDEV_MEDIA_LOADED */
goto bad;
- switch (sd->params.secsiz) {
- case 512:
- case 1024:
- case 2048:
- break;
- default:
- printf("sd%ld: Can't deal with %d bytes logical blocks\n",
- unit, sd->params.secsiz);
- Debugger("sd");
- errcode = ENXIO;
- goto bad;
- }
SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded "));
@@ -686,15 +675,16 @@ sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p,
}
/*
- * Find out from the device what it's capacity is
+ * Find out from the device what it's capacity is. It turns
+ * out this is also the best way to find out the sector size.
*/
-static u_int32_t
-sd_size(unit, flags)
- int unit, flags;
+static int
+sd_size(int unit, u_int32_t *sizep, u_int16_t *secsizep, int flags)
{
struct scsi_read_cap_data rdcap;
struct scsi_read_capacity scsi_cmd;
u_int32_t size;
+ u_int32_t secsize;
struct scsi_link *sc_link = SCSI_LINK(&sd_switch, unit);
/*
@@ -718,14 +708,19 @@ sd_size(unit, flags)
NULL,
flags | SCSI_DATA_IN) != 0) {
printf("sd%d: could not get size\n", unit);
- return (0);
- } else {
- size = rdcap.addr_0 + 1;
- size += rdcap.addr_1 << 8;
- size += rdcap.addr_2 << 16;
- size += rdcap.addr_3 << 24;
+ return (ENXIO);
}
- return (size);
+ size = rdcap.addr_0 + 1;
+ size += rdcap.addr_1 << 8;
+ size += rdcap.addr_2 << 16;
+ size += rdcap.addr_3 << 24;
+ secsize = rdcap.length_0;
+ secsize += rdcap.length_1 << 8;
+ secsize += rdcap.length_2 << 16;
+ secsize += rdcap.length_3 << 24;
+ *secsizep = secsize;
+ *sizep = size;
+ return (0);
}
#if 0
@@ -769,10 +764,11 @@ sd_reassign_blocks(unit, block)
* Get the scsi driver to send a full inquiry to the
* device and use the results to fill out the disk
* parameter structure.
+ * Even if we get an error, complete with some dummy information.
+ * XXX this is backwards. The read_cap (sd_size()) should be done first.
*/
static errval
-sd_get_parms(unit, flags)
- int unit, flags;
+sd_get_parms(int unit, int flags)
{
struct scsi_link *sc_link = SCSI_LINK(&sd_switch, unit);
struct scsi_data *sd = sc_link->sd;
@@ -784,6 +780,7 @@ sd_get_parms(unit, flags)
union disk_pages pages;
} scsi_sense;
u_int32_t sectors;
+ int error = 0;
/*
* First check if we have it all loaded
@@ -823,11 +820,14 @@ sd_get_parms(unit, flags)
* this depends on which controller (e.g. 1542C is
* different. but we have to put SOMETHING here..)
*/
- sectors = sd_size(unit, flags);
+ if (error = sd_size(unit, &sectors, &disk_parms->secsiz, flags)) {
+ /* we couldn't get anyhthing. removable? */
+ sectors = 32 * 64;
+ disk_parms->secsiz= DEV_BSIZE;;
+ }
disk_parms->heads = 64;
disk_parms->sectors = 32;
disk_parms->cyls = sectors / (64 * 32);
- disk_parms->secsiz = SECSIZE;
disk_parms->disksize = sectors;
} else {
@@ -846,16 +846,21 @@ sd_get_parms(unit, flags)
* can lead to wasted space! THINK ABOUT THIS !
*/
disk_parms->heads = scsi_sense.pages.rigid_geometry.nheads;
- disk_parms->cyls = scsi_3btou(&scsi_sense.pages.rigid_geometry.ncyl_2);
+ disk_parms->cyls = scsi_3btou(
+ &scsi_sense.pages.rigid_geometry.ncyl_2);
+ /* set in a default value */
disk_parms->secsiz = scsi_3btou(scsi_sense.blk_desc.blklen);
- sectors = sd_size(unit, flags);
+ if (error = sd_size(unit, &sectors,
+ &disk_parms->secsiz, flags)) {
+ /* we couldn't get anyhthing. removable? */
+ sectors = 64 * 32; /* just so non 0 */
+ }
disk_parms->disksize = sectors;
/* Check if none of these values are zero */
if(disk_parms->heads && disk_parms->cyls) {
sectors /= (disk_parms->heads * disk_parms->cyls);
- }
- else {
+ } else {
/* set it to something reasonable */
disk_parms->heads = 64;
disk_parms->cyls = sectors / (64 * 32);
@@ -866,8 +871,19 @@ sd_get_parms(unit, flags)
disk_parms->secsiz = SECSIZE;
disk_parms->sectors = sectors; /* dubious on SCSI *//*XXX */
}
- sc_link->flags |= SDEV_MEDIA_LOADED;
- return 0;
+ switch (sd->params.secsiz) {
+ case 512:
+ case 1024:
+ case 2048:
+ break;
+ default:
+ printf("sd%ld: Can't deal with %d bytes logical blocks\n",
+ unit, sd->params.secsiz);
+ error = ENXIO;
+ }
+ if (error == 0)
+ sc_link->flags |= SDEV_MEDIA_LOADED;
+ return (error);
}
static int
OpenPOWER on IntegriCloud