svn commit: r210164 - stable/8/sys/dev/ata

Alexander Motin mav at FreeBSD.org
Fri Jul 16 09:12:48 UTC 2010


Author: mav
Date: Fri Jul 16 09:12:47 2010
New Revision: 210164
URL: http://svn.freebsd.org/changeset/base/210164

Log:
  MFC r209664:
  Add ata(4) ability to limit initial ATA mode for devices via device hints.
  After boot this mode can be changed with atacontrol/camcontrol as usual.
  It works for both legacy and ATA_CAM wrapper mode.
  
  PR:             kern/123980

Modified:
  stable/8/sys/dev/ata/ata-all.c
  stable/8/sys/dev/ata/ata-all.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/dev/ata/ata-all.c
==============================================================================
--- stable/8/sys/dev/ata/ata-all.c	Fri Jul 16 09:10:11 2010	(r210163)
+++ stable/8/sys/dev/ata/ata-all.c	Fri Jul 16 09:12:47 2010	(r210164)
@@ -133,7 +133,9 @@ ata_attach(device_t dev)
     int error, rid;
 #ifdef ATA_CAM
     struct cam_devq *devq;
-    int i;
+    const char *res;
+    char buf[64];
+    int i, mode;
 #endif
 
     /* check that we have a virgin channel to attach */
@@ -152,6 +154,17 @@ ata_attach(device_t dev)
 #ifdef ATA_CAM
 	for (i = 0; i < 16; i++) {
 		ch->user[i].mode = 0;
+		snprintf(buf, sizeof(buf), "dev%d.mode", i);
+		if (resource_string_value(device_get_name(dev),
+		    device_get_unit(dev), buf, &res) == 0)
+			mode = ata_str2mode(res);
+		else if (resource_string_value(device_get_name(dev),
+		    device_get_unit(dev), "mode", &res) == 0)
+			mode = ata_str2mode(res);
+		else
+			mode = -1;
+		if (mode >= 0)
+			ch->user[i].mode = mode;
 		if (ch->flags & ATA_SATA)
 			ch->user[i].bytecount = 8192;
 		else
@@ -826,8 +839,10 @@ ata_getparam(struct ata_device *atadev, 
 {
     struct ata_channel *ch = device_get_softc(device_get_parent(atadev->dev));
     struct ata_request *request;
+    const char *res;
+    char buf[64];
     u_int8_t command = 0;
-    int error = ENOMEM, retries = 2;
+    int error = ENOMEM, retries = 2, mode = -1;
 
     if (ch->devices & (ATA_ATA_MASTER << atadev->unit))
 	command = ATA_ATA_IDENTIFY;
@@ -907,6 +922,15 @@ ata_getparam(struct ata_device *atadev, 
 		     ata_wmode(&atadev->param) > 0))
 		    atadev->mode = ATA_DMA_MAX;
 	    }
+	    snprintf(buf, sizeof(buf), "dev%d.mode", atadev->unit);
+	    if (resource_string_value(device_get_name(ch->dev),
+	        device_get_unit(ch->dev), buf, &res) == 0)
+		    mode = ata_str2mode(res);
+	    else if (resource_string_value(device_get_name(ch->dev),
+		device_get_unit(ch->dev), "mode", &res) == 0)
+		    mode = ata_str2mode(res);
+	    if (mode >= 0)
+		    atadev->mode = mode;
 	}
     }
     else {
@@ -1163,6 +1187,35 @@ ata_mode2str(int mode)
     }
 }
 
+int
+ata_str2mode(const char *str)
+{
+
+	if (!strcasecmp(str, "PIO0")) return (ATA_PIO0);
+	if (!strcasecmp(str, "PIO1")) return (ATA_PIO1);
+	if (!strcasecmp(str, "PIO2")) return (ATA_PIO2);
+	if (!strcasecmp(str, "PIO3")) return (ATA_PIO3);
+	if (!strcasecmp(str, "PIO4")) return (ATA_PIO4);
+	if (!strcasecmp(str, "WDMA0")) return (ATA_WDMA0);
+	if (!strcasecmp(str, "WDMA1")) return (ATA_WDMA1);
+	if (!strcasecmp(str, "WDMA2")) return (ATA_WDMA2);
+	if (!strcasecmp(str, "UDMA0")) return (ATA_UDMA0);
+	if (!strcasecmp(str, "UDMA16")) return (ATA_UDMA0);
+	if (!strcasecmp(str, "UDMA1")) return (ATA_UDMA1);
+	if (!strcasecmp(str, "UDMA25")) return (ATA_UDMA1);
+	if (!strcasecmp(str, "UDMA2")) return (ATA_UDMA2);
+	if (!strcasecmp(str, "UDMA33")) return (ATA_UDMA2);
+	if (!strcasecmp(str, "UDMA3")) return (ATA_UDMA3);
+	if (!strcasecmp(str, "UDMA44")) return (ATA_UDMA3);
+	if (!strcasecmp(str, "UDMA4")) return (ATA_UDMA4);
+	if (!strcasecmp(str, "UDMA66")) return (ATA_UDMA4);
+	if (!strcasecmp(str, "UDMA5")) return (ATA_UDMA5);
+	if (!strcasecmp(str, "UDMA100")) return (ATA_UDMA5);
+	if (!strcasecmp(str, "UDMA6")) return (ATA_UDMA6);
+	if (!strcasecmp(str, "UDMA133")) return (ATA_UDMA6);
+	return (-1);
+}
+
 const char *
 ata_satarev2str(int rev)
 {

Modified: stable/8/sys/dev/ata/ata-all.h
==============================================================================
--- stable/8/sys/dev/ata/ata-all.h	Fri Jul 16 09:10:11 2010	(r210163)
+++ stable/8/sys/dev/ata/ata-all.h	Fri Jul 16 09:12:47 2010	(r210164)
@@ -625,6 +625,7 @@ void ata_modify_if_48bit(struct ata_requ
 void ata_udelay(int interval);
 char *ata_unit2str(struct ata_device *atadev);
 const char *ata_mode2str(int mode);
+int ata_str2mode(const char *str);
 const char *ata_satarev2str(int rev);
 int ata_atapi(device_t dev, int target);
 int ata_pmode(struct ata_params *ap);


More information about the svn-src-all mailing list