Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Apr 2019 18:49:40 +0000 (UTC)
From:      Ilya Bakulin <kibab@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r345775 - in head/sys: arm/allwinner cam cam/mmc dev/sdhci
Message-ID:  <201904011849.x31IneXA084037@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kibab
Date: Mon Apr  1 18:49:39 2019
New Revision: 345775
URL: https://svnweb.freebsd.org/changeset/base/345775

Log:
  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

Modified:
  head/sys/arm/allwinner/aw_mmc.c
  head/sys/cam/cam_ccb.h
  head/sys/cam/mmc/mmc_da.c
  head/sys/dev/sdhci/sdhci.c

Modified: head/sys/arm/allwinner/aw_mmc.c
==============================================================================
--- head/sys/arm/allwinner/aw_mmc.c	Mon Apr  1 18:35:27 2019	(r345774)
+++ head/sys/arm/allwinner/aw_mmc.c	Mon Apr  1 18:49:39 2019	(r345775)
@@ -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;

Modified: head/sys/cam/cam_ccb.h
==============================================================================
--- head/sys/cam/cam_ccb.h	Mon Apr  1 18:35:27 2019	(r345774)
+++ head/sys/cam/cam_ccb.h	Mon Apr  1 18:49:39 2019	(r345775)
@@ -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 */

Modified: head/sys/cam/mmc/mmc_da.c
==============================================================================
--- head/sys/cam/mmc/mmc_da.c	Mon Apr  1 18:35:27 2019	(r345774)
+++ head/sys/cam/mmc/mmc_da.c	Mon Apr  1 18:49:39 2019	(r345775)
@@ -1195,6 +1195,27 @@ sdda_get_host_caps(struct cam_periph *periph, union cc
 	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, c
 	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, c
 	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,

Modified: head/sys/dev/sdhci/sdhci.c
==============================================================================
--- head/sys/dev/sdhci/sdhci.c	Mon Apr  1 18:35:27 2019	(r345774)
+++ head/sys/dev/sdhci/sdhci.c	Mon Apr  1 18:49:39 2019	(r345775)
@@ -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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904011849.x31IneXA084037>