diff --git a/stmhal/diskio.c b/stmhal/diskio.c
index 35b9eab99fa0b2dbc023869e4e603ffafa9c0d89..44059b04d5cc172a566673628ac1a23ff39edca3 100644
--- a/stmhal/diskio.c
+++ b/stmhal/diskio.c
@@ -127,7 +127,7 @@ DRESULT disk_read (
 
 #if MICROPY_HW_HAS_SDCARD
         case PD_SDCARD:
-            if (!sdcard_read_blocks(buff, sector, count)) {
+            if (sdcard_read_blocks(buff, sector, count) != 0) {
                 return RES_ERROR;
             }
             return RES_OK;
@@ -160,7 +160,7 @@ DRESULT disk_write (
 
 #if MICROPY_HW_HAS_SDCARD
         case PD_SDCARD:
-            if (!sdcard_write_blocks(buff, sector, count)) {
+            if (sdcard_write_blocks(buff, sector, count) != 0) {
                 return RES_ERROR;
             }
             return RES_OK;
diff --git a/stmhal/hal/inc/stm32f4xx_hal_sd.h b/stmhal/hal/inc/stm32f4xx_hal_sd.h
index 93bacc5da85bf676f0d472184928f0e0159038e8..66ae7cc1bf4e2aec1fdb7299c34f97ed42fd8b52 100644
--- a/stmhal/hal/inc/stm32f4xx_hal_sd.h
+++ b/stmhal/hal/inc/stm32f4xx_hal_sd.h
@@ -630,8 +630,9 @@ void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd);
   * @{
   */
 /* Blocking mode: Polling */
-HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks);
-HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks);
+// dpgeorge: read/write functions renamed to emphasise that address is given by block number
+HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_BlockNumber(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks);
+HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_BlockNumber(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks);
 HAL_SD_ErrorTypedef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint64_t startaddr, uint64_t endaddr);
 
 /* Non-Blocking mode: Interrupt */
@@ -646,8 +647,9 @@ void HAL_SD_XferCpltCallback(SD_HandleTypeDef *hsd);
 void HAL_SD_XferErrorCallback(SD_HandleTypeDef *hsd);
 
 /* Non-Blocking mode: DMA */
-HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks);
-HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks);
+// dpgeorge: read/write functions renamed to emphasise that address is given by block number
+HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_BlockNumber_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks);
+HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_BlockNumber_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks);
 HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout);
 HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout);
 /**
diff --git a/stmhal/hal/src/stm32f4xx_hal_sd.c b/stmhal/hal/src/stm32f4xx_hal_sd.c
index 5018f1b23c0c1c2e851a0dbf693d6672d228972f..75439dabb0a8e04385e6ffb563b5d4d3f66bc97a 100644
--- a/stmhal/hal/src/stm32f4xx_hal_sd.c
+++ b/stmhal/hal/src/stm32f4xx_hal_sd.c
@@ -449,13 +449,13 @@ __weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd)
   *         is managed by polling mode.  
   * @param  hsd: SD handle
   * @param  pReadBuffer: pointer to the buffer that will contain the received data
-  * @param  ReadAddr: Address from where data is to be read  
+  * @param  BlockNumber: Block number from where data is to be read (byte address = BlockNumber * BlockSize)
   * @param  BlockSize: SD card Data block size 
   *          This parameter should be 512
   * @param  NumberOfBlocks: Number of SD blocks to read   
   * @retval SD Card error state
   */
-HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
+HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_BlockNumber(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks)
 {
   SDIO_CmdInitTypeDef  sdio_cmdinitstructure;
   SDIO_DataInitTypeDef sdio_datainitstructure;
@@ -465,10 +465,16 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuff
   /* Initialize data control register */
   hsd->Instance->DCTRL = 0;
   
+  uint32_t ReadAddr;
   if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
   {
     BlockSize = 512;
-    ReadAddr /= 512;
+    ReadAddr = BlockNumber;
+  }
+  else
+  {
+    // should not overflow for standard-capacity cards
+    ReadAddr = BlockNumber * BlockSize;
   }
   
   /* Set Block Size for Card */ 
@@ -507,7 +513,7 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuff
     sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK;    
   }
   
