Subject: Re: CompactFlash
To: None <tech-kern@netbsd.org>
From: enami tsugutomo <enami@but-b.or.jp>
List: tech-kern
Date: 09/05/1998 07:19:29
Stefan Grefen <grefen@hprc.tandem.com> writes:

> wdc1 at pcmcia0 function 0 port 0x170-0x177 port 0x376-0x377

I'm using Sandisk's (actually CANON's product but probably OEM from
Sandisk) and Hagiwara SYS-COM's CompactFlash card to transfer data
from my digital camera, modifying wdc_pcmcia.c as the diffs appended
last of this mail.  Main difference is that they uses config entry of
single io space.  Also, Hagiwara SYS-COM's card was needed to map the
io space with width 16 while Sandisk card works with auto.  Sandisk
card is recognized as follows on my DEC HiNote UltraII.

pcic0 at isa0 port 0x3e0-0x3e1 iomem 0xd0000-0xd3fff: using irq 3
pcic0: controller 0 (Cirrus PD672X) has sockets A and B
pcmcia0 at pcic0 controller 0 socket 0
			:
		(ne0 is on pcmcia0)
			:
pcmcia1 at pcic0 controller 0 socket 1
pcmcia1: CIS version PCMCIA 2.0 or 2.1
pcmcia1: CIS info: SunDisk, SDP, 5/3 0.6
pcmcia1: Manufacturer code 0x45, product 0x401
pcmcia1: function 0: fixed disk, ccr addr 200 mask f
pcmcia1: function 0, config table entry 0: memory card; irq mask 0; memspace 0-7ff0; maxtwins 1; powerdown
pcmcia1: function 0, config table entry 1: I/O card; irq mask ffff; iomask 4, iospace 0-f; memspace 0-7ff0; maxtwins 1; powerdown
pcmcia1: function 0, config table entry 2: I/O card; irq mask 4000; iomask a, iospace 1f0-1f7 3f6-3f7; memspace 0-7ff0; maxtwins 1; powerdown
pcmcia1: function 0, config table entry 3: I/O card; irq mask 4000; iomask a, iospace 170-177 376-377; memspace 0-7ff0; maxtwins 1; powerdown
pcmcia1: function 0, config table entry 7: I/O card; irq mask 4000; iomask a, iospace 170-177 376-377; memspace 0-7ff0; maxtwins 1; powerdown
wdc1 at pcmcia1 function 0 port 0x330-0x33f
pcmcia1: card irq 9
atapibus1 at wdc1
wd1 at wdc1 drive 0: <SunDisk SDCFB-8>
wd1: using 1-sector 16-bit pio transfers, lba mode
wd1 7MB, 245 cyl, 2 head, 32 sec, 512 bytes/sect x 15680 sectors
apm0 at mainbus0: Power Management spec V1.1 (BIOS managing devices)
			:

enami.

(note: you need to regen pcmciadevs.h)
Index: wdc_pcmcia.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pcmcia/wdc_pcmcia.c,v
retrieving revision 1.8
diff -c -r1.8 wdc_pcmcia.c
*** wdc_pcmcia.c	1998/08/15 10:10:55	1.8
--- wdc_pcmcia.c	1998/09/04 23:06:29
***************
*** 59,69 ****
  #include <machine/bus.h>
  
  #include <dev/pcmcia/pcmciavar.h>
  #include <dev/isa/isavar.h>
  #include <dev/ic/wdcvar.h>
  
  #define WDC_PCMCIA_REG_NPORTS      8
