Subject: kern/32501: ch_ndrive abuse in wdc.
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <christos@zoulas.com>
List: netbsd-bugs
Date: 01/11/2006 22:30:00
>Number:         32501
>Category:       kern
>Synopsis:       ch_ndrive abuse in wdc.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jan 11 22:30:00 +0000 2006
>Originator:     Christos Zoulas
>Release:        NetBSD 3.99.11
>Organization:
	Smart Plants, Inc.
>Environment:
System: NetBSD rebar.astron.com 3.99.11 NetBSD 3.99.11 (ASTRON) #33: Thu Nov 17 12:02:40 EST 2005 christos@rebar.astron.com:/usr/src/sys/arch/i386/compile/ASTRON i386
Architecture: i386
Machine: i386
>Description:
	I have a sandisk memory card that presents itself as a wdc and
	only has one drive. I want to be able to tell wdc to only probe
	that drive and not create a phantom second one.
>How-To-Repeat:
>Fix:
	- Initialize ch_ndrive in the callers of wdcattach.
	- Change hard-coded instances of 2 to ch_ndrive.
	- make wdc_pcmcia.c set ndrive properly for at least this device.

Index: arch/acorn32/eb7500atx/rside.c
===================================================================
RCS file: /cvsroot/src/sys/arch/acorn32/eb7500atx/rside.c,v
retrieving revision 1.7
diff -u -u -r1.7 rside.c
--- arch/acorn32/eb7500atx/rside.c	11 Dec 2005 12:16:05 -0000	1.7
+++ arch/acorn32/eb7500atx/rside.c	11 Jan 2006 22:16:33 -0000
@@ -200,6 +200,7 @@
 		cp->ch_channel = channel;
 		cp->ch_atac = &sc->sc_wdcdev.sc_atac;
 		cp->ch_queue = &scp->rc_chqueue;