-  sdio_cmdinitstructure.Argument         = (uint32_t)ReadAddr;
+  sdio_cmdinitstructure.Argument         = ReadAddr;
   SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
   
   /* Read block(s) in polling mode */
@@ -633,13 +639,13 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuff
   *         transfer is managed by polling mode.  
   * @param  hsd: SD handle
   * @param  pWriteBuffer: pointer to the buffer that will contain the data to transmit
-  * @param  WriteAddr: Address from where data is to be written 
+  * @param  BlockNumber: Block number to where data is to be written (byte address = BlockNumber * BlockSize)
   * @param  BlockSize: SD card Data block size 
   *          This parameter should be 512.
   * @param  NumberOfBlocks: Number of SD blocks to write 
   * @retval SD Card error state
   */
-HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
+HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_BlockNumber(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks)
 {
   SDIO_CmdInitTypeDef sdio_cmdinitstructure;
   SDIO_DataInitTypeDef sdio_datainitstructure;
@@ -651,10 +657,16 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBu
   /* Initialize data control register */
   hsd->Instance->DCTRL = 0;
   
+  uint32_t WriteAddr;
   if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
   {
     BlockSize = 512;
-    WriteAddr /= 512;
+    WriteAddr = BlockNumber;
+  }
+  else
+  {
+    // should not overflow for standard-capacity cards
+    WriteAddr = BlockNumber * BlockSize;
   }
   
   /* Set Block Size for Card */ 
@@ -684,7 +696,7 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBu
     sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
   }
   
-  sdio_cmdinitstructure.Argument         = (uint32_t)WriteAddr;
+  sdio_cmdinitstructure.Argument         = WriteAddr;
   SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
   
   /* Check for error conditions */
@@ -851,13 +863,13 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBu
   *         to check the completion of the read process   
   * @param  hsd: SD handle                 
   * @param  pReadBuffer: Pointer to the buffer that will contain the received data
-  * @param  ReadAddr: Address from where data is to be read  
+  * @param  BlockNumber: Block number from where data is to be read (byte address = BlockNumber * BlockSize)
   * @param  BlockSize: SD card Data block size 
   *         This paramater should be 512.
   * @param  NumberOfBlocks: Number of blocks to read.
   * @retval SD Card error state
   */
-HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
+HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_BlockNumber_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks)
 {
   SDIO_CmdInitTypeDef sdio_cmdinitstructure;
   SDIO_DataInitTypeDef sdio_datainitstructure;
@@ -898,10 +910,16 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pRead
   /* Enable the DMA Stream */
   HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pReadBuffer, (uint32_t)(BlockSize * NumberOfBlocks));
   
+  uint32_t ReadAddr;
   if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
   {
     BlockSize = 512;
-    ReadAddr /= 512;
+    ReadAddr = BlockNumber;
+  }
+  else
+  {
+    // should not overflow for standard-capacity cards
+    ReadAddr = BlockNumber * BlockSize;
   }
   
   /* Set Block Size for Card */ 
@@ -941,7 +959,7 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pRead
     sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK;
   }
   
-  sdio_cmdinitstructure.Argument         = (uint32_t)ReadAddr;
+  sdio_cmdinitstructure.Argument         = ReadAddr;
   SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
   
   /* Check for error conditions */
@@ -968,13 +986,13 @@ HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pRead
   *         to check the completion of the write process (by SD current status polling).  
   * @param  hsd: SD handle
   * @param  pWriteBuffer: pointer to the buffer that will contain the data to transmit
-  * @param  WriteAddr: Address from where data is to be read   
+  * @param  BlockNumber: Block number to where data is to be written (byte address = BlockNumber * BlockSize)
   * @param  BlockSize: the SD card Data block size 
   *          This parameter should be 512.
   * @param  NumberOfBlocks: Number of blocks to write
   * @retval SD Card error state
   */
-HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks)
+HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_BlockNumber_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint32_t BlockNumber, uint32_t BlockSize, uint32_t NumberOfBlocks)
 {
   SDIO_CmdInitTypeDef sdio_cmdinitstructure;
   SDIO_DataInitTypeDef sdio_datainitstructure;
@@ -1015,10 +1033,16 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWri
   /* Enable SDIO DMA transfer */
   __HAL_SD_SDIO_DMA_ENABLE();
   
+  uint32_t WriteAddr;
   if (hsd->CardType == HIGH_CAPACITY_SD_CARD)
   {
     BlockSize = 512;
-    WriteAddr /= 512;
+    WriteAddr = BlockNumber;
+  }
+  else
+  {
+    // should not overflow for standard-capacity cards
+    WriteAddr = BlockNumber * BlockSize;
   }
 
   /* Set Block Size for Card */ 
@@ -1049,7 +1073,7 @@ HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWri
     sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
   }
   
-  sdio_cmdinitstructure.Argument         = (uint32_t)WriteAddr;
+  sdio_cmdinitstructure.Argument         = WriteAddr;
   SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure);
 
   /* Check for error conditions */
diff --git a/stmhal/sdcard.c b/stmhal/sdcard.c
index 8952161b69625124d236cee62ee9d76a6f582249..a628d3e45074703035c7b5f30181acad5a7003ba 100644
--- a/stmhal/sdcard.c
+++ b/stmhal/sdcard.c
@@ -141,54 +141,46 @@ uint64_t sdcard_get_capacity_in_bytes(void) {
     return cardinfo.CardCapacity;
 }
 
-bool sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
+mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
     // check that dest pointer is aligned on a 4-byte boundary
     if (((uint32_t)dest & 3) != 0) {
-        return false;
+        return SD_ERROR;
     }
 
     // check that SD card is initialised
     if (sd_handle.Instance == NULL) {
-        return false;
+        return SD_ERROR;
     }
 
     // We must disable IRQs because the SDIO peripheral has a small FIFO
     // buffer and we can't let it fill up in the middle of a read.
     // This will not be needed when SD uses DMA for transfer.
-    __disable_irq();
-    HAL_SD_ErrorTypedef err = HAL_SD_ReadBlocks(&sd_handle, (uint32_t*)dest, (uint64_t)block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, num_blocks);
-    __enable_irq();
+    mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
+    HAL_SD_ErrorTypedef err = HAL_SD_ReadBlocks_BlockNumber(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
+    MICROPY_END_ATOMIC_SECTION(atomic_state);
 
-    if (err != SD_OK) {
-        return false;
-    }
-
-    return true;
+    return err;
 }
 
-bool sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
+mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
     // check that src pointer is aligned on a 4-byte boundary
     if (((uint32_t)src & 3) != 0) {
-        return false;
+        return SD_ERROR;
     }
 
     // check that SD card is initialised
     if (sd_handle.Instance == NULL) {
-        return false;
+        return SD_ERROR;
     }
 
     // We must disable IRQs because the SDIO peripheral has a small FIFO
     // buffer and we can't let it drain to empty in the middle of a write.
     // This will not be needed when SD uses DMA for transfer.
-    __disable_irq();
-    HAL_SD_ErrorTypedef err = HAL_SD_WriteBlocks(&sd_handle, (uint32_t*)src, (uint64_t)block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, num_blocks);
-    __enable_irq();
-
-    if (err != SD_OK) {
-        return false;
-    }
+    mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
+    HAL_SD_ErrorTypedef err = HAL_SD_WriteBlocks_BlockNumber(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks);
+    MICROPY_END_ATOMIC_SECTION(atomic_state);
 
-    return true;
+    return err;
 }
 
 #if 0
@@ -205,7 +197,7 @@ bool sdcard_read_blocks_dma(uint8_t *dest, uint32_t block_num, uint32_t num_bloc
     }
 
     // do the read
-    if (HAL_SD_ReadBlocks_DMA(&sd_handle, (uint32_t*)dest, (uint64_t)block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE) != SD_OK) {
+    if (HAL_SD_ReadBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE) != SD_OK) {
         return false;
     }
 
