/* * Performs a read request for SDHC. */ static int sdhc_read_request(struct sd_host *host, struct request *req) { int i; unsigned long nr_blocks; /* in card blocks */ size_t block_len; /* in bytes */ unsigned long start; void *buf = req->buffer; int retval; start = blk_rq_pos(req); nr_blocks = blk_rq_cur_sectors(req); block_len = 1 << KERNEL_SECTOR_SHIFT; for (i = 0; i < nr_blocks; i++) { retval = sd_read_single_block(host, start, buf, block_len); if (retval < 0) break; start ++; buf += block_len; } /* number of kernel sectors transferred */ retval = i; return retval; }
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { DRESULT result; if (pdrv >= N_PDRV) { result = RES_ERROR; } else if (!pdrv_data[pdrv].initialized) { result = RES_NOTRDY; } else if (!pdrv_data[pdrv].present) { result = RES_ERROR; } else { while (count > 0) { uint32_t addr; int read_res; addr = get_addr(sector, pdrv_data[pdrv].byte_addressable); read_res = sd_read_single_block(addr, buff); if (read_res != 0) { break; } buff += SD_SECTOR_SIZE; sector++; count--; } if (count > 0) { result = RES_ERROR; } else { result = RES_OK; } } return result; }
/* * Performs a read request. */ static int sd_read_request(struct sd_host *host, struct request *req) { int i; unsigned long nr_blocks; /* in card blocks */ size_t block_len; /* in bytes */ unsigned long start; void *buf = req->buffer; int retval; /* * It seems that some cards do not accept single block reads for the * read block length reported by the card. * For now, we perform only 512 byte single block reads. */ start = blk_rq_pos(req) << KERNEL_SECTOR_SHIFT; #if 0 nr_blocks = req->current_nr_sectors >> (host->card.csd.read_blkbits - KERNEL_SECTOR_SHIFT); block_len = 1 << host->card.csd.read_blkbits; #else nr_blocks = blk_rq_cur_sectors(req); block_len = 1 << KERNEL_SECTOR_SHIFT; #endif for (i = 0; i < nr_blocks; i++) { retval = sd_read_single_block(host, start, buf, block_len); if (retval < 0) break; start += block_len; buf += block_len; } /* number of kernel sectors transferred */ #if 0 retval = i << (host->card.csd.read_blkbits - KERNEL_SECTOR_SHIFT); #else retval = i; #endif return retval; }
scsi_cmdret_t scsi_sd_read10( SCSI_PARAMS ) { const sdio_t *sdio = (const sdio_t*)scsi_lun[lun].info; scsi_cdb10_t *cdb10 = (scsi_cdb10_t *)cmd; //uint8_t DPO = (cdb10->cdb_info >> 4) & 0x1; //uint8_t FUA = (cdb10->cdb_info >> 3) & 0x1; uint32_t lba = msbtohost32(cdb10->lba); uint32_t nblocks = msbtohost16(cdb10->length); uint32_t sdsize = sd_get_size(*sdio); sd_card_type_t sdtype = sd_get_type(*sdio); sd_error_t sdret; scsi_cmdret_t ret; uint32_t la = (sdtype != SDHC) ? lba * BLOCKSIZE : lba; sdret = SD_NO_ERROR; sd_transfer_ended = false; sd_set_transfer_handler(*sdio, sd_transfer_handler); if ((lba + nblocks - 1) >= sdsize) { log_error("SCSI Read(10), read beyond limit (limit 0x%08x, request 0x%08x / +%d)",sdsize,lba,nblocks); *status = SCSI_CHECK_CONDITION; return SCSI_CMD_DONE; } if (datamax < BLOCKSIZE) { log_error("SCSI Read(10), read buffer is smaller than a single sector (%d/%d bytes)",datalen,BLOCKSIZE); *status = SCSI_CHECK_CONDITION; return SCSI_CMD_ERROR; } sdret = sd_read_single_block(*sdio, la, data); if (cont == 0) { log_info("SCSI Read(10) type %d, lba 0x%08x, length %d",sdtype,lba,nblocks); } else { DBG("-%d-\n",cont); } if (sdret != SD_NO_ERROR) { log_error("SCSI Read Command Error on SD %d",sdret); *status = SCSI_CHECK_CONDITION; return SCSI_CMD_DONE; } while (!sd_transfer_ended) { ; } sdret = sd_get_status(*sdio); if (sdret != SD_NO_ERROR) { log_error("SCSI Read Error on SD (lba 0x%08x) ret %d",lba,sdret); *status = SCSI_CHECK_CONDITION; return SCSI_CMD_DONE; } switch (nblocks) { case 0: *status = SCSI_CHECK_CONDITION; ret = SCSI_CMD_ERROR; break; case 1: *datalen = BLOCKSIZE; *status = SCSI_GOOD; ret = SCSI_CMD_DONE; break; default: cdb10->lba = msbtohost32( lba + 1 ); cdb10->length = msbtohost16( nblocks - 1 ); *datalen = BLOCKSIZE; *status = SCSI_GOOD; ret = SCSI_CMD_PARTIAL; break; } return ret; }