summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-10-28 00:31:22 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-10-28 00:31:22 +0000
commit8b9bc3f201869285335e59cc548ce9bc2de2ad9c (patch)
tree00c06a4303953021af06899f0352f8a123681dd9
parentb164f177fd439b1ad22f0cd02926114d92cd2349 (diff)
downloadnuttx-8b9bc3f201869285335e59cc548ce9bc2de2ad9c.tar.gz
nuttx-8b9bc3f201869285335e59cc548ce9bc2de2ad9c.tar.bz2
nuttx-8b9bc3f201869285335e59cc548ce9bc2de2ad9c.zip
Add SCSI read format capacities command -- WinXP needs it
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1088 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/drivers/usbdev/usbdev_scsi.c62
-rw-r--r--nuttx/include/nuttx/scsi.h42
2 files changed, 100 insertions, 4 deletions
diff --git a/nuttx/drivers/usbdev/usbdev_scsi.c b/nuttx/drivers/usbdev/usbdev_scsi.c
index 94ae730a7..af535c0bc 100644
--- a/nuttx/drivers/usbdev/usbdev_scsi.c
+++ b/nuttx/drivers/usbdev/usbdev_scsi.c
@@ -97,6 +97,7 @@ static void usbstrg_dumpdata(const char *msg, const ubyte *buf, int buflen);
static uint16 usbstrg_getbe16(ubyte *buf);
static uint32 usbstrg_getbe32(ubyte *buf);
static void usbstrg_putbe16(ubyte * buf, uint16 val);
+static void usbstrg_putbe24(ubyte *buf, uint32 val);
static void usbstrg_putbe32(ubyte *buf, uint32 val);
#if 0 /* not used */
static uint16 usbstrg_getle16(ubyte *buf);
@@ -123,6 +124,8 @@ static inline int usbstrg_cmdmodesense6(FAR struct usbstrg_dev_s *priv,
FAR ubyte *buf);
static inline int usbstrg_cmdstartstopunit(FAR struct usbstrg_dev_s *priv);
static inline int usbstrg_cmdpreventmediumremoval(FAR struct usbstrg_dev_s *priv);
+static inline int usbstrg_cmdreadformatcapacity(FAR struct usbstrg_dev_s *priv,
+ FAR ubyte *buf);
static inline int usbstrg_cmdreadcapacity10(FAR struct usbstrg_dev_s *priv,
FAR ubyte *buf);
static inline int usbstrg_cmdread10(FAR struct usbstrg_dev_s *priv);
@@ -223,6 +226,22 @@ static void usbstrg_putbe16(ubyte * buf, uint16 val)
}
/****************************************************************************
+ * Name: usbstrg_putbe24
+ *
+ * Description:
+ * Store a 32-bit value in big-endian order to the location specified by
+ * a byte pointer
+ *
+ ****************************************************************************/
+
+static void usbstrg_putbe24(ubyte *buf, uint32 val)
+{
+ buf[0] = val >> 16;
+ buf[1] = val >> 8;
+ buf[2] = val;
+}
+
+/****************************************************************************
* Name: usbstrg_putbe32
*
* Description:
@@ -782,6 +801,40 @@ static inline int usbstrg_cmdpreventmediumremoval(FAR struct usbstrg_dev_s *priv
}
/****************************************************************************
+ * Name: usbstrg_cmdreadformatcapacity
+ *
+ * Description:
+ * Handle SCSI_CMD_READFORMATCAPACITIES command (MMC)
+ *
+ ****************************************************************************/
+
+static inline int usbstrg_cmdreadformatcapacity(FAR struct usbstrg_dev_s *priv,
+ FAR ubyte *buf)
+{
+ FAR struct scsicmd_readformatcapcacities_s *rfc = (FAR struct scsicmd_readformatcapcacities_s *)priv->cdb;
+ FAR struct scsiresp_readformatcapacities_s *hdr;
+ FAR struct usbstrg_lun_s *lun = priv->lun;
+ int ret;
+
+ priv->u.alloclen = usbstrg_getbe16(rfc->alloclen);
+ ret = usbstrg_setupcmd(priv, SCSICMD_READFORMATCAPACITIES_SIZEOF, USBSTRG_FLAGS_DIRDEVICE2HOST);
+ if (ret == OK)
+ {
+ hdr = (FAR struct scsiresp_readformatcapacities_s *)buf;
+ memset(hdr, 0, SCSIRESP_READFORMATCAPACITIES_SIZEOF);
+ hdr->listlen = SCSIRESP_CURRCAPACITYDESC_SIZEOF;
+
+ /* Only the Current/Maximum Capacity Descriptor follows the header */
+
+ usbstrg_putbe32(hdr->nblocks, lun->nsectors);
+ hdr->type = SCIRESP_RDFMTCAPACITIES_FORMATED;
+ usbstrg_putbe24(hdr->blocklen, lun->sectorsize);
+ priv->nreqbytes = SCSIRESP_READFORMATCAPACITIES_SIZEOF;
+ }
+ return ret;
+}
+
+/****************************************************************************
* Name: usbstrg_cmdreadcapacity10
*
* Description:
@@ -1693,16 +1746,17 @@ static int usbstrg_cmdparsestate(FAR struct usbstrg_dev_s *priv)
ret = usbstrg_cmdpreventmediumremoval(priv);
break;
- /* * 0x20-22 Vendor specific
- * case SCSI_CMD_READFORMATCAPACITIES: * 0x23 Vendor-specific
- * * 0x24 Vendor specific */
+ /* * 0x20-22 Vendor specific */
+ case SCSI_CMD_READFORMATCAPACITIES: /* 0x23 Vendor-specific */
+ ret = usbstrg_cmdreadformatcapacity(priv, buf);
+ break;
+ /* * 0x24 Vendor specific */
case SCSI_CMD_READCAPACITY10: /* 0x25 Mandatory */
ret = usbstrg_cmdreadcapacity10(priv, buf);
break;
/* * 0x26-27 Vendor specific */
-
case SCSI_CMD_READ10: /* 0x28 Mandatory */
return usbstrg_cmdread10(priv);
break;
diff --git a/nuttx/include/nuttx/scsi.h b/nuttx/include/nuttx/scsi.h
index e21b7a90d..e8a07a5cd 100644
--- a/nuttx/include/nuttx/scsi.h
+++ b/nuttx/include/nuttx/scsi.h
@@ -14,6 +14,9 @@
* "SCSI Block Commands -2 (SBC-2)," American National Standard
* for Information Technology, November 13, 2004
*
+ * "SCSI Multimedia Commands - 3 (MMC-3)," American National Standard
+ * for Information Technology, November 12, 2001
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -563,6 +566,12 @@
#define SCSICMD_PREVENTMEDIUMREMOVAL_TRANSPORT 0x01 /* Removal prohibited from data transport */
#define SCSICMD_PREVENTMEDIUMREMOVAL_MCHANGER 0x02 /* Removal prohibited from medium changer */
+/* Read format capacities */
+
+#define SCIRESP_RDFMTCAPACITIES_UNFORMATED 0x01 /* Unformatted media */
+#define SCIRESP_RDFMTCAPACITIES_FORMATED 0x02 /* Formatted media */
+#define SCIRESP_RDFMTCAPACITIES_NOMEDIA 0x03 /* No media */
+
/* Read 6 */
#define SCSICMD_READ6_MSLBAMASK 0x1f
@@ -811,6 +820,39 @@ struct scsicmd_preventmediumremoval_s
};
#define SCSICMD_PREVENTMEDIUMREMOVAL_SIZEOF 6
+struct scsicmd_readformatcapcacities_s
+{
+ ubyte opcode; /* 0: 0x23 */
+ ubyte reserved[6]; /* 1-6: Reserved */
+ ubyte alloclen[2]; /* 7-8: Allocation length */
+ ubyte control; /* 9: Control */
+};
+#define SCSICMD_READFORMATCAPACITIES_SIZEOF 10
+
+struct scsiresp_readformatcapacities_s
+{
+ /* Current capacity header */
+
+ ubyte reserved[3]; /* 0-2: Reserved */
+ ubyte listlen; /* 3: Capacity list length */
+
+ /* Current/Maximum Capacity Descriptor (actually a separate structure) */
+
+ ubyte nblocks[4]; /* 4-7: Number of blocks */
+ ubyte type; /* 8: Bits 2-7: Reserved, Bits 0-1: Descriptor type */
+ ubyte blocklen[3]; /* 9-11: Block length */
+};
+#define SCSIRESP_READFORMATCAPACITIES_SIZEOF 12
+#define SCSIRESP_CURRCAPACITYDESC_SIZEOF 8
+
+struct scsiresp_formattedcapacitydesc_s
+{
+ ubyte nblocks[4]; /* 0-3: Number of blocks */
+ ubyte type; /* 4: Bits 2-7: Type, bits 0-1, reserved */
+ ubyte param[3]; /* 5-7: Type dependent parameter */
+};
+#define SCSIRESP_FORMATTEDCAPACITYDESC_SIZEOF 8
+
struct scsicmd_readcapacity10_s
{
ubyte opcode; /* 0: 0x25 */