Subject: kern/2535: sys/scsi/sd.c doesn't know about floppy devices
To: None <gnats-bugs@NetBSD.ORG>
From: None <leo@marco.de>
List: netbsd-bugs
Date: 06/10/1996 13:26:00
>Number: 2535
>Category: kern
>Synopsis: sys/scsi/sd.c doesn't know about floppy devices
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Jun 10 07:35:06 1996
>Last-Modified:
>Originator: Matthias Pfaller
>Organization:
leo@dachau.marco.de in real life: Matthias Pfaller
marco GmbH, 85221 Dachau, Germany tel: +49 8131 516142
>Release: 960607
>Environment:
System: NetBSD klondike 1.2_ALPHA NetBSD 1.2_ALPHA (KLONDIKE) #4: Sat Jun 8 20:06:39 MET DST 1996 leo@klondike:/usr/src/sys/arch/pc532/compile/KLONDIKE pc532
>Description:
sys/scsi/sd.c doesn't know how to deal with scsi floppy disk drives
(like the TEAC FC-1). For floppy drives mode page 5 and not
mode page 4 has to be asked for geometry information.
In order to avoid unwanted error messages during kernel startup,
I had to teach scsi_interpret_sense to honor SCSI_SILENT for
illegal requests.
One thing left open by this patch is the scsi_start problem.
scsi_start should not get called for floppy drives.
>How-To-Repeat:
Connect a TEAC FC-1 to your machine and you'll get a bunch of
error messages when booting.
>Fix:
--- scsi_base.c.ORIG Sat May 4 13:52:21 1996
+++ scsi_base.c Wed May 29 19:47:13 1996
@@ -683,6 +683,8 @@
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 */
--- scsi_disk.h.ORIG Tue Mar 19 13:30:26 1996
+++ scsi_disk.h Wed May 29 19:47:15 1996
@@ -174,6 +174,43 @@
u_int8_t reserved2;
u_int8_t reserved3;
} rigid_geometry;
+ struct page_flex_geometry {
+ u_char pg_code; /* page code (should be 5) */
+ u_char pg_length; /* page length (should be 0x1e) */
+ u_char xfr_rate1;
+ u_char xfr_rate0;
+ u_char nheads; /* number of heads */
+ u_char ph_sec_t; /* physical sectors per track */
+ u_char bytes_s_1; /* bytes per sector (MSB) */
+ u_char bytes_s_0; /* bytes per sector (LSB) */
+ u_char ncyl_1; /* number of cylinders (MSB) */
+ u_char ncyl_0; /* number of cylinders (LSB) */
+ u_char st_cyl_wp_1; /* starting cyl., write precomp (MSB) */
+ u_char st_cyl_wp_0; /* starting cyl., write precomp (LSB) */
+ u_char st_cyl_rwc_1; /* starting cyl., red. write cur (MSB) */
+ u_char st_cyl_rwc_0; /* starting cyl., red. write cur (LSB) */
+ u_char driv_step_1; /* drive step rate (MSB) */
+ u_char driv_step_0; /* drive step rate (LSB) */
+ u_char driv_step_w; /* drive step pulse width */
+ u_char head_settle_1; /* head settle delay (MSB) */
+ u_char head_settle_0; /* head settle delay (LSB) */
+ u_char motor_on; /* motor on delay */
+ u_char motor_off; /* motor off delay */
+ u_char flags; /* various flags */
+#define MO 0x20 /* motor on (pin 16)? */
+#define SSN 0x40 /* start at sector 1 */
+#define TRDY 0x20 /* RDY (pin 34) valid */
+ u_char step_p_cyl; /* step pulses per cylinder */
+ u_char write_pre; /* write precompensation */
+ u_char head_load; /* head load delay */
+ u_char head_unload; /* head unload delay */
+ u_char pin_34_2; /* pin 34 (6) and pin 2 (7/11) definition */
+ u_char pin_4_1; /* pin 4 (8/9) and pin 1 (13) definition */
+ u_char reserved1;
+ u_char reserved2;
+ u_char reserved3;
+ u_char reserved4;
+ } flex_geometry;
};
#endif /* _SCSI_SCSI_DISK_H */
--- sd.c.ORIG Tue May 14 13:57:46 1996
+++ sd.c Sun Jun 9 18:28:28 1996
@@ -852,8 +861,39 @@
*/
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);
+ SDRETRIES, 6000, NULL, flags | SCSI_DATA_IN | SCSI_SILENT) != 0) {
+ bzero(&scsi_cmd, sizeof(scsi_cmd));
+ /*
+ * do a "mode sense page 5"
+ */
+ scsi_cmd.opcode = MODE_SENSE;
+ scsi_cmd.page = 5;
+ scsi_cmd.length = 0x20;
+ 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 | SCSI_SILENT) == 0) {
+ dp->heads = scsi_sense.pages.flex_geometry.nheads;
+ dp->cyls =
+ scsi_sense.pages.flex_geometry.ncyl_1 * 256 +
+ scsi_sense.pages.flex_geometry.ncyl_0;
+ dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
+ dp->sectors = scsi_sense.pages.flex_geometry.ph_sec_t;
+ dp->disksize = dp->heads * dp->cyls * dp->sectors;
+ if (dp->heads == 0 || dp->cyls == 0
+ || dp->sectors == 0) {
+ printf("%s: mode sense (5) returned nonsense",
+ sd->sc_dev.dv_xname);
+ goto fake_it;
+ }
+
+ if (dp->blksize == 0)
+ dp->blksize = 512;
+
+ return 0;
+ }
+
+ printf("%s: could not mode sense (4/5)", sd->sc_dev.dv_xname);
fake_it:
printf("; using fictitious geometry\n");
/*
>Audit-Trail:
>Unformatted: