Subject: Re: sd(4) on atapibus
To: None <current-users@NetBSD.org>
From: Kouichirou Hiratsuka <hira@po6.nsk.ne.jp>
List: current-users
Date: 09/25/2003 15:07:43
Hello,
> USB floppy drive does not work on -current (my PR kern/22875). It has not
> worked since this commit.
>
> http://mail-index.netbsd.org/source-changes/2003/09/18/0000.html
>
> Now, sd_atapi.c and sd_scsi.c were merged into sd.c. According to sd_atapi.c,
> on atapibus, third argument of scsipi_mode_sense_big() was constant value. On
> atapibus, must it be ATAPI_FLEX_GEOMETRY_PAGE?
>
> My USB floppy drive does work well with a following patch.
Is get_parms() necessary for both of SCSI and ATAPI bus? According to sd_scsi.c
and sd_atapi.c, it considerably differed in case of SCSI and ATAPI. I tried
switch of it by bus type.
This patch also does work well for my USB floppy drive. Maybe it's better than
my previous patch.
best regards.
--
Kouichirou Hiratsuka
hira@po6.nsk.ne.jp
Index: sd.c
===================================================================
RCS file: /cvs/cvsroot/src/sys/dev/scsipi/sd.c,v
retrieving revision 1.210
diff -u -r1.210 sd.c
--- sd.c 18 Sep 2003 06:55:53 -0000 1.210
+++ sd.c 25 Sep 2003 06:05:03 -0000
@@ -87,6 +87,7 @@
#include <dev/scsipi/scsi_disk.h>
#include <dev/scsipi/scsiconf.h>
#include <dev/scsipi/sdvar.h>
+#include <dev/scsipi/atapi_disk.h>
#define SDUNIT(dev) DISKUNIT(dev)
#define SDPART(dev) DISKPART(dev)
@@ -114,6 +115,9 @@
int));
int sd_get_capacity __P((struct sd_softc *, struct disk_parms *, int));
int sd_get_parms __P((struct sd_softc *, struct disk_parms *, int));
+int sd_scsibus_get_parms __P((struct sd_softc *, struct disk_parms *, int));
+int sd_atapibus_get_parms __P((struct sd_softc *, struct disk_parms *,
+ int));
int sd_flush __P((struct sd_softc *, int));
int sd_getcache __P((struct sd_softc *, int *));
int sd_setcache __P((struct sd_softc *, int));
@@ -1773,6 +1777,27 @@
struct disk_parms *dp;
int flags;
{
+ switch (scsipi_periph_bustype(sd->sc_periph)) {
+ case SCSIPI_BUSTYPE_SCSI:
+ return (sd_scsibus_get_parms(sd, dp, flags));
+ break;
+ case SCSIPI_BUSTYPE_ATAPI:
+ return (sd_atapibus_get_parms(sd, dp, flags));
+ break;
+ default:
+ return (SDGP_RESULT_OFFLINE);
+ break;
+ }
+ /* NOTREACHED */
+ return (SDGP_RESULT_OFFLINE);
+}
+
+int
+sd_scsibus_get_parms(sd, dp, flags)
+ struct sd_softc *sd;
+ struct disk_parms *dp;
+ int flags;
+{
struct sd_mode_sense_data scsipi_sense;
int error;
int big;
@@ -1907,6 +1932,84 @@
blksize:
return (SDGP_RESULT_OK);
+}
+
+int
+sd_atapibus_get_parms(sd, dp, flags)
+ struct sd_softc *sd;
+ struct disk_parms *dp;
+ int flags;
+{
+ struct atapi_read_format_capacities scsipi_cmd;
+ struct atapi_capacity_descriptor *descp;
+ struct atapi_sd_mode_data sense_data;
+ char capacity_data[ATAPI_CAP_DESC_SIZE(1)];
+ int error;
+
+ memset(&scsipi_cmd, 0, sizeof scsipi_cmd);
+ scsipi_cmd.opcode = ATAPI_READ_FORMAT_CAPACITIES;
+ _lto2b(ATAPI_CAP_DESC_SIZE(1), scsipi_cmd.length);
+
+ error = scsipi_command(sd->sc_periph,
+ (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
+ (void *)capacity_data, ATAPI_CAP_DESC_SIZE(1), SDRETRIES, 20000,
+ NULL, flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK);
+ SC_DEBUG(sd->sc_periph, SCSIPI_DB2,
+ ("sd_atapibus_get_parms: read format capacities error=%d\n",
+ error));
+
+ if (error != 0)
+ return (SDGP_RESULT_OFFLINE);
+ descp = (struct atapi_capacity_descriptor *)
+ &capacity_data[ATAPI_CAP_DESC_OFFSET_DESC(0)];
+
+ switch (descp->byte5 & ATAPI_CAP_DESC_CODE_MASK) {
+ case ATAPI_CAP_DESC_CODE_UNFORMATTED:
+ return SDGP_RESULT_UNFORMATTED;
+
+ case ATAPI_CAP_DESC_CODE_RESERVED:
+ case ATAPI_CAP_DESC_CODE_FORMATTED:
+ break;
+
+ case ATAPI_CAP_DESC_CODE_NONE:
+ return SDGP_RESULT_OFFLINE;
+ }
+
+ dp->disksize = _4btol(descp->nblks);
+ dp->blksize = _3btol(descp->blklen);
+ if (dp->blksize == 0)
+ dp->disksize512 = dp->disksize;
+ else
+ dp->disksize512 = (dp->disksize * dp->blksize) / DEV_BSIZE;
+
+ /*
+ * First, set up standard fictitious geometry, a la sd_scsi.c.
+ */
+ dp->heads = 64;
+ dp->sectors = 32;
+ dp->cyls = dp->disksize / (64 * 32);
+ dp->rot_rate = 3600;
+
+ /*
+ * Then try to get something better. If we can't, that's
+ * still OK.
+ *
+ * XXX Rigid geometry page?
+ */
+ error = scsipi_mode_sense_big(sd->sc_periph, 0,
+ ATAPI_FLEX_GEOMETRY_PAGE, &sense_data.header, FLEXGEOMETRYPAGESIZE,
+ flags | XS_CTL_DATA_ONSTACK, SDRETRIES, 20000);
+ SC_DEBUG(sd->sc_periph, SCSIPI_DB2,
+ ("sd_atapibus_get_parms: mode sense (flex) error=%d\n", error));
+ if (error != 0)
+ return (SDGP_RESULT_OK);
+
+ dp->heads = sense_data.pages.flex_geometry.nheads;
+ dp->sectors = sense_data.pages.flex_geometry.ph_sec_tr;
+ dp->cyls = _2btol(sense_data.pages.flex_geometry.ncyl);
+ dp->rot_rate = _2btol(sense_data.pages.flex_geometry.rot_rate);
+
+ return (SDGP_RESULT_OK);
}
int