kern/104318: Promise SATA PDC4xxxx cards -- port numbering problem

Rich Wales richw at richw.org
Wed Oct 11 20:30:26 PDT 2006


>Number:         104318
>Category:       kern
>Synopsis:       Promise SATA PDC4xxxx cards -- port numbering problem
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Oct 12 03:30:09 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Rich Wales
>Release:        6.1-RELEASE-p10
>Organization:
>Environment:
FreeBSD tapeworm.richw.org 6.1-RELEASE-p10 FreeBSD 6.1-RELEASE-p10 #8: Tue Oct 10 18:37:52 PDT 2006     richw at tapeworm.richw.org:/usr/obj/usr/src/sys/WHODUNIT  i386
>Description:
On the newer 4-port Promise non-RAID SATA cards (with PDC4xxxx-series chips), the enumeration of the ports is jumbled.  The port labelled as "Port 1" on the card, for example, is being recognized as if it were port 4.

This problem has been noted with Linux systems as well; see this page, for instance:  http://www.thisishull.net/printthread.php?t=150545

>How-To-Repeat:

>Fix:
The accompanying patch rearranges the unit numbers so the enumeration of the ports will correspond to the physical labelling on the card.  This code assumes that ata_promise_mio_allocate() will only be called once for each device.

Patch attached with submission follows:

--- sys/dev/ata/ata-chipset.c.orig	Thu Mar 16 13:28:51 2006
+++ sys/dev/ata/ata-chipset.c	Tue Oct 10 00:14:16 2006
@@ -3332,6 +3332,11 @@
     return 0;
 }
 
+/*
+ * translation map for port enumeration on PDC4xxxx-series controllers
+ */
+static int pdc4_port_map[4] = {3, 1, 0, 2};
+
 static int
 ata_promise_mio_allocate(device_t dev)
 {
@@ -3339,6 +3344,15 @@
     struct ata_channel *ch = device_get_softc(dev);
     int offset = (ctlr->chip->cfg2 & PRSX4X) ? 0x000c0000 : 0;
     int i;
+
+    /*
+     * port enumeration on PDC4xxxx-series controllers
+     * doesn't correspond to labelling on the card;
+     * rearrange unit numbers to make them correspond
+     */
+    if ((ctlr->chip->cfg2 & PRSATA2)
+	&& ch->unit >= 0 && ch->unit <= 3)
+    	ch->unit = pdc4_port_map[ch->unit];
  
     for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
 	ch->r_io[i].res = ctlr->r_res2;

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list