diff options
Diffstat (limited to 'os')
| -rw-r--r-- | os/hal/include/hal_usb_msd.h | 3 | ||||
| -rw-r--r-- | os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.c | 6 | ||||
| -rw-r--r-- | os/hal/ports/TIVA/LLD/SSI/hal_spi_lld.h | 36 | ||||
| -rw-r--r-- | os/hal/src/hal_usb_msd.c | 22 | ||||
| -rw-r--r-- | os/various/lib_scsi.c | 78 | ||||
| -rw-r--r-- | os/various/lib_scsi.h | 15 | 
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;  /** | 
