Use information about max data size that the controller is able to operate
Using DFLTPHYS/MAXPHYS is not always OK, instead make it possible for the controller driver to provide maximum data size to MMCCAM, and use it there. The old stack already does this. Reviewed by: manu Approved by: imp (mentor) Differential Revision: https://reviews.freebsd.org/D15892
This commit is contained in:
parent
e9e2022e74
commit
5d20e65174
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=345775
@ -256,6 +256,8 @@ aw_mmc_cam_action(struct cam_sim *sim, union ccb *ccb)
|
||||
cts->proto_specific.mmc.host_f_min = sc->aw_host.f_min;
|
||||
cts->proto_specific.mmc.host_f_max = sc->aw_host.f_max;
|
||||
cts->proto_specific.mmc.host_caps = sc->aw_host.caps;
|
||||
cts->proto_specific.mmc.host_max_data = (sc->aw_mmc_conf->dma_xferlen *
|
||||
AW_MMC_DMA_SEGS) / MMC_SECTOR_SIZE;
|
||||
memcpy(&cts->proto_specific.mmc.ios, &sc->aw_host.ios, sizeof(struct mmc_ios));
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
break;
|
||||
|
@ -1051,6 +1051,7 @@ struct ccb_trans_settings_mmc {
|
||||
#define MMC_CAP_8_BIT_DATA (1 << 1) /* Can do 8-bit data transfers */
|
||||
#define MMC_CAP_HSPEED (1 << 2) /* Can do High Speed transfers */
|
||||
uint32_t host_caps;
|
||||
uint32_t host_max_data;
|
||||
};
|
||||
|
||||
/* Get/Set transfer rate/width/disconnection/tag queueing settings */
|
||||
|
@ -1195,6 +1195,27 @@ sdda_get_host_caps(struct cam_periph *periph, union ccb *ccb)
|
||||
return (cts->host_caps);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
sdda_get_max_data(struct cam_periph *periph, union ccb *ccb)
|
||||
{
|
||||
struct ccb_trans_settings_mmc *cts;
|
||||
|
||||
cts = &ccb->cts.proto_specific.mmc;
|
||||
memset(cts, 0, sizeof(struct ccb_trans_settings_mmc));
|
||||
|
||||
ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
|
||||
ccb->ccb_h.flags = CAM_DIR_NONE;
|
||||
ccb->ccb_h.retry_count = 0;
|
||||
ccb->ccb_h.timeout = 100;
|
||||
ccb->ccb_h.cbfcnp = NULL;
|
||||
xpt_action(ccb);
|
||||
|
||||
if (ccb->ccb_h.status != CAM_REQ_CMP)
|
||||
panic("Cannot get host max data");
|
||||
KASSERT(cts->host_max_data != 0, ("host_max_data == 0?!"));
|
||||
return (cts->host_max_data);
|
||||
}
|
||||
|
||||
static void
|
||||
sdda_start_init(void *context, union ccb *start_ccb)
|
||||
{
|
||||
@ -1420,7 +1441,6 @@ sdda_add_part(struct cam_periph *periph, u_int type, const char *name,
|
||||
struct sdda_softc *sc = (struct sdda_softc *)periph->softc;
|
||||
struct sdda_part *part;
|
||||
struct ccb_pathinq cpi;
|
||||
u_int maxio;
|
||||
|
||||
CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
|
||||
("Partition type '%s', size %ju %s\n",
|
||||
@ -1479,12 +1499,9 @@ sdda_add_part(struct cam_periph *periph, u_int type, const char *name,
|
||||
part->disk->d_gone = sddadiskgonecb;
|
||||
part->disk->d_name = part->name;
|
||||
part->disk->d_drv1 = part;
|
||||
maxio = cpi.maxio; /* Honor max I/O size of SIM */
|
||||
if (maxio == 0)
|
||||
maxio = DFLTPHYS; /* traditional default */
|
||||
else if (maxio > MAXPHYS)
|
||||
maxio = MAXPHYS; /* for safety */
|
||||
part->disk->d_maxsize = maxio;
|
||||
part->disk->d_maxsize =
|
||||
MIN(MAXPHYS, sdda_get_max_data(periph,
|
||||
(union ccb *)&cpi) * mmc_get_sector_size(periph));
|
||||
part->disk->d_unit = cnt;
|
||||
part->disk->d_flags = 0;
|
||||
strlcpy(part->disk->d_descr, sc->card_id_string,
|
||||
|
@ -2580,6 +2580,7 @@ sdhci_cam_action(struct cam_sim *sim, union ccb *ccb)
|
||||
case XPT_GET_TRAN_SETTINGS:
|
||||
{
|
||||
struct ccb_trans_settings *cts = &ccb->cts;
|
||||
uint32_t max_data;
|
||||
|
||||
if (sdhci_debug > 1)
|
||||
slot_printf(slot, "Got XPT_GET_TRAN_SETTINGS\n");
|
||||
@ -2593,6 +2594,19 @@ sdhci_cam_action(struct cam_sim *sim, union ccb *ccb)
|
||||
cts->proto_specific.mmc.host_f_min = slot->host.f_min;
|
||||
cts->proto_specific.mmc.host_f_max = slot->host.f_max;
|
||||
cts->proto_specific.mmc.host_caps = slot->host.caps;
|
||||
/*
|
||||
* Re-tuning modes 1 and 2 restrict the maximum data length
|
||||
* per read/write command to 4 MiB.
|
||||
*/
|
||||
if (slot->opt & SDHCI_TUNING_ENABLED &&
|
||||
(slot->retune_mode == SDHCI_RETUNE_MODE_1 ||
|
||||
slot->retune_mode == SDHCI_RETUNE_MODE_2)) {
|
||||
max_data = 4 * 1024 * 1024 / MMC_SECTOR_SIZE;
|
||||
} else {
|
||||
max_data = 65535;
|
||||
}
|
||||
cts->proto_specific.mmc.host_max_data = max_data;
|
||||
|
||||
memcpy(&cts->proto_specific.mmc.ios, &slot->host.ios, sizeof(struct mmc_ios));
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user