Subject: kern/3009: SCSI disk driver optical support.
To: None <gnats-bugs@gnats.netbsd.org>
From: =?ISO-2022-JP?B?Ik1JTk9VUkEgTWFrb3RvIC8gGyRCTCcxOhsoQiAbJEI/PxsoQiI=?= <minoura@kw.netlaputa.or.jp>
List: netbsd-bugs
Date: 12/08/1996 18:12:58
>Number: 3009
>Category: kern
>Synopsis: SCSI disk driver (sd.c) optical support.
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Dec 8 04:05:04 1996
>Last-Modified:
>Originator: Naofumi HONDA / MINOURA Makoto
>Organization:
NetBSD/pc98 Core Team
>Release: Dec.7, '96
>Environment:
System: NetBSD daisy 1.2B NetBSD 1.2B (DAISY) #7: Sat Dec 7 19:09:41 JST 1996 root@daisy:/usr/src/sys/arch/i386/compile/DAISY i386
>Description:
SCSI optical disks (e.g. MO and PD) are supported by sd.c.
There are two problems:-
- sd.c does not know MODE_SENSE page 6 (optical device specific).
Instead, it tries page 4 and 5.
- Some drives (such as FUJITSU M2513A 640/540MB magneto-optical) are
very slow so that 10 second timeout is not enough.
>How-To-Repeat:
>Fix:
Written by Naofumi HONDA and MINOURA Makoto.
Or, we can port FreeBSD od driver.
diff -rc scsi.ORIG/sd.c scsi/sd.c
*** scsi.ORIG/sd.c Thu Dec 5 21:19:58 1996
--- scsi/sd.c Sun Dec 8 17:54:53 1996
***************
*** 95,100 ****
--- 95,101 ----
u_long disksize; /* total number sectors */
} params;
struct buf buf_queue;
+ u_int8_t type;
};
struct scsi_mode_sense_data {
***************
*** 116,121 ****
--- 117,123 ----
void sdstart __P((void *));
int sddone __P((struct scsi_xfer *, int));
int sd_reassign_blocks __P((struct sd_softc *, u_long));
+ int sd_get_optparms __P((struct sd_softc *, int, struct disk_parms *));
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));
***************
*** 188,193 ****
--- 190,196 ----
* Store information needed to contact our base driver
*/
sd->sc_link = sc_link;
+ sd->type = (sa->sa_inqbuf->device & SID_TYPE);
sc_link->device = &sd_switch;
sc_link->device_softc = sd;
if (sc_link->openings > SDOUTSTANDING)
***************
*** 619,625 ****
*/
error = scsi_scsi_cmd(sc_link, cmdp, cmdlen,
(u_char *)bp->b_data, bp->b_bcount,
! SDRETRIES, 10000, bp, SCSI_NOSLEEP |
((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT));
if (error)
printf("%s: not queued, error %d\n",
--- 622,628 ----
*/
error = scsi_scsi_cmd(sc_link, cmdp, cmdlen,
(u_char *)bp->b_data, bp->b_bcount,
! SDRETRIES, 60000, bp, SCSI_NOSLEEP |
((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT));
if (error)
printf("%s: not queued, error %d\n",
***************
*** 796,802 ****
/* as long as it's not 0 - readdisklabel divides by it (?) */
}
! strncpy(lp->d_typename, "SCSI disk", 16);
lp->d_type = DTYPE_SCSI;
strncpy(lp->d_packname, "fictitious", 16);
lp->d_secperunit = sd->params.disksize;
--- 799,808 ----
/* as long as it's not 0 - readdisklabel divides by it (?) */
}
! if (sd->type == T_OPTICAL)
! strncpy(lp->d_typename, "SCSI optical", 16);
! else
! strncpy(lp->d_typename, "SCSI disk", 16);
lp->d_type = DTYPE_SCSI;
strncpy(lp->d_packname, "fictitious", 16);
lp->d_secperunit = sd->params.disksize;
***************
*** 878,883 ****
--- 884,934 ----
SDRETRIES, 6000, NULL, flags | SCSI_DATA_IN | SCSI_SILENT);
}
+ int
+ sd_get_optparms(sd, flags, dp)
+ struct sd_softc *sd;
+ int flags;
+ struct disk_parms *dp;
+ {
+ 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;
+ u_long sectors;
+ int error = 0;
+
+ dp->blksize = 512L;
+ if ((sectors = scsi_size(sd->sc_link, flags)) == 0)
+ error = 1;
+ /* XXX:
+ * I know it is better to get the following params from the
+ * mode sense page 6 only ( optical device parameter page! ).
+ * However, there are stupid optical devices which does NOT
+ * support the page 6. Ghaa....
+ */
+ bzero(&scsi_cmd, sizeof(scsi_cmd));
+ scsi_cmd.opcode = MODE_SENSE;
+ scsi_cmd.page = 0x3f; /* all pages */
+ scsi_cmd.length = sizeof(struct scsi_mode_header) +
+ sizeof(struct scsi_blk_desc);
+ if ((error |= 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)
+ {
+ dp->blksize = _3btol(scsi_sense.blk_desc.blklen);
+ if (dp->blksize == 0)
+ dp->blksize = 512L;
+ }
+ dp->heads = 64;
+ dp->sectors = 32;
+ dp->cyls = sectors / (64 * 32);
+ dp->disksize = sectors;
+ return error;
+ }
+
/*
* Get the scsi driver to send a full inquiry to the * device and use the
* results to fill out the disk parameter structure.
***************
*** 892,897 ****
--- 943,956 ----
u_long sectors;
int page;
int error;
+
+ if (sd->type == T_OPTICAL) {
+ int error;
+
+ if (error = sd_get_optparms(sd, flags, dp))
+ sd->sc_link->flags &= ~SDEV_MEDIA_LOADED;
+ return error;
+ }
if ((error = sd_mode_sense(sd, &scsi_sense, page = 4, flags)) == 0) {
SC_DEBUG(sd->sc_link, SDEV_DB3,
>Audit-Trail:
>Unformatted: