/*
 * 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;
}
示例#2
0
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;
}
示例#3
0
/*
 * 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;
}
示例#4
0
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;
}