diff options
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/drivers/usbdev/usbdev_scsi.c | 62 | ||||
-rw-r--r-- | nuttx/include/nuttx/scsi.h | 42 |
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 */ |