! #define WDC_PCMCIA_AUXREG_OFFSET   0x206
  #define WDC_PCMCIA_AUXREG_NPORTS   2
  
  struct wdc_pcmcia_softc {
--- 59,71 ----
  #include <machine/bus.h>
  
  #include <dev/pcmcia/pcmciavar.h>
+ #include <dev/pcmcia/pcmciadevs.h>
+ 
  #include <dev/isa/isavar.h>
  #include <dev/ic/wdcvar.h>
  
  #define WDC_PCMCIA_REG_NPORTS      8
! #define WDC_PCMCIA_AUXREG_OFFSET   (WDC_PCMCIA_REG_NPORTS + 6)
  #define WDC_PCMCIA_AUXREG_NPORTS   2
  
  struct wdc_pcmcia_softc {
***************
*** 83,88 ****
--- 85,138 ----
  	sizeof(struct wdc_pcmcia_softc), wdc_pcmcia_match, wdc_pcmcia_attach
  };
  
+ struct wdc_pcmcia_product {
+ 	u_int32_t	wpp_vendor;	/* vendor ID */
+ 	u_int32_t	wpp_product;	/* product ID */
+ 	int		wpp_io_width;	/* io width. this is work around XXX */
+ 	const char	*wpp_cis_info;	/* XXX necessary? */
+ 	const char	*wpp_name;	/* product name */
+ } wdc_pcmcia_products[] = {
+ 
+ 	{ /* PCMCIA_VENDOR_DIGITAL XXX */ 0x0100,
+ 	  PCMCIA_PRODUCT_DIGITAL_MOBILE_MEDIA_CDROM,
+ 	  PCMCIA_WIDTH_AUTO, "Digital Mobile Media CD-ROM",
+ 	  PCMCIA_STR_DIGITAL_MOBILE_MEDIA_CDROM },
+ 
+ 	{ PCMCIA_VENDOR_HAGIWARASYSCOM,
+ 	  0,			/* XXX */
+ 	  PCMCIA_WIDTH_IO16, NULL, "Hagiwara SYS-COM ComactFlash Card" },
+ 
+ 	/* CANON FC-8M is also matches.  */
+ 	{ PCMCIA_VENDOR_SANDISK,
+ 	  PCMCIA_PRODUCT_SANDISK_SDCFB,
+ 	  PCMCIA_WIDTH_IO16 /* _AUTO also works */, NULL,
+ 	  PCMCIA_STR_SANDISK_SDCFB },
+ 
+ 	{ 0, 0, 0, NULL, NULL }
+ };
+ 
+ struct wdc_pcmcia_product *
+ 	wdc_pcmcia_lookup __P((struct pcmcia_attach_args *));
+ 
+ struct wdc_pcmcia_product *
+ wdc_pcmcia_lookup(pa)
+ 	struct pcmcia_attach_args *pa;
+ {
+ 	struct wdc_pcmcia_product *wpp;
+ 
+ 	for (wpp = wdc_pcmcia_products; wpp->wpp_name != NULL; wpp++)
+ 		if (pa->manufacturer == wpp->wpp_vendor &&
+ 		    (wpp->wpp_product == 0 ||
+ 			pa->product == wpp->wpp_product) &&
+ 		    (wpp->wpp_cis_info == NULL ||
+ 			(pa->card->cis1_info[1] != NULL &&
+ 			    strcmp(pa->card->cis1_info[1],
+ 				wpp->wpp_cis_info) == 0)))
+ 			return (wpp);
+ 
+ 	return (NULL);
+ }
+ 
  static int
  wdc_pcmcia_match(parent, match, aux)
  	struct device *parent;
***************
*** 91,104 ****
  {
  	struct pcmcia_attach_args *pa = aux;
  
! 	if (pa->card->manufacturer == 0x100 && pa->card->product == 0xd00) {
! 		if (pa->card->cis1_info[1] != NULL &&
! 		    strcmp(pa->card->cis1_info[1], "Digital Mobile Media CD-ROM") == 0)
! 			return 1;
! 	}
! 
  
! 	return 0;
  }
  
  static void
--- 141,150 ----
  {
  	struct pcmcia_attach_args *pa = aux;
  
! 	if (wdc_pcmcia_lookup(pa) != NULL)
! 		return (1);
  
! 	return (0);
  }
  
  static void
***************
*** 110,135 ****
  	struct wdc_pcmcia_softc *sc = (void *)self;
  	struct pcmcia_attach_args *pa = aux;
  	struct pcmcia_config_entry *cfe;
  
  	for (cfe = SIMPLEQ_FIRST(&pa->pf->cfe_head); cfe != NULL;
  	    cfe = SIMPLEQ_NEXT(cfe, cfe_list)) {
  		if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start,
! 		    cfe->iospace[0].length, 0, &sc->sc_pioh))
  			continue;
! 		if (cfe->num_iospace > 1) {
  			if (!pcmcia_io_alloc(pa->pf, cfe->iospace[1].start,
! 			    cfe->iospace[1].length, 0, &sc->sc_auxpioh)) {
  				break;
! 			}
! 		} else {
  			sc->sc_auxpioh.iot = sc->sc_pioh.iot;
! 			if (!bus_space_subregion(sc->sc_pioh.iot, sc->sc_pioh.ioh,
! 			    WDC_PCMCIA_REG_NPORTS,
! 			    cfe->iospace[0].length - WDC_PCMCIA_REG_NPORTS,
! 			    &sc->sc_auxpioh.ioh))
  				break;
  		}
