Changeset View
Changeset View
Standalone View
Standalone View
sys/cam/mmc/mmc_da.c
Show First 20 Lines • Show All 785 Lines • ▼ Show 20 Lines | if (softc == NULL) { | ||||
printf("sddaregister: Unable to probe new device. " | printf("sddaregister: Unable to probe new device. " | ||||
"Unable to allocate softc\n"); | "Unable to allocate softc\n"); | ||||
return (CAM_REQ_CMP_ERR); | return (CAM_REQ_CMP_ERR); | ||||
} | } | ||||
softc->state = SDDA_STATE_INIT; | softc->state = SDDA_STATE_INIT; | ||||
softc->mmcdata = | softc->mmcdata = | ||||
(struct mmc_data *)malloc(sizeof(struct mmc_data), M_DEVBUF, M_NOWAIT|M_ZERO); | (struct mmc_data *)malloc(sizeof(struct mmc_data), M_DEVBUF, M_NOWAIT|M_ZERO); | ||||
if (softc->mmcdata == NULL) { | |||||
imp: In theory, we should retry at some other level... In practice, this will never happen and it's… | |||||
printf("sddaregister: Unable to probe new device. " | |||||
"Unable to allocate mmcdata\n"); | |||||
return (CAM_REQ_CMP_ERR); | |||||
} | |||||
periph->softc = softc; | periph->softc = softc; | ||||
Done Inline ActionsOn a side-note; that malloc can fail... bz: On a side-note; that malloc can fail... | |||||
Done Inline ActionsAdded a check for that. kibab: Added a check for that. | |||||
softc->periph = periph; | softc->periph = periph; | ||||
request_ccb = (union ccb*) arg; | request_ccb = (union ccb*) arg; | ||||
xpt_schedule(periph, CAM_PRIORITY_XPT); | xpt_schedule(periph, CAM_PRIORITY_XPT); | ||||
TASK_INIT(&softc->start_init_task, 0, sdda_start_init_task, periph); | TASK_INIT(&softc->start_init_task, 0, sdda_start_init_task, periph); | ||||
taskqueue_enqueue(taskqueue_thread, &softc->start_init_task); | taskqueue_enqueue(taskqueue_thread, &softc->start_init_task); | ||||
return (CAM_REQ_CMP); | return (CAM_REQ_CMP); | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
mmc_send_ext_csd(struct cam_periph *periph, union ccb *ccb, | mmc_send_ext_csd(struct cam_periph *periph, union ccb *ccb, | ||||
uint8_t *rawextcsd, size_t buf_len) { | uint8_t *rawextcsd, size_t buf_len) { | ||||
int err; | int err; | ||||
struct mmc_data d; | struct mmc_data d; | ||||
KASSERT(buf_len == 512, ("Buffer for ext csd must be 512 bytes")); | KASSERT(buf_len == 512, ("Buffer for ext csd must be 512 bytes")); | ||||
memset(&d, 0, sizeof(d)); | |||||
d.data = rawextcsd; | d.data = rawextcsd; | ||||
d.len = buf_len; | d.len = buf_len; | ||||
d.flags = MMC_DATA_READ; | d.flags = MMC_DATA_READ; | ||||
memset(d.data, 0, d.len); | memset(d.data, 0, d.len); | ||||
cam_fill_mmcio(&ccb->mmcio, | cam_fill_mmcio(&ccb->mmcio, | ||||
/*retries*/ 0, | /*retries*/ 0, | ||||
/*cbfcnp*/ NULL, | /*cbfcnp*/ NULL, | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | mmc_sd_switch(struct cam_periph *periph, union ccb *ccb, | ||||
uint8_t mode, uint8_t grp, uint8_t value, | uint8_t mode, uint8_t grp, uint8_t value, | ||||
uint8_t *res) { | uint8_t *res) { | ||||
struct mmc_data mmc_d; | struct mmc_data mmc_d; | ||||
uint32_t arg; | uint32_t arg; | ||||
int err; | int err; | ||||
memset(res, 0, 64); | memset(res, 0, 64); | ||||
memset(&mmc_d, 0, sizeof(mmc_d)); | |||||
mmc_d.len = 64; | mmc_d.len = 64; | ||||
mmc_d.data = res; | mmc_d.data = res; | ||||
mmc_d.flags = MMC_DATA_READ; | mmc_d.flags = MMC_DATA_READ; | ||||
arg = mode << 31; /* 0 - check, 1 - set */ | arg = mode << 31; /* 0 - check, 1 - set */ | ||||
arg |= 0x00FFFFFF; | arg |= 0x00FFFFFF; | ||||
arg &= ~(0xF << (grp * 4)); | arg &= ~(0xF << (grp * 4)); | ||||
arg |= value << (grp * 4); | arg |= value << (grp * 4); | ||||
▲ Show 20 Lines • Show All 775 Lines • ▼ Show 20 Lines | case BIO_READ: | ||||
mmcio = &start_ccb->mmcio; | mmcio = &start_ccb->mmcio; | ||||
mmcio->cmd.opcode = opcode; | mmcio->cmd.opcode = opcode; | ||||
mmcio->cmd.arg = blockno; | mmcio->cmd.arg = blockno; | ||||
if (!(mmcp->card_features & CARD_FEATURE_SDHC)) | if (!(mmcp->card_features & CARD_FEATURE_SDHC)) | ||||
mmcio->cmd.arg <<= 9; | mmcio->cmd.arg <<= 9; | ||||
mmcio->cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | mmcio->cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||||
mmcio->cmd.data = softc->mmcdata; | mmcio->cmd.data = softc->mmcdata; | ||||
memset(mmcio->cmd.data, 0, sizeof(struct mmc_data)); | |||||
mmcio->cmd.data->data = bp->bio_data; | mmcio->cmd.data->data = bp->bio_data; | ||||
mmcio->cmd.data->len = 512 * count; | mmcio->cmd.data->len = 512 * count; | ||||
mmcio->cmd.data->flags = (bp->bio_cmd == BIO_READ ? MMC_DATA_READ : MMC_DATA_WRITE); | mmcio->cmd.data->flags = (bp->bio_cmd == BIO_READ ? MMC_DATA_READ : MMC_DATA_WRITE); | ||||
/* Direct h/w to issue CMD12 upon completion */ | /* Direct h/w to issue CMD12 upon completion */ | ||||
Done Inline ActionsThe softc mmcdata is allocated with M_ZERO; if it is not used anywhere else than here block_count and block_size are never touched so wouldn't need to be set to 0. bz: The softc mmcdata is allocated with M_ZERO; if it is not used anywhere else than here… | |||||
Done Inline ActionsThat mmcdata ends up being used in each sddastart(), so we _do_ need to initialize the fields. But you are right, I'd rather add memset(,0,). kibab: That mmcdata ends up being used in each sddastart(), so we _do_ need to initialize the fields. | |||||
if (count > 1) { | if (count > 1) { | ||||
mmcio->cmd.data->flags |= MMC_DATA_MULTI; | mmcio->cmd.data->flags |= MMC_DATA_MULTI; | ||||
mmcio->stop.opcode = MMC_STOP_TRANSMISSION; | mmcio->stop.opcode = MMC_STOP_TRANSMISSION; | ||||
mmcio->stop.flags = MMC_RSP_R1B | MMC_CMD_AC; | mmcio->stop.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||||
mmcio->stop.arg = 0; | mmcio->stop.arg = 0; | ||||
} | } | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 112 Lines • Show Last 20 Lines |
In theory, we should retry at some other level... In practice, this will never happen and it's likely super hard to do that retry right anyway with any kind of meaningful testing... Other periph drivers do this so it's fine.