@@ -230,7 +222,7 @@ bool sdcard_write_blocks_dma(const uint8_t *src, uint32_t block_num, uint32_t nu
 
     SD_Error status;
 
-    status = HAL_SD_WriteBlock_DMA(&sd_handle, (uint32_t*)src, (uint64_t)block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, num_blocks);
+    status = HAL_SD_WriteBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks);
     if (status != SD_OK) {
         return false;
     }
@@ -247,14 +239,17 @@ bool sdcard_write_blocks_dma(const uint8_t *src, uint32_t block_num, uint32_t nu
 
 /******************************************************************************/
 // Micro Python bindings
+//
+// Note: these function are a bit ad-hoc at the moment and are mainly intended
+// for testing purposes.  In the future SD should be a proper class with a
+// consistent interface and methods to mount/unmount it.
 
-static mp_obj_t sd_present(mp_obj_t self) {
+STATIC mp_obj_t sd_present(mp_obj_t self) {
     return MP_BOOL(sdcard_is_present());
 }
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(sd_present_obj, sd_present);
 
-static MP_DEFINE_CONST_FUN_OBJ_1(sd_present_obj, sd_present);
-
-static mp_obj_t sd_power(mp_obj_t self, mp_obj_t state) {
+STATIC mp_obj_t sd_power(mp_obj_t self, mp_obj_t state) {
     bool result;
     if (mp_obj_is_true(state)) {
         result = sdcard_power_on();
@@ -264,40 +259,59 @@ static mp_obj_t sd_power(mp_obj_t self, mp_obj_t state) {
     }
     return MP_BOOL(result);
 }
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(sd_power_obj, sd_power);
 
-static MP_DEFINE_CONST_FUN_OBJ_2(sd_power_obj, sd_power);
+STATIC mp_obj_t sd_info(mp_obj_t self) {
+    HAL_SD_ErrorTypedef HAL_SD_Init(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *SDCardInfo);
+    if (sd_handle.Instance == NULL) {
+        return mp_const_none;
+    }
+    HAL_SD_CardInfoTypedef cardinfo;
+    HAL_SD_Get_CardInfo(&sd_handle, &cardinfo);
+    // cardinfo.SD_csd and cardinfo.SD_cid have lots of info but we don't use them
+    mp_obj_t tuple[3] = {
+        mp_obj_new_int_from_ull(cardinfo.CardCapacity),
+        mp_obj_new_int_from_uint(cardinfo.CardBlockSize),
+        mp_obj_new_int(cardinfo.CardType),
+    };
+    return mp_obj_new_tuple(3, tuple);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(sd_info_obj, sd_info);
 
-static mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) {
+STATIC mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) {
     uint8_t *dest = m_new(uint8_t, SDCARD_BLOCK_SIZE);
-    if (!sdcard_read_blocks(dest, mp_obj_get_int(block_num), 1)) {
+    mp_uint_t ret = sdcard_read_blocks(dest, mp_obj_get_int(block_num), 1);
+
+    if (ret != 0) {
         m_free(dest, SDCARD_BLOCK_SIZE);
-        return mp_const_none;
+        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "sdcard_read_blocks failed [%u]", ret));
     }
+
     return mp_obj_new_bytearray_by_ref(SDCARD_BLOCK_SIZE, dest);
 }
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(sd_read_obj, sd_read);
 
-static MP_DEFINE_CONST_FUN_OBJ_2(sd_read_obj, sd_read);
-
-static mp_obj_t sd_write(mp_obj_t self, mp_obj_t block_num, mp_obj_t source) {
+STATIC mp_obj_t sd_write(mp_obj_t self, mp_obj_t block_num, mp_obj_t data) {
     mp_buffer_info_t bufinfo;
-    uint8_t tmp[1];
-
-    pyb_buf_get_for_send(source, &bufinfo, tmp);
+    mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
     if (bufinfo.len % SDCARD_BLOCK_SIZE != 0) {
-        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "writes must be aligned to SDCARD_BLOCK_SIZE (%d) bytes", SDCARD_BLOCK_SIZE));
+        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "writes must be a multiple of %d bytes", SDCARD_BLOCK_SIZE));
     }
 
-    if (!sdcard_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_BLOCK_SIZE)) {
-        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "sdcard_write_blocks failed"));
+    mp_uint_t ret = sdcard_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SDCARD_BLOCK_SIZE);
+
+    if (ret != 0) {
+        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "sdcard_write_blocks failed [%u]", ret));
     }
