aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
Diffstat (limited to 'os')
-rw-r--r--os/hal/include/hal_usb_msd.h3
-rw-r--r--os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c6
-rw-r--r--os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h36
-rw-r--r--os/hal/src/hal_usb_msd.c22
-rw-r--r--os/various/lib_scsi.c78
-rw-r--r--os/various/lib_scsi.h15
6 files changed, 131 insertions, 29 deletions
diff --git a/os/hal/include/hal_usb_msd.h b/os/hal/include/hal_usb_msd.h
index fcc2cf2..0fe03e4 100644
--- a/os/hal/include/hal_usb_msd.h
+++ b/os/hal/include/hal_usb_msd.h
@@ -172,7 +172,8 @@ extern "C" {
void msdObjectInit(USBMassStorageDriver *msdp);
void msdStart(USBMassStorageDriver *msdp, USBDriver *usbp,
BaseBlockDevice *blkdev, uint8_t *blkbuf,
- const scsi_inquiry_response_t *scsi_inquiry_response);
+ const scsi_inquiry_response_t *scsi_inquiry_response,
+ const scsi_unit_serial_number_inquiry_response_t *serialInquiry);
void msdStop(USBMassStorageDriver *msdp);
bool msd_request_hook(USBDriver *usbp);
#ifdef __cplusplus
diff --git a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c
index 98defed..126959f 100644
--- a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c
+++ b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c
@@ -359,6 +359,7 @@ void spi_lld_stop(SPIDriver *spip)
}
}
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
/**
* @brief Asserts the slave select signal and prepares for transfers.
*
@@ -368,7 +369,7 @@ void spi_lld_stop(SPIDriver *spip)
*/
void spi_lld_select(SPIDriver *spip)
{
- palClearPad(spip->config->ssport, spip->config->sspad);
+ /* No implementation on Tiva.*/
}
/**
@@ -381,8 +382,9 @@ void spi_lld_select(SPIDriver *spip)
*/
void spi_lld_unselect(SPIDriver *spip)
{
- palSetPad(spip->config->ssport, spip->config->sspad);
+ /* No implementation on Tiva.*/
}
+#endif
/**
* @brief Ignores data on the SPI bus.
diff --git a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h
index 64560eb..4dcf6db 100644
--- a/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h
+++ b/os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h
@@ -165,6 +165,10 @@
#define TIVA_UDMA_REQUIRED
#endif
+#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
+#error "SPI_SELECT_MODE_LLD not supported by this driver"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -189,16 +193,34 @@ typedef struct {
/**
* @brief Operation complete callback or @p NULL.
*/
- spicallback_t end_cb;
- /* End of the mandatory fields.*/
+ spicallback_t end_cb;
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LINE) || defined(__DOXYGEN__)
+ /**
+ * @brief The chip select line.
+ */
+ ioline_t ssline;
+#endif
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PORT) || defined(__DOXYGEN__)
+ /**
+ * @brief The chip select port.
+ */
+ ioportid_t ssport;
/**
- * @brief The chip select line port.
+ * @brief The chip select port mask.
*/
- ioportid_t ssport;
+ uint8fast_t ssmask;
+#endif
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PAD) || defined(__DOXYGEN__)
/**
- * @brief The chip select line pad number.
+ * @brief The chip select port.
*/
- uint16_t sspad;
+ ioportid_t ssport;
+ /**
+ * @brief The chip select pad number.
+ */
+ uint_fast8_t sspad;
+#endif
+ /* End of the mandatory fields.*/
/**
* @brief SSI CR0 initialization data.
*/
@@ -289,8 +311,10 @@ extern "C" {
void spi_lld_init(void);
void spi_lld_start(SPIDriver *spip);
void spi_lld_stop(SPIDriver *spip);
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
void spi_lld_select(SPIDriver *spip);
void spi_lld_unselect(SPIDriver *spip);
+#endif
void spi_lld_ignore(SPIDriver *spip, size_t n);
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf);
diff --git a/os/hal/src/hal_usb_msd.c b/os/hal/src/hal_usb_msd.c
index 6cc5386..564bad0 100644
--- a/os/hal/src/hal_usb_msd.c
+++ b/os/hal/src/hal_usb_msd.c
@@ -84,6 +84,19 @@ static const scsi_inquiry_response_t default_scsi_inquiry_response = {
{'v',CH_KERNEL_MAJOR+'0','.',CH_KERNEL_MINOR+'0'}
};
+/**
+ * @brief Hardcoded default SCSI unit serial number inquiry response structure.
+ */
+static const scsi_unit_serial_number_inquiry_response_t default_scsi_unit_serial_number_inquiry_response =
+{
+ 0x00,
+ 0x80,
+ 0x00,
+ 0x08,
+ "00000000"
+};
+
+
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
@@ -373,7 +386,8 @@ void msdStop(USBMassStorageDriver *msdp) {
*/
void msdStart(USBMassStorageDriver *msdp, USBDriver *usbp,
BaseBlockDevice *blkdev, uint8_t *blkbuf,
- const scsi_inquiry_response_t *inquiry) {
+ const scsi_inquiry_response_t *inquiry,
+ const scsi_unit_serial_number_inquiry_response_t *serialInquiry) {
osalDbgCheck((msdp != NULL) && (usbp != NULL)
&& (blkdev != NULL) && (blkbuf != NULL));
@@ -393,6 +407,12 @@ void msdStart(USBMassStorageDriver *msdp, USBDriver *usbp,
else {
msdp->scsi_config.inquiry_response = inquiry;
}
+ if (NULL == serialInquiry) {
+ msdp->scsi_config.unit_serial_number_inquiry_response = &default_scsi_unit_serial_number_inquiry_response;
+ }
+ else {
+ msdp->scsi_config.unit_serial_number_inquiry_response = serialInquiry;
+ }
msdp->scsi_config.blkbuf = blkbuf;
msdp->scsi_config.blkdev = blkdev;
msdp->scsi_config.transport = &msdp->scsi_transport;
diff --git a/os/various/lib_scsi.c b/os/various/lib_scsi.c
index 55aeb7e..ea2adda 100644
--- a/os/various/lib_scsi.c
+++ b/os/various/lib_scsi.c
@@ -159,7 +159,6 @@ static bool cmd_ignored(SCSITarget *scsip, const uint8_t *cmd) {
(void)scsip;
(void)cmd;
- set_sense_ok(scsip);
return SCSI_SUCCESS;
}
@@ -175,7 +174,12 @@ static bool cmd_ignored(SCSITarget *scsip, const uint8_t *cmd) {
*/
static bool inquiry(SCSITarget *scsip, const uint8_t *cmd) {
- if ((cmd[1] & 0b11) || cmd[2] != 0) {
+ if ((cmd[1] & 0b1) && cmd[2] == 0x80) {
+ /* Unit serial number page */
+ return transmit_data(scsip, (const uint8_t *)scsip->config->unit_serial_number_inquiry_response,
+ sizeof(scsi_unit_serial_number_inquiry_response_t));
+ }
+ else if ((cmd[1] & 0b11) || cmd[2] != 0) {
set_sense(scsip, SCSI_SENSE_KEY_ILLEGAL_REQUEST,
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
SCSI_ASENSEQ_NO_QUALIFIER);
@@ -199,10 +203,7 @@ static bool inquiry(SCSITarget *scsip, const uint8_t *cmd) {
*/
static bool request_sense(SCSITarget *scsip, const uint8_t *cmd) {
- uint32_t tmp;
- memcpy(&tmp, &cmd[1], 3);
-
- if ((tmp != 0) || (cmd[4] != sizeof(scsi_sense_response_t))) {
+ if (((cmd[1] & 0x01) != 0) || (cmd[4] != sizeof(scsi_sense_response_t))) {
set_sense(scsip, SCSI_SENSE_KEY_ILLEGAL_REQUEST,
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
SCSI_ASENSEQ_NO_QUALIFIER);
@@ -378,6 +379,30 @@ static bool data_read_write10(SCSITarget *scsip, const uint8_t *cmd) {
}
return SCSI_SUCCESS;
}
+
+/**
+ * @brief SCSI test unit ready command handler
+ * @details If block device is inserted, sets sense data in 'all OK' condition
+ * and returns success status.
+ * If block device is not inserted, sets sense data to 'Medium not present' considion,
+ * and returns check condition status.
+ */
+static bool test_unit_ready(SCSITarget *scsip, const uint8_t *cmd) {
+ (void)cmd;
+
+ if (blkIsInserted(scsip->config->blkdev)) {
+ return SCSI_SUCCESS;
+ }
+ else {
+ warnprintf("SCSI Medium is not inserted.\r\n");
+ set_sense(scsip, SCSI_SENSE_KEY_NOT_READY,
+ SCSI_ASENSE_MEDIUM_NOT_PRESENT,
+ SCSI_ASENSEQ_NO_QUALIFIER);
+ return SCSI_FAILED;
+ }
+
+}
+
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
@@ -398,54 +423,69 @@ static bool data_read_write10(SCSITarget *scsip, const uint8_t *cmd) {
*/
bool scsiExecCmd(SCSITarget *scsip, const uint8_t *cmd) {
- /* status will be overwritten later in case of error */
- set_sense_ok(scsip);
+ bool ret = SCSI_SUCCESS;
switch (cmd[0]) {
case SCSI_CMD_INQUIRY:
dbgprintf("SCSI_CMD_INQUIRY\r\n");
- return inquiry(scsip, cmd);
+ ret = inquiry(scsip, cmd);
+ break;
case SCSI_CMD_REQUEST_SENSE:
dbgprintf("SCSI_CMD_REQUEST_SENSE\r\n");
- return request_sense(scsip, cmd);
+ ret = request_sense(scsip, cmd);
+ break;
case SCSI_CMD_READ_CAPACITY_10:
dbgprintf("SCSI_CMD_READ_CAPACITY_10\r\n");
- return read_capacity10(scsip, cmd);
+ ret = read_capacity10(scsip, cmd);
+ break;
case SCSI_CMD_READ_10:
dbgprintf("SCSI_CMD_READ_10\r\n");
- return data_read_write10(scsip, cmd);
+ ret = data_read_write10(scsip, cmd);
+ break;
case SCSI_CMD_WRITE_10:
dbgprintf("SCSI_CMD_WRITE_10\r\n");
- return data_read_write10(scsip, cmd);
+ ret = data_read_write10(scsip, cmd);
+ break;
case SCSI_CMD_TEST_UNIT_READY:
dbgprintf("SCSI_CMD_TEST_UNIT_READY\r\n");
- return cmd_ignored(scsip, cmd);
+ ret = test_unit_ready(scsip, cmd);
+ break;
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
dbgprintf("SCSI_CMD_ALLOW_MEDIUM_REMOVAL\r\n");
- return cmd_ignored(scsip, cmd);
+ ret = cmd_ignored(scsip, cmd);
+ break;
case SCSI_CMD_MODE_SENSE_6:
dbgprintf("SCSI_CMD_MODE_SENSE_6\r\n");
- return mode_sense6(scsip, cmd);
+ ret = mode_sense6(scsip, cmd);
+ break;
case SCSI_CMD_READ_FORMAT_CAPACITIES:
dbgprintf("SCSI_CMD_READ_FORMAT_CAPACITIES\r\n");
- return read_format_capacities(scsip, cmd);
+ ret = read_format_capacities(scsip, cmd);
+ break;
case SCSI_CMD_VERIFY_10:
dbgprintf("SCSI_CMD_VERIFY_10\r\n");
- return cmd_ignored(scsip, cmd);
+ ret = cmd_ignored(scsip, cmd);
+ break;
default:
warnprintf("SCSI unhandled command: %X\r\n", cmd[0]);
- return cmd_unhandled(scsip, cmd);
+ ret = cmd_unhandled(scsip, cmd);
+ break;
}
+
+ if (ret == SCSI_SUCCESS)
+ set_sense_ok(scsip);
+
+ return ret;
}
/**
diff --git a/os/various/lib_scsi.h b/os/various/lib_scsi.h
index 97badb0..8384ae3 100644
--- a/os/various/lib_scsi.h
+++ b/os/various/lib_scsi.h
@@ -133,6 +133,17 @@ typedef struct PACKED_VAR {
} scsi_inquiry_response_t;
/**
+ * @brief Represents SCSI unit serial number inquiry response structure.
+ * @details See SCSI specification.
+ */
+typedef struct PACKED_VAR {
+ uint8_t peripheral;
+ uint8_t page_code;
+ uint8_t reserved;
+ uint8_t page_length;
+ uint8_t serianNumber[8];
+} scsi_unit_serial_number_inquiry_response_t;
+/**
* @brief Represents SCSI mode sense (6) request structure.
* @details See SCSI specification.
*/
@@ -225,6 +236,10 @@ typedef struct {
* @brief Pointer to SCSI inquiry response object.
*/
const scsi_inquiry_response_t *inquiry_response;
+ /**
+ * @brief Pointer to SCSI unit serial number inquiry response object.
+ */
+ const scsi_unit_serial_number_inquiry_response_t *unit_serial_number_inquiry_response;
} SCSITargetConfig;
/**