Changeset View
Changeset View
Standalone View
Standalone View
head/sys/cam/mmc/mmc_da.c
Show First 20 Lines • Show All 196 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
return (false); | return (false); | ||||
} | } | ||||
static uint32_t mmc_get_spec_vers(struct cam_periph *periph); | static uint32_t mmc_get_spec_vers(struct cam_periph *periph); | ||||
static uint64_t mmc_get_media_size(struct cam_periph *periph); | static uint64_t mmc_get_media_size(struct cam_periph *periph); | ||||
static uint32_t mmc_get_cmd6_timeout(struct cam_periph *periph); | static uint32_t mmc_get_cmd6_timeout(struct cam_periph *periph); | ||||
static void sdda_add_part(struct cam_periph *periph, u_int type, | static bool sdda_add_part(struct cam_periph *periph, u_int type, | ||||
const char *name, u_int cnt, off_t media_size, bool ro); | const char *name, u_int cnt, off_t media_size, bool ro); | ||||
static struct periph_driver sddadriver = | static struct periph_driver sddadriver = | ||||
{ | { | ||||
sddainit, "sdda", | sddainit, "sdda", | ||||
TAILQ_HEAD_INITIALIZER(sddadriver.units), /* generation */ 0 | TAILQ_HEAD_INITIALIZER(sddadriver.units), /* generation */ 0 | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 1,283 Lines • ▼ Show 20 Lines | finish_hs_tests: | ||||
softc->state = SDDA_STATE_NORMAL; | softc->state = SDDA_STATE_NORMAL; | ||||
cam_periph_unhold(periph); | cam_periph_unhold(periph); | ||||
/* MMC partitions support */ | /* MMC partitions support */ | ||||
if (mmcp->card_features & CARD_FEATURE_MMC && mmc_get_spec_vers(periph) >= 4) { | if (mmcp->card_features & CARD_FEATURE_MMC && mmc_get_spec_vers(periph) >= 4) { | ||||
sdda_process_mmc_partitions(periph, start_ccb); | sdda_process_mmc_partitions(periph, start_ccb); | ||||
} else if (mmcp->card_features & CARD_FEATURE_SD20) { | } else if (mmcp->card_features & CARD_FEATURE_SD20) { | ||||
/* For SD[HC] cards, just add one partition that is the whole card */ | /* For SD[HC] cards, just add one partition that is the whole card */ | ||||
sdda_add_part(periph, 0, "sdda", | if (sdda_add_part(periph, 0, "sdda", | ||||
periph->unit_number, | periph->unit_number, | ||||
mmc_get_media_size(periph), | mmc_get_media_size(periph), | ||||
sdda_get_read_only(periph, start_ccb)); | sdda_get_read_only(periph, start_ccb)) == false) | ||||
return; | |||||
softc->part_curr = 0; | softc->part_curr = 0; | ||||
} | } | ||||
cam_periph_hold(periph, PRIBIO|PCATCH); | cam_periph_hold(periph, PRIBIO|PCATCH); | ||||
xpt_announce_periph(periph, softc->card_id_string); | xpt_announce_periph(periph, softc->card_id_string); | ||||
/* | /* | ||||
* Add async callbacks for bus reset and bus device reset calls. | * Add async callbacks for bus reset and bus device reset calls. | ||||
* I don't bother checking if this fails as, in most cases, | * I don't bother checking if this fails as, in most cases, | ||||
* the system will function just fine without them and the only | * the system will function just fine without them and the only | ||||
* alternative would be to not attach the device on failure. | * alternative would be to not attach the device on failure. | ||||
*/ | */ | ||||
xpt_register_async(AC_LOST_DEVICE | AC_GETDEV_CHANGED | | xpt_register_async(AC_LOST_DEVICE | AC_GETDEV_CHANGED | | ||||
AC_ADVINFO_CHANGED, sddaasync, periph, periph->path); | AC_ADVINFO_CHANGED, sddaasync, periph, periph->path); | ||||
} | } | ||||
static void | static bool | ||||
sdda_add_part(struct cam_periph *periph, u_int type, const char *name, | sdda_add_part(struct cam_periph *periph, u_int type, const char *name, | ||||
u_int cnt, off_t media_size, bool ro) | u_int cnt, off_t media_size, bool ro) | ||||
{ | { | ||||
struct sdda_softc *sc = (struct sdda_softc *)periph->softc; | struct sdda_softc *sc = (struct sdda_softc *)periph->softc; | ||||
struct sdda_part *part; | struct sdda_part *part; | ||||
struct ccb_pathinq cpi; | struct ccb_pathinq cpi; | ||||
CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, | CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, | ||||
("Partition type '%s', size %ju %s\n", | ("Partition type '%s', size %ju %s\n", | ||||
part_type(type), | part_type(type), | ||||
media_size, | media_size, | ||||
ro ? "(read-only)" : "")); | ro ? "(read-only)" : "")); | ||||
part = sc->part[type] = malloc(sizeof(*part), M_DEVBUF, | part = sc->part[type] = malloc(sizeof(*part), M_DEVBUF, | ||||
M_WAITOK | M_ZERO); | M_NOWAIT | M_ZERO); | ||||
if (part == NULL) { | |||||
printf("Cannot add partition for sdda\n"); | |||||
return (false); | |||||
} | |||||
part->cnt = cnt; | part->cnt = cnt; | ||||
part->type = type; | part->type = type; | ||||
part->ro = ro; | part->ro = ro; | ||||
part->sc = sc; | part->sc = sc; | ||||
snprintf(part->name, sizeof(part->name), name, periph->unit_number); | snprintf(part->name, sizeof(part->name), name, periph->unit_number); | ||||
/* | /* | ||||
* Due to the nature of RPMB partition it doesn't make much sense | * Due to the nature of RPMB partition it doesn't make much sense | ||||
* to add it as a disk. It would be more appropriate to create a | * to add it as a disk. It would be more appropriate to create a | ||||
* userland tool to operate on the partition or leverage the existing | * userland tool to operate on the partition or leverage the existing | ||||
* tools from sysutils/mmc-utils. | * tools from sysutils/mmc-utils. | ||||
*/ | */ | ||||
if (type == EXT_CSD_PART_CONFIG_ACC_RPMB) { | if (type == EXT_CSD_PART_CONFIG_ACC_RPMB) { | ||||
/* TODO: Create device, assign IOCTL handler */ | /* TODO: Create device, assign IOCTL handler */ | ||||
CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, | CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, | ||||
("Don't know what to do with RPMB partitions yet\n")); | ("Don't know what to do with RPMB partitions yet\n")); | ||||
return; | return (false); | ||||
} | } | ||||
bioq_init(&part->bio_queue); | bioq_init(&part->bio_queue); | ||||
bzero(&cpi, sizeof(cpi)); | bzero(&cpi, sizeof(cpi)); | ||||
xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE); | xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE); | ||||
cpi.ccb_h.func_code = XPT_PATH_INQ; | cpi.ccb_h.func_code = XPT_PATH_INQ; | ||||
xpt_action((union ccb *)&cpi); | xpt_action((union ccb *)&cpi); | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | // sc->disk->d_dump = sddadump; | ||||
* Acquire a reference to the periph before we register with GEOM. | * Acquire a reference to the periph before we register with GEOM. | ||||
* We'll release this reference once GEOM calls us back (via | * We'll release this reference once GEOM calls us back (via | ||||
* sddadiskgonecb()) telling us that our provider has been freed. | * sddadiskgonecb()) telling us that our provider has been freed. | ||||
*/ | */ | ||||
if (cam_periph_acquire(periph) != 0) { | if (cam_periph_acquire(periph) != 0) { | ||||
xpt_print(periph->path, "%s: lost periph during " | xpt_print(periph->path, "%s: lost periph during " | ||||
"registration!\n", __func__); | "registration!\n", __func__); | ||||
cam_periph_lock(periph); | cam_periph_lock(periph); | ||||
return; | return (false); | ||||
} | } | ||||
disk_create(part->disk, DISK_VERSION); | disk_create(part->disk, DISK_VERSION); | ||||
cam_periph_lock(periph); | cam_periph_lock(periph); | ||||
cam_periph_unhold(periph); | cam_periph_unhold(periph); | ||||
return (true); | |||||
} | } | ||||
/* | /* | ||||
* For MMC cards, process EXT_CSD and add partitions that are supported by | * For MMC cards, process EXT_CSD and add partitions that are supported by | ||||
* this device. | * this device. | ||||
*/ | */ | ||||
static void | static void | ||||
sdda_process_mmc_partitions(struct cam_periph *periph, union ccb *ccb) | sdda_process_mmc_partitions(struct cam_periph *periph, union ccb *ccb) | ||||
▲ Show 20 Lines • Show All 384 Lines • Show Last 20 Lines |