+
     return mp_const_none;
 }
-
-static MP_DEFINE_CONST_FUN_OBJ_3(sd_write_obj, sd_write);
+STATIC MP_DEFINE_CONST_FUN_OBJ_3(sd_write_obj, sd_write);
 
 STATIC const mp_map_elem_t sdcard_locals_dict_table[] = {
     { MP_OBJ_NEW_QSTR(MP_QSTR_present), (mp_obj_t)&sd_present_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_power), (mp_obj_t)&sd_power_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&sd_info_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&sd_read_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&sd_write_obj },
 };
diff --git a/stmhal/sdcard.h b/stmhal/sdcard.h
index 3a5353467ee712da7f068b841d48449c9a0354f3..8197768de02997d3bf2e24b93965bfa483e5cc87 100644
--- a/stmhal/sdcard.h
+++ b/stmhal/sdcard.h
@@ -32,7 +32,9 @@ bool sdcard_is_present(void);
 bool sdcard_power_on(void);
 void sdcard_power_off(void);
 uint64_t sdcard_get_capacity_in_bytes(void);
-bool sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks);
-bool sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
+
+// these return 0 on success, non-zero on error
+mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks);
+mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
 
 extern const struct _mp_obj_base_t pyb_sdcard_obj;
diff --git a/stmhal/usbd_msc_storage.c b/stmhal/usbd_msc_storage.c
index b6b1972266e89d4e1ebde1dffd242dd4f013787a..ab2d4459abab7061f6f80f490f88d7976b716b63 100644
--- a/stmhal/usbd_msc_storage.c
+++ b/stmhal/usbd_msc_storage.c
@@ -321,7 +321,7 @@ int8_t SDCARD_STORAGE_PreventAllowMediumRemoval(uint8_t lun, uint8_t param) {
   * @retval Status
   */
 int8_t SDCARD_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
-    if (!sdcard_read_blocks(buf, blk_addr, blk_len)) {
+    if (sdcard_read_blocks(buf, blk_addr, blk_len) != 0) {
         return -1;
     }
     return 0;
@@ -336,7 +336,7 @@ int8_t SDCARD_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_
   * @retval Status
   */
 int8_t SDCARD_STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
-    if (!sdcard_write_blocks(buf, blk_addr, blk_len)) {
+    if (sdcard_write_blocks(buf, blk_addr, blk_len) != 0) {
         return -1;
     }
     return 0;
diff --git a/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h b/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h
index 798bdc99dbaa54d473b744b00a6550918f392e5b..7eca900ee0177db4be1b329f48dbd773c6499df4 100644
--- a/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h
+++ b/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h
@@ -83,7 +83,7 @@ typedef struct {
   uint16_t                 scsi_blk_size;
   uint32_t                 scsi_blk_nbr;
   
-  uint32_t                 scsi_blk_addr;
+  uint32_t                 scsi_blk_addr_in_blks;
   uint32_t                 scsi_blk_len;
 } USBD_MSC_BOT_HandleTypeDef;
 
diff --git a/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c b/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c
index 60258d64d9fd12c928b463715c9f9ccdc842bfe4..894812c18f7a8dd28f3ccec6ee10206a566bb6cb 100644
--- a/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c
+++ b/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c
@@ -510,7 +510,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef  *pdev, uint8_t lun , uint8_t *para
       return -1;
     } 
     
-    hmsc->scsi_blk_addr = (params[2] << 24) | \
+    hmsc->scsi_blk_addr_in_blks = (params[2] << 24) | \
       (params[3] << 16) | \
         (params[4] <<  8) | \
           params[5];
@@ -520,13 +520,12 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef  *pdev, uint8_t lun , uint8_t *para
     
     
     
-    if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0)
+    if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr_in_blks, hmsc->scsi_blk_len) < 0)
     {
       return -1; /* error */
     }
     
     hmsc->bot_state = USBD_BOT_DATA_IN;
