- Apply PR/2535: Add support for flex scsi disks.

- Add a quirk called SCSI_NOMODESENSE for drives like the iomega jaz,
  that don't support mode sense.
This commit is contained in:
christos 1996-07-05 16:19:02 +00:00
parent ec3f2031a8
commit 7e1c82f6f4
10 changed files with 228 additions and 90 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsi_base.c,v 1.36 1996/05/03 19:48:20 christos Exp $ */
/* $NetBSD: scsi_base.c,v 1.37 1996/07/05 16:19:02 christos Exp $ */
/*
* Copyright (c) 1994, 1995 Charles Hannum. All rights reserved.
@ -683,6 +683,8 @@ scsi_interpret_sense(xs)
case 0x5: /* ILLEGAL REQUEST */
if ((xs->flags & SCSI_IGNORE_ILLEGAL_REQUEST) != 0)
return 0;
if ((xs->flags & SCSI_SILENT) != 0)
return EIO;
error = EINVAL;
break;
case 0x6: /* UNIT ATTENTION */

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsi_disk.h,v 1.9 1996/03/19 03:05:15 mycroft Exp $ */
/* $NetBSD: scsi_disk.h,v 1.10 1996/07/05 16:19:05 christos Exp $ */
/*
* SCSI interface description
@ -174,6 +174,36 @@ union disk_pages {
u_int8_t reserved2;
u_int8_t reserved3;
} rigid_geometry;
struct page_flex_geometry {
u_int8_t pg_code; /* page code (should be 5) */
u_int8_t pg_length; /* page length (should be 0x1e) */
u_int8_t xfr_rate[2];
u_int8_t nheads; /* number of heads */
u_int8_t ph_sec_tr; /* physical sectors per track */
u_int8_t bytes_s[2]; /* bytes per sector */
u_int8_t ncyl[2]; /* number of cylinders */
u_int8_t st_cyl_wp[2]; /* start cyl., write precomp */
u_int8_t st_cyl_rwc[2]; /* start cyl., red. write cur */
u_int8_t driv_step[2]; /* drive step rate */
u_int8_t driv_step_w; /* drive step pulse width */
u_int8_t head_settle[2];/* head settle delay */
u_int8_t motor_on; /* motor on delay */
u_int8_t motor_off; /* motor off delay */
u_int8_t flags; /* various flags */
#define MOTOR_ON 0x20 /* motor on (pin 16)? */
#define START_AT_SECTOR_1 0x40 /* start at sector 1 */
#define READY_VALID 0x20 /* RDY (pin 34) valid */
u_int8_t step_p_cyl; /* step pulses per cylinder */
u_int8_t write_pre; /* write precompensation */
u_int8_t head_load; /* head load delay */
u_int8_t head_unload; /* head unload delay */
u_int8_t pin_34_2; /* pin 34 (6) pin 2 (7/11) definition */
u_int8_t pin_4_1; /* pin 4 (8/9) pin 1 (13) definition */
u_int8_t reserved1;
u_int8_t reserved2;
u_int8_t reserved3;
u_int8_t reserved4;
} flex_geometry;
};
#endif /* _SCSI_SCSI_DISK_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */
/* $NetBSD: scsiconf.c,v 1.58 1996/07/05 16:19:08 christos Exp $ */
/*
* Copyright (c) 1994 Charles Hannum. All rights reserved.
@ -346,7 +346,8 @@ struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
"SEAGATE ", "ST296N ", ""}, SDEV_NOLUNS},
{{T_DIRECT, T_FIXED,
"TOSHIBA ", "MK538FB ", "6027"}, SDEV_NOLUNS},
{{T_DIRECT, T_REMOV,
"iomega", "jaz 1GB", ""}, SDEV_NOMODESENSE},
/* XXX: QIC-36 tape behind Emulex adapter. Very broken. */
{{T_SEQUENTIAL, T_REMOV,

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsiconf.h,v 1.29 1996/03/19 03:05:15 mycroft Exp $ */
/* $NetBSD: scsiconf.h,v 1.30 1996/07/05 16:19:12 christos Exp $ */
/*
* Copyright (c) 1993, 1994, 1995 Charles Hannum. All rights reserved.
@ -151,6 +151,7 @@ struct scsi_link {
#define SDEV_NOSYNCWIDE 0x02 /* does not grok SDTR or WDTR */
#define SDEV_NOLUNS 0x04 /* does not grok LUNs */
#define SDEV_FORCELUNS 0x08 /* prehistoric drive/ctlr groks LUNs */
#define SDEV_NOMODESENSE 0x10 /* removable media/optical drives */
struct scsi_device *device; /* device entry points etc. */
void *device_softc; /* needed for call to foo_start */
struct scsi_adapter *adapter; /* adapter entry points etc. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: sd.c,v 1.101 1996/06/04 23:12:14 thorpej Exp $ */
/* $NetBSD: sd.c,v 1.102 1996/07/05 16:19:16 christos Exp $ */
/*
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
@ -97,6 +97,12 @@ struct sd_softc {
struct buf buf_queue;
};
struct scsi_mode_sense_data {
struct scsi_mode_header header;
struct scsi_blk_desc blk_desc;
union disk_pages pages;
} scsi_sense;
int sdmatch __P((struct device *, void *, void *));
void sdattach __P((struct device *, struct device *, void *));
int sdlock __P((struct sd_softc *));
@ -107,6 +113,8 @@ void sdstart __P((void *));
int sddone __P((struct scsi_xfer *, int));
int sd_reassign_blocks __P((struct sd_softc *, u_long));
int sd_get_parms __P((struct sd_softc *, int));
static int sd_mode_sense __P((struct sd_softc *, struct scsi_mode_sense_data *,
int, int));
struct cfattach sd_ca = {
sizeof(struct sd_softc), sdmatch, sdattach
@ -821,6 +829,29 @@ sd_reassign_blocks(sd, blkno)
5000, NULL, SCSI_DATA_OUT);
}
static int
sd_mode_sense(sd, scsi_sense, page, flags)
struct sd_softc *sd;
struct scsi_mode_sense_data *scsi_sense;
int page, flags;
{
struct scsi_mode_sense scsi_cmd;
bzero(&scsi_cmd, sizeof(scsi_cmd));
scsi_cmd.opcode = MODE_SENSE;
scsi_cmd.page = page;
scsi_cmd.length = 0x20;
/*
* If the command worked, use the results to fill out
* the parameter structure
*/
return scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd,
sizeof(scsi_cmd), (u_char *)scsi_sense, sizeof(*scsi_sense),
SDRETRIES, 6000, NULL, flags | SCSI_DATA_IN | SCSI_SILENT);
}
/*
* Get the scsi driver to send a full inquiry to the * device and use the
* results to fill out the disk parameter structure.
@ -831,43 +862,12 @@ sd_get_parms(sd, flags)
int flags;
{
struct disk_parms *dp = &sd->params;
struct scsi_mode_sense scsi_cmd;
struct scsi_mode_sense_data {
struct scsi_mode_header header;
struct scsi_blk_desc blk_desc;
union disk_pages pages;
} scsi_sense;
struct scsi_mode_sense_data scsi_sense;
u_long sectors;
int page;
int error;
/*
* do a "mode sense page 4"
*/
bzero(&scsi_cmd, sizeof(scsi_cmd));
scsi_cmd.opcode = MODE_SENSE;
scsi_cmd.page = 4;
scsi_cmd.length = 0x20;
/*
* If the command worked, use the results to fill out
* the parameter structure
*/
if (scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd,
sizeof(scsi_cmd), (u_char *)&scsi_sense, sizeof(scsi_sense),
SDRETRIES, 6000, NULL, flags | SCSI_DATA_IN) != 0) {
printf("%s: could not mode sense (4)", sd->sc_dev.dv_xname);
fake_it:
printf("; using fictitious geometry\n");
/*
* use adaptec standard fictitious geometry
* this depends on which controller (e.g. 1542C is
* different. but we have to put SOMETHING here..)
*/
sectors = scsi_size(sd->sc_link, flags);
dp->heads = 64;
dp->sectors = 32;
dp->cyls = sectors / (64 * 32);
dp->blksize = 512;
dp->disksize = sectors;
} else {
if ((error = sd_mode_sense(sd, &scsi_sense, page = 4, flags)) == 0) {
SC_DEBUG(sd->sc_link, SDEV_DB3,
("%d cyls, %d heads, %d precomp, %d red_write, %d land_zone\n",
_3btol(scsi_sense.pages.rigid_geometry.ncyl),
@ -886,11 +886,8 @@ sd_get_parms(sd, flags)
dp->cyls = _3btol(scsi_sense.pages.rigid_geometry.ncyl);
dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
if (dp->heads == 0 || dp->cyls == 0) {
printf("%s: mode sense (4) returned nonsense",
sd->sc_dev.dv_xname);
if (dp->heads == 0 || dp->cyls == 0)
goto fake_it;
}
if (dp->blksize == 0)
dp->blksize = 512;
@ -899,8 +896,46 @@ sd_get_parms(sd, flags)
dp->disksize = sectors;
sectors /= (dp->heads * dp->cyls);
dp->sectors = sectors; /* XXX dubious on SCSI */
return 0;
}
if ((error = sd_mode_sense(sd, &scsi_sense, page = 5, flags)) == 0) {
dp->heads = scsi_sense.pages.flex_geometry.nheads;
dp->cyls = _2btol(scsi_sense.pages.flex_geometry.ncyl);
dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
dp->sectors = scsi_sense.pages.flex_geometry.ph_sec_tr;
dp->disksize = dp->heads * dp->cyls * dp->sectors;
if (dp->disksize == 0)
goto fake_it;
if (dp->blksize == 0)
dp->blksize = 512;
return 0;
}
fake_it:
if ((sd->sc_link->quirks & SDEV_NOMODESENSE) == 0) {
if (error == 0)
printf("%s: mode sense (%d) returned nonsense",
sd->sc_dev.dv_xname, page);
else
printf("%s: could not mode sense (4/5)",
sd->sc_dev.dv_xname);
printf("; using fictitious geometry\n");
}
/*
* use adaptec standard fictitious geometry
* this depends on which controller (e.g. 1542C is
* different. but we have to put SOMETHING here..)
*/
sectors = scsi_size(sd->sc_link, flags);
dp->heads = 64;
dp->sectors = 32;
dp->cyls = sectors / (64 * 32);
dp->blksize = 512;
dp->disksize = sectors;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsi_base.c,v 1.36 1996/05/03 19:48:20 christos Exp $ */
/* $NetBSD: scsi_base.c,v 1.37 1996/07/05 16:19:02 christos Exp $ */
/*
* Copyright (c) 1994, 1995 Charles Hannum. All rights reserved.
@ -683,6 +683,8 @@ scsi_interpret_sense(xs)
case 0x5: /* ILLEGAL REQUEST */
if ((xs->flags & SCSI_IGNORE_ILLEGAL_REQUEST) != 0)
return 0;
if ((xs->flags & SCSI_SILENT) != 0)
return EIO;
error = EINVAL;
break;
case 0x6: /* UNIT ATTENTION */

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsi_disk.h,v 1.9 1996/03/19 03:05:15 mycroft Exp $ */
/* $NetBSD: scsi_disk.h,v 1.10 1996/07/05 16:19:05 christos Exp $ */
/*
* SCSI interface description
@ -174,6 +174,36 @@ union disk_pages {
u_int8_t reserved2;
u_int8_t reserved3;
} rigid_geometry;
struct page_flex_geometry {
u_int8_t pg_code; /* page code (should be 5) */
u_int8_t pg_length; /* page length (should be 0x1e) */
u_int8_t xfr_rate[2];
u_int8_t nheads; /* number of heads */
u_int8_t ph_sec_tr; /* physical sectors per track */
u_int8_t bytes_s[2]; /* bytes per sector */
u_int8_t ncyl[2]; /* number of cylinders */
u_int8_t st_cyl_wp[2]; /* start cyl., write precomp */
u_int8_t st_cyl_rwc[2]; /* start cyl., red. write cur */
u_int8_t driv_step[2]; /* drive step rate */
u_int8_t driv_step_w; /* drive step pulse width */
u_int8_t head_settle[2];/* head settle delay */
u_int8_t motor_on; /* motor on delay */
u_int8_t motor_off; /* motor off delay */
u_int8_t flags; /* various flags */
#define MOTOR_ON 0x20 /* motor on (pin 16)? */
#define START_AT_SECTOR_1 0x40 /* start at sector 1 */
#define READY_VALID 0x20 /* RDY (pin 34) valid */
u_int8_t step_p_cyl; /* step pulses per cylinder */
u_int8_t write_pre; /* write precompensation */
u_int8_t head_load; /* head load delay */
u_int8_t head_unload; /* head unload delay */
u_int8_t pin_34_2; /* pin 34 (6) pin 2 (7/11) definition */
u_int8_t pin_4_1; /* pin 4 (8/9) pin 1 (13) definition */
u_int8_t reserved1;
u_int8_t reserved2;
u_int8_t reserved3;
u_int8_t reserved4;
} flex_geometry;
};
#endif /* _SCSI_SCSI_DISK_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */
/* $NetBSD: scsiconf.c,v 1.58 1996/07/05 16:19:08 christos Exp $ */
/*
* Copyright (c) 1994 Charles Hannum. All rights reserved.
@ -346,7 +346,8 @@ struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
"SEAGATE ", "ST296N ", ""}, SDEV_NOLUNS},
{{T_DIRECT, T_FIXED,
"TOSHIBA ", "MK538FB ", "6027"}, SDEV_NOLUNS},
{{T_DIRECT, T_REMOV,
"iomega", "jaz 1GB", ""}, SDEV_NOMODESENSE},
/* XXX: QIC-36 tape behind Emulex adapter. Very broken. */
{{T_SEQUENTIAL, T_REMOV,

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsiconf.h,v 1.29 1996/03/19 03:05:15 mycroft Exp $ */
/* $NetBSD: scsiconf.h,v 1.30 1996/07/05 16:19:12 christos Exp $ */
/*
* Copyright (c) 1993, 1994, 1995 Charles Hannum. All rights reserved.
@ -151,6 +151,7 @@ struct scsi_link {
#define SDEV_NOSYNCWIDE 0x02 /* does not grok SDTR or WDTR */
#define SDEV_NOLUNS 0x04 /* does not grok LUNs */
#define SDEV_FORCELUNS 0x08 /* prehistoric drive/ctlr groks LUNs */
#define SDEV_NOMODESENSE 0x10 /* removable media/optical drives */
struct scsi_device *device; /* device entry points etc. */
void *device_softc; /* needed for call to foo_start */
struct scsi_adapter *adapter; /* adapter entry points etc. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: sd.c,v 1.101 1996/06/04 23:12:14 thorpej Exp $ */
/* $NetBSD: sd.c,v 1.102 1996/07/05 16:19:16 christos Exp $ */
/*
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
@ -97,6 +97,12 @@ struct sd_softc {
struct buf buf_queue;
};
struct scsi_mode_sense_data {
struct scsi_mode_header header;
struct scsi_blk_desc blk_desc;
union disk_pages pages;
} scsi_sense;
int sdmatch __P((struct device *, void *, void *));
void sdattach __P((struct device *, struct device *, void *));
int sdlock __P((struct sd_softc *));
@ -107,6 +113,8 @@ void sdstart __P((void *));
int sddone __P((struct scsi_xfer *, int));
int sd_reassign_blocks __P((struct sd_softc *, u_long));
int sd_get_parms __P((struct sd_softc *, int));
static int sd_mode_sense __P((struct sd_softc *, struct scsi_mode_sense_data *,
int, int));
struct cfattach sd_ca = {
sizeof(struct sd_softc), sdmatch, sdattach
@ -821,6 +829,29 @@ sd_reassign_blocks(sd, blkno)
5000, NULL, SCSI_DATA_OUT);
}
static int
sd_mode_sense(sd, scsi_sense, page, flags)
struct sd_softc *sd;
struct scsi_mode_sense_data *scsi_sense;
int page, flags;
{
struct scsi_mode_sense scsi_cmd;
bzero(&scsi_cmd, sizeof(scsi_cmd));
scsi_cmd.opcode = MODE_SENSE;
scsi_cmd.page = page;
scsi_cmd.length = 0x20;
/*
* If the command worked, use the results to fill out
* the parameter structure
*/
return scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd,
sizeof(scsi_cmd), (u_char *)scsi_sense, sizeof(*scsi_sense),
SDRETRIES, 6000, NULL, flags | SCSI_DATA_IN | SCSI_SILENT);
}
/*
* Get the scsi driver to send a full inquiry to the * device and use the
* results to fill out the disk parameter structure.
@ -831,43 +862,12 @@ sd_get_parms(sd, flags)
int flags;
{
struct disk_parms *dp = &sd->params;
struct scsi_mode_sense scsi_cmd;
struct scsi_mode_sense_data {
struct scsi_mode_header header;
struct scsi_blk_desc blk_desc;
union disk_pages pages;
} scsi_sense;
struct scsi_mode_sense_data scsi_sense;
u_long sectors;
int page;
int error;
/*
* do a "mode sense page 4"
*/
bzero(&scsi_cmd, sizeof(scsi_cmd));
scsi_cmd.opcode = MODE_SENSE;
scsi_cmd.page = 4;
scsi_cmd.length = 0x20;
/*
* If the command worked, use the results to fill out
* the parameter structure
*/
if (scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd,
sizeof(scsi_cmd), (u_char *)&scsi_sense, sizeof(scsi_sense),
SDRETRIES, 6000, NULL, flags | SCSI_DATA_IN) != 0) {
printf("%s: could not mode sense (4)", sd->sc_dev.dv_xname);
fake_it:
printf("; using fictitious geometry\n");
/*
* use adaptec standard fictitious geometry
* this depends on which controller (e.g. 1542C is
* different. but we have to put SOMETHING here..)
*/
sectors = scsi_size(sd->sc_link, flags);
dp->heads = 64;
dp->sectors = 32;
dp->cyls = sectors / (64 * 32);
dp->blksize = 512;
dp->disksize = sectors;
} else {
if ((error = sd_mode_sense(sd, &scsi_sense, page = 4, flags)) == 0) {
SC_DEBUG(sd->sc_link, SDEV_DB3,
("%d cyls, %d heads, %d precomp, %d red_write, %d land_zone\n",
_3btol(scsi_sense.pages.rigid_geometry.ncyl),
@ -886,11 +886,8 @@ sd_get_parms(sd, flags)
dp->cyls = _3btol(scsi_sense.pages.rigid_geometry.ncyl);
dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
if (dp->heads == 0 || dp->cyls == 0) {
printf("%s: mode sense (4) returned nonsense",
sd->sc_dev.dv_xname);
if (dp->heads == 0 || dp->cyls == 0)
goto fake_it;
}
if (dp->blksize == 0)
dp->blksize = 512;
@ -899,8 +896,46 @@ sd_get_parms(sd, flags)
dp->disksize = sectors;
sectors /= (dp->heads * dp->cyls);
dp->sectors = sectors; /* XXX dubious on SCSI */
return 0;
}
if ((error = sd_mode_sense(sd, &scsi_sense, page = 5, flags)) == 0) {
dp->heads = scsi_sense.pages.flex_geometry.nheads;
dp->cyls = _2btol(scsi_sense.pages.flex_geometry.ncyl);
dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
dp->sectors = scsi_sense.pages.flex_geometry.ph_sec_tr;
dp->disksize = dp->heads * dp->cyls * dp->sectors;
if (dp->disksize == 0)
goto fake_it;
if (dp->blksize == 0)
dp->blksize = 512;
return 0;
}
fake_it:
if ((sd->sc_link->quirks & SDEV_NOMODESENSE) == 0) {
if (error == 0)
printf("%s: mode sense (%d) returned nonsense",
sd->sc_dev.dv_xname, page);
else
printf("%s: could not mode sense (4/5)",
sd->sc_dev.dv_xname);
printf("; using fictitious geometry\n");
}
/*
* use adaptec standard fictitious geometry
* this depends on which controller (e.g. 1542C is
* different. but we have to put SOMETHING here..)
*/
sectors = scsi_size(sd->sc_link, flags);
dp->heads = 64;
dp->sectors = 32;
dp->cyls = sectors / (64 * 32);
dp->blksize = 512;
dp->disksize = sectors;
return 0;
}