Changeset View
Standalone View
sys/cam/mmc/mmc_xpt.c
Show First 20 Lines • Show All 386 Lines • ▼ Show 20 Lines | |||||
mmc_announce_periph(struct cam_periph *periph) | mmc_announce_periph(struct cam_periph *periph) | ||||
{ | { | ||||
struct ccb_pathinq cpi; | struct ccb_pathinq cpi; | ||||
struct ccb_trans_settings cts; | struct ccb_trans_settings cts; | ||||
struct cam_path *path = periph->path; | struct cam_path *path = periph->path; | ||||
cam_periph_assert(periph, MA_OWNED); | cam_periph_assert(periph, MA_OWNED); | ||||
CAM_DEBUG(periph->path, CAM_DEBUG_INFO, | CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("mmc_announce_periph")); | ||||
("mmc_announce_periph: called\n")); | |||||
xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); | xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL); | ||||
cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; | cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; | ||||
cts.type = CTS_TYPE_CURRENT_SETTINGS; | cts.type = CTS_TYPE_CURRENT_SETTINGS; | ||||
xpt_action((union ccb*)&cts); | xpt_action((union ccb*)&cts); | ||||
if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) | if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) | ||||
return; | return; | ||||
xpt_path_inq(&cpi, periph->path); | xpt_path_inq(&cpi, periph->path); | ||||
printf("XPT info: CLK %04X, ...\n", cts.proto_specific.mmc.ios.clock); | printf("XPT info: CLK %04X, ...\n", cts.proto_specific.mmc.ios.clock); | ||||
} | } | ||||
void | void | ||||
mmccam_start_discovery(struct cam_sim *sim) { | mmccam_start_discovery(struct cam_sim *sim) | ||||
{ | |||||
imp: Since I'm in the area, I'd be tempted to fix this to match style(9) | |||||
union ccb *ccb; | union ccb *ccb; | ||||
uint32_t pathid; | uint32_t pathid; | ||||
KASSERT(sim->sim_dev != NULL, ("mmccam_start_discovery(%s): sim_dev is not initialized," | |||||
Done Inline ActionsThis races the timeout that's setup in at least dwmmc_attach. It's likely OK, though, then initialize things and then call this directly from the startup.... something to think about though... imp: This races the timeout that's setup in at least dwmmc_attach. It's likely OK, though, then… | |||||
Done Inline ActionsI don't see how this KASSERT races with anything -- it's here to prevent usage of cam_sim_alloc() (without _dev()) with MMCCAM drivers since it breaks SDIO bus. kibab: I don't see how this KASSERT races with anything -- it's here to prevent usage of cam_sim_alloc… | |||||
Done Inline ActionsIt' is a good kassert, since it made me look and I found the races that I described which this KASSERT will detect on systems that are super-duper slow. Sorry if I wasn't clear about it... imp: It' is a good kassert, since it made me look and I found the races that I described which this… | |||||
" has cam_sim_alloc_dev() been used?", cam_sim_name(sim))); | |||||
pathid = cam_sim_path(sim); | pathid = cam_sim_path(sim); | ||||
ccb = xpt_alloc_ccb_nowait(); | ccb = xpt_alloc_ccb(); | ||||
Done Inline ActionsAre you allowed to block here? I didn't audit all the places this is called, but I think it's OK. imp: Are you allowed to block here? I didn't audit all the places this is called, but I think it's… | |||||
Done Inline Actionsthere are 4 call sites for this function and none happens in the interrupt context, so I guess it's fine. kibab: there are 4 call sites for this function and none happens in the interrupt context, so I guess… | |||||
if (ccb == NULL) { | |||||
return; | |||||
} | |||||
/* | /* | ||||
* We create a rescan request for BUS:0:0, since the card | * We create a rescan request for BUS:0:0, since the card | ||||
* will be at lun 0. | * will be at lun 0. | ||||
*/ | */ | ||||
if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid, | if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid, | ||||
/* target */ 0, /* lun */ 0) != CAM_REQ_CMP) { | /* target */ 0, /* lun */ 0) != CAM_REQ_CMP) { | ||||
xpt_free_ccb(ccb); | xpt_free_ccb(ccb); | ||||
device_printf(sim->sim_dev, "Cannot create path for MMC discovery request\n"); | |||||
Done Inline ActionsI don't think this can actually ever fail. imp: I don't think this can actually ever fail.
| |||||
Done Inline ActionsWell there are some calls to malloc(...,M_NOWAIT) deep inside the call stack, so I'd check the return code just in case, it's a good practice anyway. kibab: Well there are some calls to malloc(...,M_NOWAIT) deep inside the call stack, so I'd check the… | |||||
Done Inline ActionsI agree with the check, but don't think we should report it here... imp: I agree with the check, but don't think we should report it here... | |||||
return; | return; | ||||
} | } | ||||
xpt_rescan(ccb); | xpt_rescan(ccb); | ||||
} | } | ||||
/* This func is called per attached device :-( */ | /* This func is called per attached device :-( */ | ||||
void | void | ||||
mmc_print_ident(struct mmc_params *ident_data) | mmc_print_ident(struct mmc_params *ident_data) | ||||
▲ Show 20 Lines • Show All 380 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
mmcprobe_softc *softc; | mmcprobe_softc *softc; | ||||
struct cam_path *path; | struct cam_path *path; | ||||
int err; | int err; | ||||
struct ccb_mmcio *mmcio; | struct ccb_mmcio *mmcio; | ||||
u_int32_t priority; | u_int32_t priority; | ||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("mmcprobe_done\n")); | CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("mmcprobe_done\n")); | ||||
softc = (mmcprobe_softc *)periph->softc; | softc = (mmcprobe_softc *)periph->softc; | ||||
path = done_ccb->ccb_h.path; | path = done_ccb->ccb_h.path; | ||||
priority = done_ccb->ccb_h.pinfo.priority; | priority = done_ccb->ccb_h.pinfo.priority; | ||||
switch (softc->action) { | switch (softc->action) { | ||||
case PROBE_RESET: | case PROBE_RESET: | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case PROBE_IDENTIFY: | case PROBE_IDENTIFY: | ||||
{ | { | ||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("done with PROBE_RESET\n")); | CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("done with PROBE_RESET\n")); | ||||
mmcio = &done_ccb->mmcio; | mmcio = &done_ccb->mmcio; | ||||
err = mmcio->cmd.error; | err = mmcio->cmd.error; | ||||
if (err != MMC_ERR_NONE) { | if (err != MMC_ERR_NONE) { | ||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | ||||
("GO_IDLE_STATE failed with error %d\n", | ("GO_IDLE_STATE failed with error %d\n", | ||||
err)); | err)); | ||||
/* There was a device there, but now it's gone... */ | /* There was a device there, but now it's gone... */ | ||||
if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { | if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { | ||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | |||||
("Device lost!\n")); | |||||
xpt_async(AC_LOST_DEVICE, path, NULL); | xpt_async(AC_LOST_DEVICE, path, NULL); | ||||
} | } | ||||
PROBE_SET_ACTION(softc, PROBE_INVALID); | PROBE_SET_ACTION(softc, PROBE_INVALID); | ||||
break; | break; | ||||
} | } | ||||
path->device->protocol = PROTO_MMCSD; | path->device->protocol = PROTO_MMCSD; | ||||
PROBE_SET_ACTION(softc, PROBE_SEND_IF_COND); | PROBE_SET_ACTION(softc, PROBE_SEND_IF_COND); | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | if (err != MMC_ERR_NONE) { | ||||
uint32_t ioifcond = mmcio->cmd.resp[0]; | uint32_t ioifcond = mmcio->cmd.resp[0]; | ||||
uint32_t io_ocr = ioifcond & R4_IO_OCR_MASK; | uint32_t io_ocr = ioifcond & R4_IO_OCR_MASK; | ||||
mmcp->sdio_func_count = R4_IO_NUM_FUNCTIONS(ioifcond); | mmcp->sdio_func_count = R4_IO_NUM_FUNCTIONS(ioifcond); | ||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | ||||
("SDIO card: %d functions\n", mmcp->sdio_func_count)); | ("SDIO card: %d functions\n", mmcp->sdio_func_count)); | ||||
if (io_ocr == 0) { | if (io_ocr == 0) { | ||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | ||||
("SDIO OCR invalid?!\n")); | ("SDIO OCR invalid, retrying\n")); | ||||
break; /* Retry */ | break; /* Retry */ | ||||
} | } | ||||
if (io_ocr != 0 && mmcp->io_ocr == 0) { | if (io_ocr != 0 && mmcp->io_ocr == 0) { | ||||
mmcp->io_ocr = io_ocr; | mmcp->io_ocr = io_ocr; | ||||
break; /* Retry, this time with non-0 OCR */ | break; /* Retry, this time with non-0 OCR */ | ||||
} | } | ||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | ||||
▲ Show 20 Lines • Show All 207 Lines • ▼ Show 20 Lines | if (err != MMC_ERR_NONE) { | ||||
break; | break; | ||||
} | } | ||||
PROBE_SET_ACTION(softc, PROBE_DONE); | PROBE_SET_ACTION(softc, PROBE_DONE); | ||||
break; | break; | ||||
} | } | ||||
default: | default: | ||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | ||||
("mmc_probedone: invalid action state 0x%x\n", softc->action)); | ("mmcprobe_done: invalid action state 0x%x\n", softc->action)); | ||||
panic("default: case in mmc_probe_done()"); | panic("default: case in mmc_probe_done()"); | ||||
} | } | ||||
if (softc->action == PROBE_INVALID && | if (softc->action == PROBE_INVALID && | ||||
(path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { | (path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { | ||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | xpt_async(AC_LOST_DEVICE, path, NULL); | ||||
Done Inline ActionsWhy do you need to do this here? Usually the SIM sends this when it detects that a periph that used to be there has departed. imp: Why do you need to do this here? Usually the SIM sends this when it detects that a periph that… | |||||
Not Done Inline ActionsBecause we are doing this from the mmcprobe device code (which is effectively a SIM), and getting here means that the device has disappeared. kibab: Because we are doing this from the mmcprobe device code (which is effectively a SIM), and… | |||||
Not Done Inline Actionsah, so they do... I'd forgotten about that case... imp: ah, so they do... I'd forgotten about that case... | |||||
("mmc_probedone: Should send AC_LOST_DEVICE but won't for now\n")); | |||||
//xpt_async(AC_LOST_DEVICE, path, NULL); | |||||
} | } | ||||
if (softc->action != PROBE_INVALID) | if (softc->action != PROBE_INVALID) | ||||
xpt_schedule(periph, priority); | xpt_schedule(periph, priority); | ||||
/* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */ | /* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */ | ||||
int frozen = cam_release_devq(path, 0, 0, 0, FALSE); | int frozen = cam_release_devq(path, 0, 0, 0, FALSE); | ||||
CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, ("mmc_probedone: remaining freezecnt %d\n", frozen)); | CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE, | ||||
("mmcprobe_done: remaining freeze count %d\n", frozen)); | |||||
if (softc->action == PROBE_DONE) { | if (softc->action == PROBE_DONE) { | ||||
/* Notify the system that the device is found! */ | /* Notify the system that the device is found! */ | ||||
if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { | if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { | ||||
path->device->flags &= ~CAM_DEV_UNCONFIGURED; | path->device->flags &= ~CAM_DEV_UNCONFIGURED; | ||||
xpt_acquire_device(path->device); | xpt_acquire_device(path->device); | ||||
done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; | done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; | ||||
xpt_action(done_ccb); | xpt_action(done_ccb); | ||||
xpt_async(AC_FOUND_DEVICE, path, done_ccb); | xpt_async(AC_FOUND_DEVICE, path, done_ccb); | ||||
} | } | ||||
} | } | ||||
xpt_release_ccb(done_ccb); | xpt_release_ccb(done_ccb); | ||||
if (softc->action == PROBE_DONE || softc->action == PROBE_INVALID) { | if (softc->action == PROBE_DONE || softc->action == PROBE_INVALID) { | ||||
cam_periph_invalidate(periph); | cam_periph_invalidate(periph); | ||||
cam_periph_release_locked(periph); | cam_periph_release_locked(periph); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
mmc_path_inq(struct ccb_pathinq *cpi, const char *hba, | mmc_path_inq(struct ccb_pathinq *cpi, const char *hba, | ||||
const struct cam_sim *sim, size_t maxio) | const struct cam_sim *sim, size_t maxio) | ||||
{ | { | ||||
cpi->version_num = 1; | cpi->version_num = 1; | ||||
Show All 22 Lines |
Since I'm in the area, I'd be tempted to fix this to match style(9)