-    hmsc->scsi_blk_addr *= hmsc->scsi_blk_size;
     hmsc->scsi_blk_len  *= hmsc->scsi_blk_size;
     
     /* cases 4,5 : Hi <> Dn */
@@ -591,7 +590,7 @@ static int8_t SCSI_Write10 (USBD_HandleTypeDef  *pdev, uint8_t lun , uint8_t *pa
     } 
     
     
-    hmsc->scsi_blk_addr = (params[2] << 24) | \
+    hmsc->scsi_blk_addr_in_blks = (params[2] << 24) | \
       (params[3] << 16) | \
         (params[4] <<  8) | \
           params[5];
@@ -601,13 +600,12 @@ static int8_t SCSI_Write10 (USBD_HandleTypeDef  *pdev, uint8_t lun , uint8_t *pa
     /* check if LBA address is in the right range */
     if(SCSI_CheckAddressRange(pdev,
                               lun,
-                              hmsc->scsi_blk_addr,
+                              hmsc->scsi_blk_addr_in_blks,
                               hmsc->scsi_blk_len) < 0)
     {
       return -1; /* error */      
     }
     
-    hmsc->scsi_blk_addr *= hmsc->scsi_blk_size;
     hmsc->scsi_blk_len  *= hmsc->scsi_blk_size;
     
     /* cases 3,11,13 : Hn,Ho <> D0 */
@@ -656,9 +654,12 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef  *pdev, uint8_t lun , uint8_t *pa
     return -1; /* Error, Verify Mode Not supported*/
   }
   
+  hmsc->scsi_blk_addr_in_blks = (params[2] << 24) | (params[3] << 16) | (params[4] << 8) | params[5];
+  hmsc->scsi_blk_len = (params[7] << 8) | params[8];
+
   if(SCSI_CheckAddressRange(pdev,
                             lun, 
-                            hmsc->scsi_blk_addr, 
+                            hmsc->scsi_blk_addr_in_blks,
                             hmsc->scsi_blk_len) < 0)
   {
     return -1; /* error */      
@@ -705,7 +706,7 @@ static int8_t SCSI_ProcessRead (USBD_HandleTypeDef  *pdev, uint8_t lun)
   
   if( ((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun ,
                               hmsc->bot_data, 
-                              hmsc->scsi_blk_addr / hmsc->scsi_blk_size, 
+                              hmsc->scsi_blk_addr_in_blks,
                               len / hmsc->scsi_blk_size) < 0)
   {
     
@@ -723,7 +724,7 @@ static int8_t SCSI_ProcessRead (USBD_HandleTypeDef  *pdev, uint8_t lun)
              len);
   
   
-  hmsc->scsi_blk_addr   += len; 
+  hmsc->scsi_blk_addr_in_blks += len / hmsc->scsi_blk_size;
   hmsc->scsi_blk_len    -= len;  
   
   /* case 6 : Hi = Di */
@@ -752,7 +753,7 @@ static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef  *pdev, uint8_t lun)
   
   if(((USBD_StorageTypeDef *)pdev->pUserData)->Write(lun ,
                               hmsc->bot_data, 
-                              hmsc->scsi_blk_addr / hmsc->scsi_blk_size, 
+                              hmsc->scsi_blk_addr_in_blks,
                               len / hmsc->scsi_blk_size) < 0)
   {
     SCSI_SenseCode(pdev,
@@ -763,7 +764,7 @@ static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef  *pdev, uint8_t lun)
   }
   
   
-  hmsc->scsi_blk_addr  += len; 
+  hmsc->scsi_blk_addr_in_blks += len / hmsc->scsi_blk_size;
   hmsc->scsi_blk_len   -= len; 
   
   /* case 12 : Ho = Do */