Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/sdhci/sdhci.c
Show First 20 Lines • Show All 490 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
uint32_t data; | uint32_t data; | ||||
char *buffer; | char *buffer; | ||||
size_t left; | size_t left; | ||||
buffer = slot->curcmd->data->data; | buffer = slot->curcmd->data->data; | ||||
buffer += slot->offset; | buffer += slot->offset; | ||||
/* Transfer one block at a time. */ | /* Transfer one block at a time. */ | ||||
#ifdef MMCCAM | |||||
if (slot->curcmd->data->flags & MMC_DATA_BLOCK_SIZE) | |||||
left = min(slot->curcmd->data->block_size, | |||||
slot->curcmd->data->len - slot->offset); | |||||
else | |||||
#endif | |||||
left = min(512, slot->curcmd->data->len - slot->offset); | left = min(512, slot->curcmd->data->len - slot->offset); | ||||
slot->offset += left; | slot->offset += left; | ||||
/* If we are too fast, broken controllers return zeroes. */ | /* If we are too fast, broken controllers return zeroes. */ | ||||
if (slot->quirks & SDHCI_QUIRK_BROKEN_TIMINGS) | if (slot->quirks & SDHCI_QUIRK_BROKEN_TIMINGS) | ||||
DELAY(10); | DELAY(10); | ||||
/* Handle unaligned and aligned buffer cases. */ | /* Handle unaligned and aligned buffer cases. */ | ||||
if ((intptr_t)buffer & 3) { | if ((intptr_t)buffer & 3) { | ||||
while (left > 3) { | while (left > 3) { | ||||
Show All 26 Lines | |||||
{ | { | ||||
uint32_t data = 0; | uint32_t data = 0; | ||||
char *buffer; | char *buffer; | ||||
size_t left; | size_t left; | ||||
buffer = slot->curcmd->data->data; | buffer = slot->curcmd->data->data; | ||||
buffer += slot->offset; | buffer += slot->offset; | ||||
/* Transfer one block at a time. */ | /* Transfer one block at a time. */ | ||||
#ifdef MMCCAM | |||||
if (slot->curcmd->data->flags & MMC_DATA_BLOCK_SIZE) { | |||||
left = min(slot->curcmd->data->block_size, | |||||
slot->curcmd->data->len - slot->offset); | |||||
} else | |||||
#endif | |||||
left = min(512, slot->curcmd->data->len - slot->offset); | left = min(512, slot->curcmd->data->len - slot->offset); | ||||
slot->offset += left; | slot->offset += left; | ||||
/* Handle unaligned and aligned buffer cases. */ | /* Handle unaligned and aligned buffer cases. */ | ||||
if ((intptr_t)buffer & 3) { | if ((intptr_t)buffer & 3) { | ||||
while (left > 3) { | while (left > 3) { | ||||
data = buffer[0] + | data = buffer[0] + | ||||
(buffer[1] << 8) + | (buffer[1] << 8) + | ||||
(buffer[2] << 16) + | (buffer[2] << 16) + | ||||
▲ Show 20 Lines • Show All 1,067 Lines • ▼ Show 20 Lines | |||||
sdhci_set_transfer_mode(struct sdhci_slot *slot, const struct mmc_data *data) | sdhci_set_transfer_mode(struct sdhci_slot *slot, const struct mmc_data *data) | ||||
{ | { | ||||
uint16_t mode; | uint16_t mode; | ||||
if (data == NULL) | if (data == NULL) | ||||
return; | return; | ||||
mode = SDHCI_TRNS_BLK_CNT_EN; | mode = SDHCI_TRNS_BLK_CNT_EN; | ||||
if (data->len > 512) { | if (data->len > 512 || data->block_count > 1) { | ||||
mode |= SDHCI_TRNS_MULTI; | mode |= SDHCI_TRNS_MULTI; | ||||
if (__predict_true( | if (data->block_count == 0 && __predict_true( | ||||
#ifdef MMCCAM | #ifdef MMCCAM | ||||
slot->ccb->mmcio.stop.opcode == MMC_STOP_TRANSMISSION && | slot->ccb->mmcio.stop.opcode == MMC_STOP_TRANSMISSION && | ||||
#else | #else | ||||
slot->req->stop != NULL && | slot->req->stop != NULL && | ||||
#endif | #endif | ||||
!(slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP))) | !(slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP))) | ||||
mode |= SDHCI_TRNS_ACMD12; | mode |= SDHCI_TRNS_ACMD12; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 246 Lines • ▼ Show 20 Lines | if (slot->flags & SDHCI_USE_DMA) { | ||||
if (data->len == sdma_bbufsz) | if (data->len == sdma_bbufsz) | ||||
slot->intmask &= ~SDHCI_INT_DMA_END; | slot->intmask &= ~SDHCI_INT_DMA_END; | ||||
else | else | ||||
slot->intmask |= SDHCI_INT_DMA_END; | slot->intmask |= SDHCI_INT_DMA_END; | ||||
WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask); | WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask); | ||||
} | } | ||||
/* Current data offset for both PIO and DMA. */ | /* Current data offset for both PIO and DMA. */ | ||||
slot->offset = 0; | slot->offset = 0; | ||||
#ifdef MMCCAM | |||||
if (data->flags & MMC_DATA_BLOCK_SIZE) { | |||||
/* Set block size and request border interrupts on the SDMA boundary. */ | /* Set block size and request border interrupts on the SDMA boundary. */ | ||||
blksz = SDHCI_MAKE_BLKSZ(slot->sdma_boundary, data->block_size); | |||||
blkcnt = data->block_count; | |||||
if (__predict_false(sdhci_debug > 0)) | |||||
slot_printf(slot, "SDIO Custom block params: blksz: " | |||||
"%#10x, blk cnt: %#10x\n", blksz, blkcnt); | |||||
} else | |||||
#endif | |||||
{ | |||||
/* Set block size and request border interrupts on the SDMA boundary. */ | |||||
blksz = SDHCI_MAKE_BLKSZ(slot->sdma_boundary, ulmin(data->len, 512)); | blksz = SDHCI_MAKE_BLKSZ(slot->sdma_boundary, ulmin(data->len, 512)); | ||||
WR2(slot, SDHCI_BLOCK_SIZE, blksz); | |||||
/* Set block count. */ | |||||
blkcnt = howmany(data->len, 512); | blkcnt = howmany(data->len, 512); | ||||
} | |||||
WR2(slot, SDHCI_BLOCK_SIZE, blksz); | |||||
WR2(slot, SDHCI_BLOCK_COUNT, blkcnt); | WR2(slot, SDHCI_BLOCK_COUNT, blkcnt); | ||||
if (__predict_false(sdhci_debug > 1)) | if (__predict_false(sdhci_debug > 1)) | ||||
slot_printf(slot, "Blk size: 0x%08x | Blk cnt: 0x%08x\n", | slot_printf(slot, "Blk size: 0x%08x | Blk cnt: 0x%08x\n", | ||||
blksz, blkcnt); | blksz, blkcnt); | ||||
} | } | ||||
void | void | ||||
sdhci_finish_data(struct sdhci_slot *slot) | sdhci_finish_data(struct sdhci_slot *slot) | ||||
▲ Show 20 Lines • Show All 872 Lines • ▼ Show 20 Lines | sdhci_cam_request(struct sdhci_slot *slot, union ccb *ccb) | ||||
SDHCI_LOCK(slot); | SDHCI_LOCK(slot); | ||||
/* if (slot->req != NULL) { | /* if (slot->req != NULL) { | ||||
SDHCI_UNLOCK(slot); | SDHCI_UNLOCK(slot); | ||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
*/ | */ | ||||
if (__predict_false(sdhci_debug > 1)) { | if (__predict_false(sdhci_debug > 1)) { | ||||
slot_printf(slot, "CMD%u arg %#x flags %#x dlen %u dflags %#x\n", | slot_printf(slot, "CMD%u arg %#x flags %#x dlen %u dflags %#x " | ||||
"blksz=%zu blkcnt=%zu\n", | |||||
mmcio->cmd.opcode, mmcio->cmd.arg, mmcio->cmd.flags, | mmcio->cmd.opcode, mmcio->cmd.arg, mmcio->cmd.flags, | ||||
mmcio->cmd.data != NULL ? (unsigned int) mmcio->cmd.data->len : 0, | mmcio->cmd.data != NULL ? (unsigned int) mmcio->cmd.data->len : 0, | ||||
mmcio->cmd.data != NULL ? mmcio->cmd.data->flags: 0); | mmcio->cmd.data != NULL ? mmcio->cmd.data->flags : 0, | ||||
mmcio->cmd.data != NULL ? mmcio->cmd.data->block_size : 0, | |||||
mmcio->cmd.data != NULL ? mmcio->cmd.data->block_count : 0); | |||||
bz: I'd put <blank>: 0 for the last three lines like for len : 0, but that's only a style nit. | |||||
Done Inline ActionsAck kibab: Ack | |||||
} | } | ||||
if (mmcio->cmd.data != NULL) { | if (mmcio->cmd.data != NULL) { | ||||
if (mmcio->cmd.data->len == 0 || mmcio->cmd.data->flags == 0) | if (mmcio->cmd.data->len == 0 || mmcio->cmd.data->flags == 0) | ||||
panic("data->len = %d, data->flags = %d -- something is b0rked", | panic("data->len = %d, data->flags = %d -- something is b0rked", | ||||
(int)mmcio->cmd.data->len, mmcio->cmd.data->flags); | (int)mmcio->cmd.data->len, mmcio->cmd.data->flags); | ||||
} | } | ||||
slot->ccb = ccb; | slot->ccb = ccb; | ||||
slot->flags = 0; | slot->flags = 0; | ||||
Show All 13 Lines |
I'd put <blank>: 0 for the last three lines like for len : 0, but that's only a style nit.