Index: sys/cam/mmc/mmc_da.c =================================================================== --- sys/cam/mmc/mmc_da.c +++ sys/cam/mmc/mmc_da.c @@ -150,6 +150,17 @@ struct timeval log_time; }; +static const char *mmc_errmsg[] = +{ + "None", + "Timeout", + "Bad CRC", + "Fifo", + "Failed", + "Invalid", + "NO MEMORY" +}; + #define ccb_bp ppriv_ptr1 static disk_strategy_t sddastrategy; @@ -165,6 +176,7 @@ static int sddaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags); +static int mmc_handle_reply(union ccb *ccb); static uint16_t get_rca(struct cam_periph *periph); static void sdda_start_init(void *context, union ccb *start_ccb); static void sdda_start_init_task(void *context, int pending); @@ -218,6 +230,36 @@ return periph->path->device->mmc_ident_data.card_rca; } +/* + * Figure out if CCB execution resulted in error. + * Look at both CAM-level errors and on MMC protocol errors. +*/ +static int +mmc_handle_reply(union ccb *ccb) +{ + + if (ccb->ccb_h.func_code != XPT_MMC_IO) + panic("__func__: don't know how to handle non-XPT_MMC_IO errors"); + + /* TODO: maybe put MMC-specific handling into cam.c/cam_error_print altogether */ + if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) { + if (ccb->mmcio.cmd.error != 0) { + xpt_print_path(ccb->ccb_h.path); + printf("CMD%d failed, err %d (%s)\n", + ccb->mmcio.cmd.opcode, + ccb->mmcio.cmd.error, + mmc_errmsg[ccb->mmcio.cmd.error]); + return (EIO); + } + } else { + cam_error_print(ccb, CAM_ESF_ALL, CAM_EPF_ALL); + return (EIO); + } + + return (0); /* Normal return */ +} + + static uint32_t mmc_get_bits(uint32_t *bits, int bit_len, int start, int size) { @@ -777,11 +819,12 @@ /*mmc_data*/ NULL, /*timeout*/ 0); - err = cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); + cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); + err = mmc_handle_reply(ccb); if (err != 0) - return err; + return (err); if (!(ccb->mmcio.cmd.resp[0] & R1_APP_CMD)) - return MMC_ERR_FAILED; + return (MMC_ERR_FAILED); /* Now exec actual command */ int flags = 0; @@ -803,12 +846,14 @@ /*mmc_data*/ cmd->data, /*timeout*/ 0); - err = cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); + cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); + err = mmc_handle_reply(ccb); + if (err != 0) + return (err); memcpy(cmd->resp, ccb->mmcio.cmd.resp, sizeof(cmd->resp)); cmd->error = ccb->mmcio.cmd.error; - if (err != 0) - return err; - return 0; + + return (0); } static int @@ -858,10 +903,9 @@ /*mmc_data*/ &d, /*timeout*/ 0); - err = cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); - if (err != 0) - return (err); - return (MMC_ERR_NONE); + cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); + err = mmc_handle_reply(ccb); + return (err); } static void @@ -904,7 +948,7 @@ static int mmc_select_card(struct cam_periph *periph, union ccb *ccb, uint32_t rca) { - int flags; + int flags, err; flags = (rca ? MMC_RSP_R1B : MMC_RSP_NONE) | MMC_CMD_AC; cam_fill_mmcio(&ccb->mmcio, @@ -918,42 +962,20 @@ /*timeout*/ 0); cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); - - if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) { - if (ccb->mmcio.cmd.error != 0) { - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_PERIPH, - ("%s: MMC_SELECT command failed", __func__)); - return EIO; - } - return 0; /* Normal return */ - } else { - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_PERIPH, - ("%s: CAM request failed\n", __func__)); - return EIO; - } + err = mmc_handle_reply(ccb); + return (err); } static int mmc_switch(struct cam_periph *periph, union ccb *ccb, uint8_t set, uint8_t index, uint8_t value, u_int timeout) { + int err; mmc_switch_fill_mmcio(ccb, set, index, value, timeout); cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); - - if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) { - if (ccb->mmcio.cmd.error != 0) { - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_PERIPH, - ("%s: MMC command failed", __func__)); - return (EIO); - } - return (0); /* Normal return */ - } else { - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_PERIPH, - ("%s: CAM request failed\n", __func__)); - return (EIO); - } - + err = mmc_handle_reply(ccb); + return (err); } static uint32_t @@ -987,6 +1009,7 @@ struct mmc_data mmc_d; uint32_t arg; + int err; memset(res, 0, 64); mmc_d.len = 64; @@ -1009,19 +1032,8 @@ /*timeout*/ 0); cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL); - - if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) { - if (ccb->mmcio.cmd.error != 0) { - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_PERIPH, - ("%s: MMC command failed", __func__)); - return EIO; - } - return 0; /* Normal return */ - } else { - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_PERIPH, - ("%s: CAM request failed\n", __func__)); - return EIO; - } + err = mmc_handle_reply(ccb); + return (err); } static int