+		cp->ch_ndrive = 2;
 		wdr->cmd_iot = wdr->ctl_iot = &sc->sc_tag;
 		if (bus_space_map(wdr->cmd_iot,
 		    rside_info[channel].drive_registers,
Index: arch/acorn32/mainbus/wdc_pioc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/acorn32/mainbus/wdc_pioc.c,v
retrieving revision 1.20
diff -u -u -r1.20 wdc_pioc.c
--- arch/acorn32/mainbus/wdc_pioc.c	11 Dec 2005 12:16:05 -0000	1.20
+++ arch/acorn32/mainbus/wdc_pioc.c	11 Jan 2006 22:16:33 -0000
@@ -190,6 +190,7 @@
 	sc->sc_wdcdev.sc_atac.atac_nchannels = 1;
 	sc->sc_channel.ch_channel = 0;
 	sc->sc_channel.ch_queue = &sc->sc_chqueue;
+	sc->sc_channel.ch_ndrive = 2;
 
 	wdc_init_shadow_regs(&sc->sc_channel);
 
Index: arch/acorn32/podulebus/icside.c
===================================================================
RCS file: /cvsroot/src/sys/arch/acorn32/podulebus/icside.c,v
retrieving revision 1.24
diff -u -u -r1.24 icside.c
--- arch/acorn32/podulebus/icside.c	11 Dec 2005 12:16:05 -0000	1.24
+++ arch/acorn32/podulebus/icside.c	11 Jan 2006 22:16:33 -0000
@@ -269,6 +269,7 @@
 		cp->ch_channel = channel;
 		cp->ch_atac = &sc->sc_wdcdev.sc_atac;
 		cp->ch_queue = &icp->ic_chqueue;
+		cp->ch_ndrive = 2;
 		wdr->cmd_iot = &sc->sc_tag;
 		wdr->ctl_iot = &sc->sc_tag;
 		if (ide->modspace)
Index: arch/acorn32/podulebus/rapide.c
===================================================================
RCS file: /cvsroot/src/sys/arch/acorn32/podulebus/rapide.c,v
retrieving revision 1.23
diff -u -u -r1.23 rapide.c
--- arch/acorn32/podulebus/rapide.c	11 Dec 2005 12:16:05 -0000	1.23
+++ arch/acorn32/podulebus/rapide.c	11 Jan 2006 22:16:33 -0000
@@ -263,6 +263,7 @@
 		cp->ch_channel = channel;
 		cp->ch_atac = &sc->sc_wdcdev.sc_atac;
 		cp->ch_queue = &rcp->rc_chqueue;
+		cp->ch_ndrive = 2;
 		wdr->cmd_iot = iot;
 		wdr->ctl_iot = iot;
 		wdr->data32iot = iot;
Index: arch/acorn32/podulebus/simide.c
===================================================================
RCS file: /cvsroot/src/sys/arch/acorn32/podulebus/simide.c,v
retrieving revision 1.22
diff -u -u -r1.22 simide.c
--- arch/acorn32/podulebus/simide.c	11 Dec 2005 12:16:05 -0000	1.22
+++ arch/acorn32/podulebus/simide.c	11 Jan 2006 22:16:33 -0000
@@ -261,6 +261,7 @@
 		cp->ch_channel = channel;
 		cp->ch_atac = &sc->sc_wdcdev.sc_atac;
 		cp->ch_queue = &scp->sc_chqueue;
+		cp->ch_ndrive = 2;
 		wdr->cmd_iot = wdr->ctl_iot = &sc->sc_tag;
 		iobase = pa->pa_podule->mod_base;
 		if (bus_space_map(wdr->cmd_iot, iobase +
Index: arch/amiga/dev/wdc_amiga.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/dev/wdc_amiga.c,v
retrieving revision 1.26
diff -u -u -r1.26 wdc_amiga.c
--- arch/amiga/dev/wdc_amiga.c	11 Dec 2005 12:16:28 -0000	1.26
+++ arch/amiga/dev/wdc_amiga.c	11 Jan 2006 22:16:33 -0000
@@ -147,6 +147,7 @@
 	sc->sc_channel.ch_channel = 0;
 	sc->sc_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	sc->sc_channel.ch_queue = &sc->sc_chqueue;
+	sc->sc_channel.ch_ndrive = 2;
 
 	wdc_init_shadow_regs(&sc->sc_channel);
 
Index: arch/atari/dev/wdc_mb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/atari/dev/wdc_mb.c,v
retrieving revision 1.26
diff -u -u -r1.26 wdc_mb.c
--- arch/atari/dev/wdc_mb.c	11 Dec 2005 12:16:54 -0000	1.26
+++ arch/atari/dev/wdc_mb.c	11 Jan 2006 22:16:33 -0000
@@ -218,6 +218,7 @@
 	sc->sc_channel.ch_channel = 0;
 	sc->sc_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	sc->sc_channel.ch_queue = &sc->sc_chqueue;
+	sc->sc_channel.ch_ndrive = 2;
 
 	/*
 	 * Setup & enable disk related interrupts.
Index: arch/evbarm/iq31244/wdc_obio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/iq31244/wdc_obio.c,v
retrieving revision 1.2
diff -u -u -r1.2 wdc_obio.c
--- arch/evbarm/iq31244/wdc_obio.c	11 Dec 2005 12:17:09 -0000	1.2
+++ arch/evbarm/iq31244/wdc_obio.c	11 Jan 2006 22:16:33 -0000
@@ -118,6 +118,7 @@
 	sc->ata_channel.ch_channel = 0;
 	sc->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	sc->ata_channel.ch_queue = &sc->wdc_chqueue;
+	sc->ata_channel.ch_ndrive = 2;
 	wdc_init_shadow_regs(&sc->ata_channel);
 
 	printf("\n");
Index: arch/evbarm/tsarm/wdc_ts.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/tsarm/wdc_ts.c,v
retrieving revision 1.2
diff -u -u -r1.2 wdc_ts.c
--- arch/evbarm/tsarm/wdc_ts.c	11 Dec 2005 12:17:11 -0000	1.2
+++ arch/evbarm/tsarm/wdc_ts.c	11 Jan 2006 22:16:33 -0000
@@ -116,6 +116,7 @@
 	sc->ata_channel.ch_channel = 0;
 	sc->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	sc->ata_channel.ch_queue = &sc->wdc_chqueue;
+	sc->ata_channel.ch_ndrive = 2;
 	wdc_init_shadow_regs(&sc->ata_channel);
 
 	printf("\n");
Index: arch/i386/pnpbios/pciide_pnpbios.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/pnpbios/pciide_pnpbios.c,v
retrieving revision 1.20
diff -u -u -r1.20 pciide_pnpbios.c
--- arch/i386/pnpbios/pciide_pnpbios.c	11 Dec 2005 12:17:47 -0000	1.20
+++ arch/i386/pnpbios/pciide_pnpbios.c	11 Jan 2006 22:16:34 -0000
@@ -140,6 +140,7 @@
 	cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	cp->ata_channel.ch_queue = malloc(sizeof(struct ata_queue),
 					  M_DEVBUF, M_NOWAIT);
+	cp->ata_channel.ch_ndrive = 2;
 	if (cp->ata_channel.ch_queue == NULL) {
 		printf("%s: unable to allocate memory for command queue\n",
 			self->dv_xname);
Index: arch/mac68k/obio/wdc_obio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/obio/wdc_obio.c,v
retrieving revision 1.19
diff -u -u -r1.19 wdc_obio.c
--- arch/mac68k/obio/wdc_obio.c	11 Dec 2005 12:18:03 -0000	1.19
+++ arch/mac68k/obio/wdc_obio.c	11 Jan 2006 22:16:34 -0000
@@ -228,6 +228,7 @@
 	chp->ch_channel = 0;
 	chp->ch_atac = &sc->sc_wdcdev.sc_atac;
 	chp->ch_queue = &sc->sc_chqueue;
+	chp->ch_ndrive = 2;
 
 	printf("\n");
 
Index: arch/macppc/dev/kauai.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/kauai.c,v
retrieving revision 1.18
diff -u -u -r1.18 kauai.c
--- arch/macppc/dev/kauai.c	11 Dec 2005 12:18:03 -0000	1.18
+++ arch/macppc/dev/kauai.c	11 Jan 2006 22:16:34 -0000
@@ -194,6 +194,7 @@
 	chp->ch_channel = 0;
 	chp->ch_atac = &sc->sc_wdcdev.sc_atac;
 	chp->ch_queue = &sc->sc_queue;
+	chp->ch_ndrive = 2;
 	wdc_init_shadow_regs(chp);
 
 	wdcattach(chp);
Index: arch/macppc/dev/wdc_obio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/wdc_obio.c,v
retrieving revision 1.42
diff -u -u -r1.42 wdc_obio.c
--- arch/macppc/dev/wdc_obio.c	11 Dec 2005 12:18:03 -0000	1.42
+++ arch/macppc/dev/wdc_obio.c	11 Jan 2006 22:16:34 -0000
@@ -220,6 +220,7 @@
 	chp->ch_channel = 0;
 	chp->ch_atac = &sc->sc_wdcdev.sc_atac;
 	chp->ch_queue = &sc->sc_chqueue;
+	chp->ch_ndrive = 2;
 
 	wdc_init_shadow_regs(chp);
 
Index: arch/playstation2/dev/wdc_spd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/playstation2/dev/wdc_spd.c,v
retrieving revision 1.21
diff -u -u -r1.21 wdc_spd.c
--- arch/playstation2/dev/wdc_spd.c	24 Dec 2005 23:24:01 -0000	1.21
+++ arch/playstation2/dev/wdc_spd.c	11 Jan 2006 22:16:34 -0000
@@ -218,6 +218,7 @@
 	ch->ch_channel = 0;
 	ch->ch_atac = &sc->sc_wdcdev.sc_atac;
 	ch->ch_queue = &sc->sc_chqueue;
+	ch->ch_ndrive = 2;
 
 	__wdc_spd_bus_space(ch);
 
Index: arch/prep/dev/wdc_obio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/prep/dev/wdc_obio.c,v
retrieving revision 1.21
diff -u -u -r1.21 wdc_obio.c
--- arch/prep/dev/wdc_obio.c	11 Dec 2005 12:18:47 -0000	1.21
+++ arch/prep/dev/wdc_obio.c	11 Jan 2006 22:16:34 -0000
@@ -170,6 +170,7 @@
 	sc->sc_channel.ch_channel = 0;
 	sc->sc_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	sc->sc_channel.ch_queue = &sc->sc_chqueue;
+	sc->sc_channel.ch_ndrive = 2;
 
 	wdcattach(&sc->sc_channel);
 }
Index: dev/ic/wdc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdc.c,v
retrieving revision 1.231
diff -u -u -r1.231 wdc.c
--- dev/ic/wdc.c	16 Nov 2005 23:39:08 -0000	1.231
+++ dev/ic/wdc.c	11 Jan 2006 22:16:35 -0000
@@ -223,7 +223,7 @@
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
 	struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
 	u_int8_t st0 = 0, st1 = 0;
-	int i, error, s;
+	int i, j, error, s;
 
 	if (wdcprobe1(chp, 0) == 0) {
 		/* No drives, abort the attach here. */
@@ -275,7 +275,7 @@
 	/* Wait a bit, some devices are weird just after a reset. */
 	delay(5000);
 
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < chp->ch_ndrive; i++) {
 		/* XXX This should be done by other code. */
 		chp->ch_drive[i].chnl_softc = chp;
 		chp->ch_drive[i].drive = i;
@@ -321,9 +321,8 @@
 		if (error == CMD_OK) {
 			/* If IDENTIFY succeeded, this is not an OLD ctrl */
 			s = splbio();
-			/* XXXJRT ch_ndrive */
-			chp->ch_drive[0].drive_flags &= ~DRIVE_OLD;
-			chp->ch_drive[1].drive_flags &= ~DRIVE_OLD;
+			for (j = 0; j < chp->ch_ndrive; j++)
+				chp->ch_drive[j].drive_flags &= ~DRIVE_OLD;
 			splx(s);
 		} else {
 			s = splbio();
@@ -383,11 +382,9 @@
 				splx(s);
 			} else {
 				s = splbio();
-				/* XXXJRT ch_ndrive */
-				chp->ch_drive[0].drive_flags &=
-				    ~(DRIVE_ATA | DRIVE_ATAPI);
-				chp->ch_drive[1].drive_flags &=
-				    ~(DRIVE_ATA | DRIVE_ATAPI);
+				for (j = 0; j < chp->ch_ndrive; j++)
+					chp->ch_drive[j].drive_flags &=
+					    ~(DRIVE_ATA | DRIVE_ATAPI);
 				splx(s);
 			}
 		}
@@ -638,7 +635,7 @@
 	 * be something here assume it's ATA or OLD.  Ghost will be killed
 	 * later in attach routine.
 	 */
-	for (drive = 0; drive < 2; drive++) {
+	for (drive = 0; drive < chp->ch_ndrive; drive++) {
 		if ((ret_value & (0x01 << drive)) == 0)
 			continue;
 		if (wdc->select)
@@ -683,11 +680,7 @@
 	struct atac_softc *atac = chp->ch_atac;
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
 
-	/*
-	 * Start out assuming 2 drives.  This may change as we probe
-	 * drives.
-	 */
-	chp->ch_ndrive = 2;
+	KASSERT(chp->ch_ndrive > 0 && chp->ch_ndrive < 3);
 
 	/* default data transfer methods */
 	if (wdc->datain_pio == NULL)
Index: dev/ic/wdc_upc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdc_upc.c,v
retrieving revision 1.21
diff -u -u -r1.21 wdc_upc.c
--- dev/ic/wdc_upc.c	11 Dec 2005 12:21:29 -0000	1.21
+++ dev/ic/wdc_upc.c	11 Jan 2006 22:16:35 -0000
@@ -90,6 +90,7 @@
 	sc->sc_channel.ch_channel = 0;
 	sc->sc_channel.ch_atac = &sc->sc_wdc.sc_atac;
 	sc->sc_channel.ch_queue = &sc->sc_chqueue;
+	sc->sc_channel.ch_ndrive = 2;
 	for (i = 0; i < WDC_NREG; i++) {
 		if (bus_space_subregion(ua->ua_iot, ua->ua_ioh, i,
 		    i == 0 ? 4 : 1, &wdr->cmd_iohs[i]) != 0) {
Index: dev/isa/wdc_isa.c
===================================================================
RCS file: /cvsroot/src/sys/dev/isa/wdc_isa.c,v
retrieving revision 1.47
diff -u -u -r1.47 wdc_isa.c
--- dev/isa/wdc_isa.c	11 Dec 2005 12:22:03 -0000	1.47
+++ dev/isa/wdc_isa.c	11 Jan 2006 22:16:35 -0000
@@ -213,6 +213,7 @@
 	sc->ata_channel.ch_channel = 0;
 	sc->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	sc->ata_channel.ch_queue = &sc->wdc_chqueue;
+	sc->ata_channel.ch_ndrive = 2;
 	wdc_init_shadow_regs(&sc->ata_channel);
 
 	printf("\n");
Index: dev/isapnp/wdc_isapnp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/isapnp/wdc_isapnp.c,v
retrieving revision 1.32
diff -u -u -r1.32 wdc_isapnp.c
--- dev/isapnp/wdc_isapnp.c	11 Dec 2005 12:22:16 -0000	1.32
+++ dev/isapnp/wdc_isapnp.c	11 Jan 2006 22:16:35 -0000
@@ -165,6 +165,7 @@
 	sc->ata_channel.ch_channel = 0;
 	sc->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	sc->ata_channel.ch_queue = &sc->wdc_chqueue;
+	sc->ata_channel.ch_ndrive = 2;
 
 	wdc_init_shadow_regs(&sc->ata_channel);
 
Index: dev/ofisa/wdc_ofisa.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ofisa/wdc_ofisa.c,v
retrieving revision 1.26
diff -u -u -r1.26 wdc_ofisa.c
--- dev/ofisa/wdc_ofisa.c	11 Dec 2005 12:22:48 -0000	1.26
+++ dev/ofisa/wdc_ofisa.c	11 Jan 2006 22:16:35 -0000
@@ -160,6 +160,7 @@
 	sc->sc_channel.ch_channel = 0;
 	sc->sc_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	sc->sc_channel.ch_queue = &sc->sc_chqueue;
+	sc->sc_channel.ch_ndrive = 2;
 
 	wdc_init_shadow_regs(&sc->sc_channel);
 
Index: dev/pci/artsata.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/artsata.c,v
retrieving revision 1.8
diff -u -u -r1.8 artsata.c
--- dev/pci/artsata.c	11 Dec 2005 12:22:48 -0000	1.8
+++ dev/pci/artsata.c	11 Jan 2006 22:16:35 -0000
@@ -301,6 +301,7 @@
 	cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	cp->ata_channel.ch_queue =
 	    malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT);
+	cp->ata_channel.ch_ndrive = 2;
 	if (cp->ata_channel.ch_queue == NULL) {
 		aprint_error("%s %s channel: "
 		    "can't allocate memory for command queue",
Index: dev/pci/cypide.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/cypide.c,v
retrieving revision 1.16
diff -u -u -r1.16 cypide.c
--- dev/pci/cypide.c	11 Dec 2005 12:22:49 -0000	1.16
+++ dev/pci/cypide.c	11 Jan 2006 22:16:35 -0000
@@ -155,6 +155,7 @@
 	cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	cp->ata_channel.ch_queue =
 	    malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT);
+	cp->ata_channel.ch_ndrive = 2;
 	if (cp->ata_channel.ch_queue == NULL) {
 		aprint_error("%s primary channel: "
 		    "can't allocate memory for command queue",
Index: dev/pci/hptide.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/hptide.c,v
retrieving revision 1.19
diff -u -u -r1.19 hptide.c
--- dev/pci/hptide.c	11 Dec 2005 12:22:49 -0000	1.19
+++ dev/pci/hptide.c	11 Jan 2006 22:16:35 -0000
@@ -333,7 +333,7 @@
 	}
 
 	/* Per drive settings */
-	for (drive = 0; drive < 2; drive++) {
+	for (drive = 0; drive < chp->ch_ndrive; drive++) {
 		drvp = &chp->ch_drive[drive];
 		/* If no drive, skip */
 		if ((drvp->drive_flags & DRIVE) == 0)
Index: dev/pci/pdcsata.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pdcsata.c,v
retrieving revision 1.4
diff -u -u -r1.4 pdcsata.c
--- dev/pci/pdcsata.c	4 Dec 2005 17:39:03 -0000	1.4
+++ dev/pci/pdcsata.c	11 Jan 2006 22:16:35 -0000
@@ -285,6 +285,7 @@
 		cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 		cp->ata_channel.ch_queue =
 		    malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT);
+		cp->ata_channel.ch_ndrive = 2;
 		if (cp->ata_channel.ch_queue == NULL) {
 			aprint_error("%s channel %d: "
 			    "can't allocate memory for command queue\n",
Index: dev/pci/satalink.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/satalink.c,v
retrieving revision 1.27
diff -u -u -r1.27 satalink.c
--- dev/pci/satalink.c	24 Dec 2005 20:27:42 -0000	1.27
+++ dev/pci/satalink.c	11 Jan 2006 22:16:35 -0000
@@ -594,6 +594,7 @@
 	cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	cp->ata_channel.ch_queue =
 	    malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT);
+	cp->ata_channel.ch_ndrive = 2;
 	if (cp->ata_channel.ch_queue == NULL) {
 		aprint_error("%s %s channel: "
 		    "can't allocate memory for command queue",
Index: dev/pcmcia/wdc_pcmcia.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pcmcia/wdc_pcmcia.c,v
retrieving revision 1.102
diff -u -u -r1.102 wdc_pcmcia.c
--- dev/pcmcia/wdc_pcmcia.c	11 Jan 2006 13:34:33 -0000	1.102
+++ dev/pcmcia/wdc_pcmcia.c	11 Jan 2006 22:16:35 -0000
@@ -98,66 +98,69 @@
 CFATTACH_DECL(wdc_pcmcia, sizeof(struct wdc_pcmcia_softc),
     wdc_pcmcia_match, wdc_pcmcia_attach, wdc_pcmcia_detach, wdcactivate);
 
-static const struct pcmcia_product wdc_pcmcia_products[] = {
-	{ PCMCIA_VENDOR_DIGITAL,
+static const struct wdc_pcmcia_product {
+	struct pcmcia_product wdc_product;
+	int wdc_ndrive;
+} wdc_pcmcia_products[] = {
+	{ { PCMCIA_VENDOR_DIGITAL,
 	  PCMCIA_PRODUCT_DIGITAL_MOBILE_MEDIA_CDROM,
-	  {NULL, "Digital Mobile Media CD-ROM", NULL, NULL} },
+	  {NULL, "Digital Mobile Media CD-ROM", NULL, NULL} }, 2 },
 
-	{ PCMCIA_VENDOR_IBM,
+	{ { PCMCIA_VENDOR_IBM,
 	  PCMCIA_PRODUCT_IBM_PORTABLE_CDROM,
-	  {NULL, "PCMCIA Portable CD-ROM Drive", NULL, NULL} },
+	  {NULL, "PCMCIA Portable CD-ROM Drive", NULL, NULL} }, 2 },
 
 	/* The TEAC IDE/Card II is used on the Sony Vaio */
-	{ PCMCIA_VENDOR_TEAC,
+	{ { PCMCIA_VENDOR_TEAC,
 	  PCMCIA_PRODUCT_TEAC_IDECARDII,
-	  PCMCIA_CIS_TEAC_IDECARDII },
+	  PCMCIA_CIS_TEAC_IDECARDII }, 2 },
 
 	/*
 	 * A fujitsu rebranded panasonic drive that reports
 	 * itself as function "scsi", disk interface 0
 	 */
-	{ PCMCIA_VENDOR_PANASONIC,
+	{ { PCMCIA_VENDOR_PANASONIC,
 	  PCMCIA_PRODUCT_PANASONIC_KXLC005,
-	  PCMCIA_CIS_PANASONIC_KXLC005 },
+	  PCMCIA_CIS_PANASONIC_KXLC005 }, 2 },
 
-	{ PCMCIA_VENDOR_SANDISK,
+	{ { PCMCIA_VENDOR_SANDISK,
 	  PCMCIA_PRODUCT_SANDISK_SDCFB,
-	  PCMCIA_CIS_SANDISK_SDCFB },
+	  PCMCIA_CIS_SANDISK_SDCFB }, 1 },
 
 	/*
 	 * EXP IDE/ATAPI DVD Card use with some DVD players.
 	 * Does not have a vendor ID or product ID.
 	 */
-	{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
-	  PCMCIA_CIS_EXP_EXPMULTIMEDIA },
+	{ { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
+	  PCMCIA_CIS_EXP_EXPMULTIMEDIA }, 2 },
 
 	/* Mobile Dock 2, neither vendor ID nor product ID */
-	{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
-	  {"SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", NULL, NULL} },
+	{ { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
+	  {"SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", NULL, NULL} }, 2 },
 
 	/* Toshiba Portege 3110 CD, neither vendor ID nor product ID */
-	{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
-	  {"FREECOM", "PCCARD-IDE", NULL, NULL} },
+	{ { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
+	  {"FREECOM", "PCCARD-IDE", NULL, NULL} }, 2 },
 
 	/* Random CD-ROM, (badged AMACOM), neither vendor ID nor product ID */
-	{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
-	  {"PCMCIA", "CD-ROM", NULL, NULL} },
+	{ { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
+	  {"PCMCIA", "CD-ROM", NULL, NULL} }, 2 },
 
 	/* IO DATA CBIDE2, with neither vendor ID nor product ID */
-	{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
-	  PCMCIA_CIS_IODATA_CBIDE2 },
+	{ { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
+	  PCMCIA_CIS_IODATA_CBIDE2 }, 2 },
 
 	/* TOSHIBA PA2673U(IODATA_CBIDE2 OEM), */
 	/*  with neither vendor ID nor product ID */
-	{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
-	  PCMCIA_CIS_TOSHIBA_CBIDE2 },
+	{ { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
+	  PCMCIA_CIS_TOSHIBA_CBIDE2 }, 2 },
 
 	/*
 	 * Novac PCMCIA-IDE Card for HD530P IDE Box,
 	 * with neither vendor ID nor product ID
 	 */
-	{ PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
-	  {"PCMCIA", "PnPIDE", NULL, NULL} },
+	{ { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
+	  {"PCMCIA", "PnPIDE", NULL, NULL} }, 2 },
 };
 static const size_t wdc_pcmcia_nproducts =
     sizeof(wdc_pcmcia_products) / sizeof(wdc_pcmcia_products[0]);
@@ -210,6 +213,7 @@
 	struct pcmcia_attach_args *pa = aux;
 	struct pcmcia_config_entry *cfe;
 	struct wdc_regs *wdr;
+	const struct wdc_pcmcia_product *wdcp;
 	bus_size_t offset;
 	int i;
 	int error;
@@ -295,6 +299,9 @@
 	sc->ata_channel.ch_channel = 0;
 	sc->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
 	sc->ata_channel.ch_queue = &sc->wdc_chqueue;
+	wdcp = pcmcia_product_lookup(pa, wdc_pcmcia_products,
+	    wdc_pcmcia_nproducts, sizeof(wdc_pcmcia_products[0]), NULL);
+	sc->ata_channel.ch_ndrive = wdcp->wdc_ndrive;
 	wdc_init_shadow_regs(&sc->ata_channel);
 
 	error = wdc_pcmcia_enable(self, 1);
Index: dev/podulebus/dtide.c
===================================================================
RCS file: /cvsroot/src/sys/dev/podulebus/dtide.c,v
retrieving revision 1.20
diff -u -u -r1.20 dtide.c
--- dev/podulebus/dtide.c	11 Dec 2005 12:23:28 -0000	1.20
+++ dev/podulebus/dtide.c	11 Jan 2006 22:16:35 -0000
@@ -107,6 +107,7 @@
 		wdr->cmd_iot = bst;
 		wdr->ctl_iot = bst;
 		ch->ch_queue = &sc->sc_chq[i];
+		ch->ch_ndrive = 2;
 		bus_space_map(pa->pa_fast_t,
 		    pa->pa_fast_base + dtide_cmdoffsets[i], 0, 8,
 		    &wdr->cmd_baseioh);
Index: dev/podulebus/hcide.c
===================================================================
RCS file: /cvsroot/src/sys/dev/podulebus/hcide.c,v
retrieving revision 1.17
diff -u -u -r1.17 hcide.c
--- dev/podulebus/hcide.c	11 Dec 2005 12:23:28 -0000	1.17
+++ dev/podulebus/hcide.c	11 Jan 2006 22:16:35 -0000
@@ -102,6 +102,7 @@
 		wdr->cmd_iot = pa->pa_mod_t;
 		wdr->ctl_iot = pa->pa_mod_t;
 		ch->ch_queue = &sc->sc_chq[i];
+		ch->ch_ndrive = 2;
 		bus_space_map(pa->pa_fast_t,
 		    pa->pa_fast_base + hcide_cmdoffsets[i], 0, 8,
 		    &wdr->cmd_baseioh);