! 		pcmcia_chip_io_free(pa->pf->sc->pct, pa->pf->sc->pch, &sc->sc_pioh);
  	}
  
  	if (cfe == NULL) {
--- 156,187 ----
  	struct wdc_pcmcia_softc *sc = (void *)self;
  	struct pcmcia_attach_args *pa = aux;
  	struct pcmcia_config_entry *cfe;
+ 	struct wdc_pcmcia_product *wpp;
  
  	for (cfe = SIMPLEQ_FIRST(&pa->pf->cfe_head); cfe != NULL;
  	    cfe = SIMPLEQ_NEXT(cfe, cfe_list)) {
+ 		if (cfe->num_iospace != 1 && cfe->num_iospace != 2)
+ 			continue;
+ 
  		if (pcmcia_io_alloc(pa->pf, cfe->iospace[0].start,
! 		    cfe->iospace[0].length,
! 		    cfe->iospace[0].start == 0 ? cfe->iospace[0].length : 0,
! 		    &sc->sc_pioh))
  			continue;
! 
! 		if (cfe->num_iospace == 2) {
  			if (!pcmcia_io_alloc(pa->pf, cfe->iospace[1].start,
! 			    cfe->iospace[1].length, 0, &sc->sc_auxpioh))
  				break;
! 		} else /* num_iospace == 1 */ {
  			sc->sc_auxpioh.iot = sc->sc_pioh.iot;
! 			if (!bus_space_subregion(sc->sc_pioh.iot,
! 			    sc->sc_pioh.ioh, WDC_PCMCIA_AUXREG_OFFSET,
! 			    WDC_PCMCIA_AUXREG_NPORTS, &sc->sc_auxpioh.ioh))
  				break;
  		}
! 		pcmcia_chip_io_free(pa->pf->sc->pct, pa->pf->sc->pch,
! 		    &sc->sc_pioh);
  	}
  
  	if (cfe == NULL) {
***************
*** 149,163 ****
  		return;
  	}
  
! 	if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, 0,
! 			  sc->sc_pioh.size, &sc->sc_pioh,
! 			  &sc->sc_iowindow)) {
  		printf(": can't map first I/O space\n");
  		return;
  	} 
! 	if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, 0,
! 			  sc->sc_auxpioh.size, &sc->sc_auxpioh,
! 			  &sc->sc_auxiowindow)) {
  		printf(": can't map second I/O space\n");
  		return;
  	}
--- 201,231 ----
  		return;
  	}
  
! 	/*
! 	 * XXX  DEC Mobile Media CDROM is not yet tested whether it works
! 	 * XXX  with PCMCIA_WIDTH_IO16.  HAGIWARA SYS-COM HPC-CF32 doesn't
! 	 * XXX  work with PCMCIA_WIDTH_AUTO.
! 	 * XXX  CANON FC-8M (SANDISK SDCFB 8M) works for both _AUTO and IO16.
! 	 * XXX  So, here is temporary work around.
! 	 */
! 	wpp = wdc_pcmcia_lookup(pa);
! 	if (wpp == NULL)
! 		panic("wdc_pcmcia_attach: impossible");
! 
! 	if (pcmcia_io_map(pa->pf, wpp->wpp_io_width, 0,
! 	    sc->sc_pioh.size, &sc->sc_pioh, &sc->sc_iowindow)) {
  		printf(": can't map first I/O space\n");
  		return;
  	} 
! 
! 	/*
! 	 * Currently, # of iospace is 1 except DIGITAL Mobile Media CD-ROM.
! 	 * So whether the work around like above is necessary or not
! 	 * is unknown.  XXX.
! 	 */
! 	if (cfe->num_iospace > 1 &&
! 	    pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, 0,
! 	    sc->sc_auxpioh.size, &sc->sc_auxpioh, &sc->sc_auxiowindow)) {
  		printf(": can't map second I/O space\n");
  		return;
  	}
Index: pcmciadevs
===================================================================
RCS file: /cvsroot/src/sys/dev/pcmcia/pcmciadevs,v
retrieving revision 1.13
diff -c -r1.13 pcmciadevs
*** pcmciadevs	1998/08/17 23:10:12	1.13
--- pcmciadevs	1998/09/04 23:06:29
***************
*** 35,40 ****
--- 35,41 ----
   * List of known PCMCIA vendors
   */
  
+ vendor SANDISK			0x0045	Sandisk Corporation
  vendor NEWMEDIA			0x0057	NewMedia Corporation
  vendor IBM			0x00a4	IBM Corporation
  vendor MOTOROLA			0x0109	Motorola Corporation
***************
*** 50,55 ****
--- 51,57 ----
  vendor SIMPLETECH		0x014d	Simple Technology
  vendor DAYNA			0x0194	Dayna Corporation
  vendor IODATA			0x01bf	I-O DATA
+ vendor HAGIWARASYSCOM		0xc012	Hagiwara SYS-COM
  
  /*
   * List of known products.  Grouped by vendor.
***************
*** 66,71 ****
--- 68,76 ----
  /* Dayna Products */
  product DAYNA COMMUNICARD_E	0x002d Dayna CommuniCard E
  
+ /* DIGITAL Products */
+ product DIGITAL MOBILE_MEDIA_CDROM 0x0d00 Digital Mobile Media CD-ROM
+ 
  /* Motorola Products */
  product MOTOROLA POWER144	0x0105 Motorola Power 14.4 Modem
  product MOTOROLA PM100C		0x0302 Motorola Personal Messenger 100C CDPD Modem
***************
*** 88,93 ****
--- 93,101 ----
  
  /* US Robotics Products */
  product USROBOTICS WORLDPORT144	0x3330 US Robotics WorldPort 14.4 Modem
+ 
+ /* Sandisk Products */
+ product SANDISK SDCFB		0x0401 Sandisk CompactFlash Card
  
  /* Simple Technology Products */
  product SIMPLETECH COMMUNICATOR288 0x0100 Simple Technology 28.8 Communicator