Date: Mon, 06 Apr 1998 17:16:53 +0000 From: Gianmarco Giovannelli <gmarco@giovannelli.it> To: mobile@FreeBSD.ORG Subject: Flash ATA/PC-card ATAPI support for -current Message-ID: <35290E05.BAEFD7E6@giovannelli.it> References: <35135766.1026387F@giovannelli.it>
next in thread | previous in thread | raw e-mail | index | archive | help
When will be the ATA/PC card drivers committed ?
A friends of mine report they works quite well (using the following
patches).
Instead I have a some problems with today -current :
.cc -c -O -Wreturn-type -Wcomment -Wredundant-decls -Wimplicit
-Wnested-externs
-Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline
-Wuninitializ
ed -nostdinc -I- -I. -I../.. -I../../../include -DKERNEL -include
opt_global.h
../../i386/isa/wd.c
In file included from ../../i386/isa/wd.c:298:
../../pccard/slot.h:40: redefinition of `struct slot_ctrl'
../../pccard/slot.h:78: redefinition of `struct pccard_device'
../../pccard/slot.h:96: redefinition of `struct pccard_devinfo'
../../pccard/slot.h:112: redefinition of `struct slot'
./../pccard/slot.h:141: redeclaration of `enum card_event'
../../pccard/slot.h:141: conflicting types for `card_removed'
../../pccard/slot.h:141: previous declaration of `card_removed'
../../pccard/slot.h:141: warning: redundant redeclaration of
`card_removed' in s
ame scope
../../pccard/slot.h:141: warning: previous declaration of `card_removed'
../../pccard/slot.h:141: conflicting types for `card_inserted'
../../pccard/slot.h:141: previous declaration of `card_inserted'
../../pccard/slot.h:141: warning: redundant redeclaration of
`card_inserted' in
same scope
../../pccard/slot.h:141: warning: previous declaration of
`card_inserted'
../../pccard/slot.h:143: warning: redundant redeclaration of
`pccard_alloc_slot'
in same scope
../../pccard/slot.h:143: warning: previous declaration of
`pccard_alloc_slot'
../../pccard/slot.h:144: warning: redundant redeclaration of
`pccard_event' in s
ame scope
../../pccard/slot.h:144: warning: previous declaration of `pccard_event'
../../pccard/slot.h:145: warning: redundant redeclaration of
`pccard_remove_cont
roller' in same scope
../../pccard/slot.h:145: warning: previous declaration of
`pccard_remove_control
ler'
../../i386/isa/wd.c:302: warning: redundant redeclaration of `card_intr'
in same
scope
../../i386/isa/wd.c:272: warning: previous declaration of `card_intr'
../../i386/isa/wd.c:303: warning: redundant redeclaration of `wdunload'
in same
scope
../../i386/isa/wd.c:273: warning: previous declaration of `wdunload'
../../i386/isa/wd.c:304: warning: redundant redeclaration of `wdinit' in
same sc
ope
../../i386/isa/wd.c:274: warning: previous declaration of `wdinit'
../../i386/isa/wd.c:305: warning: redundant redeclaration of
`wdprobe_pccard' in
same scope
../../i386/isa/wd.c:275: warning: previous declaration of
`wdprobe_pccard'
../../i386/isa/wd.c:307: redefinition of `wdinfo'
../../i386/isa/wd.c:277: `wdinfo' previously defined here
../../i386/isa/wd.c:317: redefinition of
`__set_pccarddrv_set_sym_wdinfo'
../../i386/isa/wd.c:287: `__set_pccarddrv_set_sym_wdinfo' previously
defined her
e
../../i386/isa/wd.c:319: redefinition of `static_init'
../../i386/isa/wd.c:289: `static_init' previously defined here
../../i386/isa/wd.c:320: redefinition of `lunit_in_use'
../../i386/isa/wd.c:290: `lunit_in_use' previously defined here
../../i386/isa/wd.c:321: redefinition of `ctrlr_in_use'
../../i386/isa/wd.c:291: `ctrlr_in_use' previously defined here
../../i386/isa/wd.c:429: redefinition of `wdinit'
../../i386/isa/wd.c:332: `wdinit' previously defined here
../../i386/isa/wd.c:477: redefinition of `wdunload'
../../i386/isa/wd.c:380: `wdunload' previously defined here
../../i386/isa/wd.c:505: redefinition of `card_intr'
../../i386/isa/wd.c:408: `card_intr' previously defined here
../../i386/isa/wd.c:512: redefinition of `wdprobe_pccard'
../../i386/isa/wd.c:415: `wdprobe_pccard' previously defined here
*** Error code 1
Patches :
> This is Flash ATA/PC-card ATAPI support for today's -current. Please
> test it.
>
> *CAUTION* This works on my laptop (Toshiba Libretto US version), but
> it will not work on machines that have secondary IDE interface.
>
> FYI: Sample pccard.conf entries.
>
> # IO Data PCIDE-II (Generic ATAPI interface for CD-ROM, HDD, and MO)
> card "IO DATA" "PCIDEII"
> config 0x22 "wdc1" 10
>
> # Hagiwara Sys-com HPC-CFT32 (Compact Flash 32MB)
> card "HAGIWARA" "HPC-CFT32"
> config 0x3 "wdc1" 10
>
> --
> HOSOKAWA, Tatsumi
> Network Technology Center
> Keio University
> hosokawa@ntc.keio.ac.jp
>
> Index: pccardd/cardd.c
> ===================================================================
> RCS file: /home/ncvs/src/usr.sbin/pccard/pccardd/cardd.c,v
> retrieving revision 1.30
> diff -c -r1.30 cardd.c
> *** cardd.c 1998/03/09 05:18:50 1.30
> --- cardd.c 1998/03/20 07:42:44
> ***************
> *** 189,194 ****
> --- 189,195 ----
> if (sp->cis)
> freecis(sp->cis);
> if (sp->config) {
> + logmsg("sp->config->inuse = 0;\n");
> sp->config->inuse = 0;
> sp->config->driver->inuse = 0;
> }
> ***************
> *** 404,409 ****
> --- 405,412 ----
> bzero(&sp->io, sizeof(sp->io));
> if (cisconf->iospace || (defconf && defconf->iospace)) {
> struct cis_config *cp;
> + int n_iowin = sp->card_config->io_blks;
> + int free_ioaddr;
>
> cp = cisconf;
> if (!cisconf->iospace)
> ***************
> *** 412,440 ****
> * If # of I/O lines decoded == 10, then card does its
> * own decoding.
> *
> * If an I/O block exists, then use it.
> * If no address (but a length) is available, allocate
> * from the pool.
> */
> ! if (cp->io) {
> ! sp->io.addr = cp->io->addr;
> ! sp->io.size = cp->io->size;
> ! } else
> /*
> * No I/O block, assume the address lines
> * decode gives the size.
> */
> sp->io.size = 1 << cp->io_addr;
> !
> ! if (sp->io.addr == 0) {
> ! int i = bit_fns(io_avail, IOPORTS, sp->io.size);
> !
> ! if (i < 0)
> return (-1);
> ! sp->io.addr = i;
> }
> - bit_nclear(io_avail, sp->io.addr,
> - sp->io.addr + sp->io.size - 1);
>
> /* Set up the size to take into account the decode lines. */
> sp->io.cardaddr = cp->io_addr;
> --- 415,465 ----
> * If # of I/O lines decoded == 10, then card does its
> * own decoding.
> *
> + * If two I/O blocks exist, then use them.
> * If an I/O block exists, then use it.
> * If no address (but a length) is available, allocate
> * from the pool.
> */
> ! switch (n_iowin) {
> ! case 0:
> /*
> * No I/O block, assume the address lines
> * decode gives the size.
> */
> sp->io.size = 1 << cp->io_addr;
> ! free_ioaddr = bit_fns(io_avail, IOPORTS, sp->io.size);
> ! if (free_ioaddr < 0)
> return (-1);
> ! sp->io.addr = free_ioaddr;
> ! bit_nclear(io_avail, sp->io.addr,
> ! sp->io.addr + sp->io.size - 1);
> ! break;
> ! case 1:
> ! sp->io.addr = cp->io->addr;
> ! sp->io.size = cp->io->size;
> ! bit_nclear(io_avail, sp->io.addr,
> ! sp->io.addr + sp->io.size - 1);
> ! break;
> ! case 2:
> ! sp->io.next = xmalloc(sizeof(struct allocblk));
> ! bzero(sp->io.next, sizeof(struct allocblk));
> ! sp->io.addr = cp->io->addr;
> ! sp->io.size = cp->io->size;
> ! bit_nclear(io_avail, sp->io.addr,
> ! sp->io.addr + sp->io.size - 1);
> ! if (cp->io->next) {
> ! sp->io.next->addr = cp->io->next->addr;
> ! sp->io.next->size = cp->io->next->size;
> ! bit_nclear(io_avail,
> ! sp->io.next->addr,
> ! sp->io.next->addr + sp->io.next->size - 1);
> ! }
> ! break;
> ! default:
> ! /* There's no PC card controller that has more
> ! * than two I/O windows */
> ! return (-1);
> }
>
> /* Set up the size to take into account the decode lines. */
> sp->io.cardaddr = cp->io_addr;
> ***************
> *** 451,456 ****
> --- 476,483 ----
> sp->io.flags = IODF_WS | IODF_CS16 | IODF_16BIT;
> break;
> }
> + if (sp->io.next)
> + sp->io.next->flags = sp->io.flags;
> #ifdef DEBUG
> logmsg("Using I/O addr 0x%x, size %d\n",
> sp->io.addr, sp->io.size);
> ***************
> *** 471,476 ****
> --- 498,504 ----
> struct io_desc io;
> struct dev_desc drv;
> struct driver *drvp = sp->config->driver;
> + struct allocblk *ab;
> char c;
> off_t offs;
> int rw_flags;
> ***************
> *** 523,549 ****
> return (0);
> }
> }
> ! io.window = 0;
> ! if (sp->io.size) {
> ! io.flags = sp->io.flags;
> ! io.start = sp->io.addr;
> ! io.size = sp->io.size;
> ! #if 0
> ! io.start = sp->io.addr & ~((1 << sp->io.cardaddr) - 1);
> ! io.size = 1 << sp->io.cardaddr;
> ! if (io.start < 0x100) {
> ! io.start = 0x100;
> ! io.size = 0x300;
> ! }
> ! #endif
> #ifdef DEBUG
> ! logmsg("Assigning I/O window %d, start 0x%x, size 0x%x flags 0x%x\n",
> ! io.window, io.start, io.size, io.flags);
> #endif
> ! io.flags |= IODF_ACTIVE;
> ! if (ioctl(sp->fd, PIOCSIO, &io)) {
> ! logerr("ioctl (PIOCSIO)");
> ! return (0);
> }
> }
> strcpy(drv.name, drvp->kernel);
> --- 551,570 ----
> return (0);
> }
> }
> ! for (io.window = 0, ab = &sp->io; ab; io.window++, ab = ab->next) {
> ! if (ab->size) {
> ! io.flags = ab->flags;
> ! io.start = ab->addr;
> ! io.size = ab->size;
> #ifdef DEBUG
> ! logmsg("Assigning I/O window %d, start 0x%x, size 0x%x flags 0x%x\n",
> ! io.window, io.start, io.size, io.flags);
> #endif
> ! io.flags |= IODF_ACTIVE;
> ! if (ioctl(sp->fd, PIOCSIO, &io)) {
> ! logerr("ioctl (PIOCSIO)");
> ! return (0);
> ! }
> }
> }
> strcpy(drv.name, drvp->kernel);
> Index: i386/isa/wd.c
> ===================================================================
> RCS file: /home/ncvs/src/sys/i386/isa/wd.c,v
> retrieving revision 1.151
> diff -c -r1.151 wd.c
> *** wd.c 1998/02/16 23:57:41 1.151
> --- wd.c 1998/03/20 07:41:39
> ***************
> *** 260,265 ****
> --- 260,392 ----
> static int eide_quirks;
> #endif
>
> + #include "card.h"
> + #if NCARD > 0
> + #include <sys/select.h>
> + #include <pccard/cardinfo.h>
> + #include <pccard/driver.h>
> + #include <pccard/slot.h>
> + /*
> + * PC-Card (PCMCIA) specific code.
> + */
> + static int card_intr(struct pccard_devinfo *); /* Interrupt handler */
> + static void wdunload(struct pccard_devinfo *); /* Disable driver */
> + static int wdinit(struct pccard_devinfo *); /* Init. driver */
> + static int wdprobe_pccard(struct isa_device *); /* Probe PC-card */
> +
> + static struct pccard_device wdinfo =
> + {
> + "wdc",
> + wdinit,
> + wdunload,
> + card_intr,
> + 0, /* Attributes - presently unused */
> + &bio_imask /* Interrupt mask for device */
> + };
> +
> + DATA_SET(pccarddrv_set, wdinfo);
> +
> + static int static_init = 1;
> + static int lunit_in_use = 0;
> + static int ctrlr_in_use = 0;
> +
> +
> + /*
> + * Initialize the device - called from Slot manager.
> + * if first is set, then initially check for
> + * the device's existence before initialising it.
> + * Once initialised, the device table may be set up.
> + */
> + static int
> + wdinit(struct pccard_devinfo *dp)
> + {
> + /*
> + * dynamic configuration mode
> + */
> + static_init = 0;
> + /*
> + * validate unit number.
> + */
> + if (dp->isahd.id_unit >= NWDC)
> + return(ENODEV);
> + /*
> + * Probe the device. If a value is returned, the
> + * device was found at the location.
> + */
> +
> + if (wdprobe_pccard(&dp->isahd)==0) {
> + if (bootverbose)
> + printf("Probe Failed\n");
> + return(ENXIO);
> + }
> + if (wdattach(&dp->isahd)==0) {
> + if (bootverbose)
> + printf("Attach Failed\n");
> + return(ENXIO);
> + }
> +
> + ctrlr_in_use |= (1 << dp->isahd.id_unit);
> + /*
> + * XXX TODO:
> + * If it was already inited before, the device structure
> + * should be already initialised. Here we should
> + * reset (and possibly restart) the hardware, but
> + * I am not sure of the best way to do this...
> + */
> + return(0);
> + }
> +
> + /*
> + * wdunload - unload the driver and clear the table.
> + * XXX TODO:
> + * This is called usually when the card is ejected, but
> + * can be caused by the modunload of a controller driver.
> + * The idea is reset the driver's view of the device
> + * and ensure that any driver entry points such as
> + * read and write do not hang.
> + */
> + static void
> + wdunload(struct pccard_devinfo *dp)
> + {
> + int ctrlr = dp->isahd.id_unit;
> + int lunit;
> +
> + for (lunit = 0; lunit < NWD; lunit++) {
> + if ((lunit_in_use & (1<<lunit)) && wddrives[lunit] &&
> + wddrives[lunit]->dk_ctrlr == ctrlr &&
> + wddrives[lunit]->dk_port == dp->isahd.id_iobase ) {
> + lunit_in_use &= ~(1<<lunit);
> + break;
> + }
> + }
> + ctrlr_in_use &= ~(1 << ctrlr);
> + if (bootverbose) {
> + printf("wdc%d: unloading -- ", ctrlr);
> + if (wdtab[ctrlr].b_active != 0)
> + printf("damage!\n");
> + else
> + printf("done\n");
> + }
> + }
> +
> + /*
> + * card_intr - Shared interrupt called from
> + * front end of PC-Card handler.
> + */
> + static int
> + card_intr(struct pccard_devinfo *dp)
> + {
> + wdintr(dp->isahd.id_unit);
> + return(1);
> + }
> +
> + static int
> + wdprobe_pccard(struct isa_device *isa_dev)
> + {
> + return wdprobe(isa_dev);
> + }
> + #endif /* NCARD > 0 */
> +
>
> /*
> * Here we use the pci-subsystem to find out, whether there is
> ***************
> *** 288,293 ****
> --- 415,429 ----
> if (unit >= NWDC)
> return (0);
>
> + #if NCARD > 0
> + /*
> + * If PC-Card probe required, then register driver with
> + * slot manager.
> + */
> + if (!static_init && (ctrlr_in_use & (1 << unit)))
> + return (0);
> + #endif /* NCARD > 0 */
> +
> du = malloc(sizeof *du, M_TEMP, M_NOWAIT);
> if (du == NULL)
> return (0);
> ***************
> *** 387,393 ****
> goto nodevice;
> }
>
> -
> free(du, M_TEMP);
> return (IO_WDCSIZE);
>
> --- 523,528 ----
> ***************
> *** 409,414 ****
> --- 544,554 ----
> struct isa_device *wdup;
> struct disk *du;
> struct wdparams *wp;
> + #if NCARD > 0
> + static int once_registered = 0;
> + static int old_dkunit[NWD];
> + int valid_units = 0;
> + #endif /* NCARD > 0 */
>
> if (dvp->id_unit >= NWDC)
> return (0);
> ***************
> *** 430,445 ****
> --- 570,604 ----
> if (wdup->id_iobase != dvp->id_iobase)
> continue;
> lunit = wdup->id_unit;
> +
> + #if NCARD > 0
> + if (lunit_in_use & (1 << lunit)) {
> + if (static_init)
> + panic("drive attached twice");
> + else
> + continue;
> + }
> + #endif /* NCARD > 0 */
> +
> if (lunit >= NWD)
> continue;
>
> unit = wdup->id_physid;
>
> + #if NCARD > 0
> + du = wddrives[lunit];
> + if (du == NULL)
> + du = malloc(sizeof *du, M_TEMP, M_NOWAIT);
> + if (du == NULL)
> + continue;
> + #else /* NCARD > 0 */
> du = malloc(sizeof *du, M_TEMP, M_NOWAIT);
> if (du == NULL)
> continue;
> if (wddrives[lunit] != NULL)
> panic("drive attached twice");
> + #endif /* NCARD > 0 */
> +
> wddrives[lunit] = du;
> bufq_init(&drive_queue[lunit]);
> bzero(du, sizeof *du);
> ***************
> *** 512,517 ****
> --- 671,687 ----
> * XXX timeout should be per controller.
> */
> wdtimeout(du);
> + #if NCARD > 0
> + lunit_in_use |= (1 << lunit);
> + valid_units++;
> + /* do not register twice */
> + if (once_registered & (1 << lunit)) {
> + /* reuse previous dk_dkunit */
> + du->dk_dkunit = old_dkunit[lunit];
> + goto reuse_it;
> + }
> + once_registered |= (1 << lunit);
> + #endif /* NCARD > 0 */
>
> #ifdef DEVFS
> mynor = dkmakeminor(lunit, WHOLE_DISK_SLICE, RAW_PART);
> ***************
> *** 534,543 ****
> --- 704,724 ----
> * according to iostat.
> */
> dk_wpms[dk_ndrive] = 4 * 1024 * 1024 / 2;
> + #if NCARD > 0
> + old_dkunit[lunit] = du->dk_dkunit = dk_ndrive++;
> + #else /* NCARD > 0 */
> du->dk_dkunit = dk_ndrive++;
> + #endif /* NCARD > 0 */
> } else {
> + #if NCARD > 0
> + old_dkunit[lunit] = du->dk_dkunit = -1;
> + #else /* NCARD > 0 */
> du->dk_dkunit = -1;
> + #endif /* NCARD > 0 */
> }
> + #if NCARD > 0
> + reuse_it:
> + #endif /* NCARD > 0 */
> } else {
> free(du, M_TEMP);
> wddrives[lunit] = NULL;
> ***************
> *** 548,567 ****
> * Probe all free IDE units, searching for ATAPI drives.
> */
> for (unit=0; unit<2; ++unit) {
> for (lunit=0; lunit<NWD; ++lunit)
> if (wddrives[lunit] &&
> wddrives[lunit]->dk_ctrlr == dvp->id_unit &&
> wddrives[lunit]->dk_unit == unit)
> goto next;
> #ifdef CMD640
> if (atapi_attach (dvp->id_unit, unit, dvp->id_iobase))
> atapictrlr = dvp->id_unit;
> ! #else
> atapi_attach (dvp->id_unit, unit, dvp->id_iobase);
> ! #endif
> next: ;
> }
> ! #endif
> /*
> * Discard any interrupts generated by wdgetctlr(). wdflushirq()
> * doesn't work now because the ambient ipl is too high.
> --- 729,768 ----
> * Probe all free IDE units, searching for ATAPI drives.
> */
> for (unit=0; unit<2; ++unit) {
> + #if NCARD > 0
> + for (lunit=0; lunit<NWD; ++lunit)
> + if ((lunit_in_use & (1<<lunit)) && wddrives[lunit] &&
> + wddrives[lunit]->dk_ctrlr == dvp->id_unit &&
> + wddrives[lunit]->dk_unit == unit)
> + goto next;
> + #else /* NCARD > 0 */
> for (lunit=0; lunit<NWD; ++lunit)
> if (wddrives[lunit] &&
> wddrives[lunit]->dk_ctrlr == dvp->id_unit &&
> wddrives[lunit]->dk_unit == unit)
> goto next;
> + #endif /* NCARD > 0 */
> #ifdef CMD640
> + #if NCARD > 0
> + if (atapi_attach (dvp->id_unit, unit, dvp->id_iobase)) {
> + atapictrlr = dvp->id_unit;
> + valid_units++;
> + }
> + #else /* NCARD > 0 */
> if (atapi_attach (dvp->id_unit, unit, dvp->id_iobase))
> atapictrlr = dvp->id_unit;
> ! #endif /* NCARD > 0 */
> ! #else /* CMD640 */
> ! #if NCARD > 0
> ! if (atapi_attach (dvp->id_unit, unit, dvp->id_iobase))
> ! valid_units++;
> ! #else /* NCARD > 0 */
> atapi_attach (dvp->id_unit, unit, dvp->id_iobase);
> ! #endif /* NCARD > 0 */
> ! #endif /* CMD640 */
> next: ;
> }
> ! #endif /* ATAPI */
> /*
> * Discard any interrupts generated by wdgetctlr(). wdflushirq()
> * doesn't work now because the ambient ipl is too high.
> ***************
> *** 572,580 ****
> } else {
> wdtab[dvp->id_unit].b_active = 2;
> }
> ! #else
> wdtab[dvp->id_unit].b_active = 2;
> ! #endif
>
> return (1);
> }
> --- 773,786 ----
> } else {
> wdtab[dvp->id_unit].b_active = 2;
> }
> ! #else /* CMD640 */
> wdtab[dvp->id_unit].b_active = 2;
> ! #endif /* CMD640 */
> !
> ! #if NCARD > 0
> ! if (!static_init && valid_units == 0)
> ! return (0); /* no valid unit found */
> ! #endif /* NCARD > 0 */
>
> return (1);
> }
> ***************
> *** 1287,1292 ****
> --- 1493,1503 ----
> lunit = dkunit(dev);
> if (lunit >= NWD || dktype(dev) != 0)
> return (ENXIO);
> + #if NCARD > 0
> + if ((lunit_in_use & (1<<lunit)) == 0)
> + return (ENXIO);
> + #endif /* NCARD > 0 */
> +
> du = wddrives[lunit];
> if (du == NULL)
> return (ENXIO);
> ***************
> *** 2025,2030 ****
> --- 2236,2244 ----
> lunit = dkunit(dev); /* eventually support floppies? */
> part = dkpart(dev);
> if (lunit >= NWD || (du = wddrives[lunit]) == NULL
> + #if NCARD > 0
> + || (lunit_in_use & (1 << lunit)) == 0
> + #endif /* NCARD > 0 */
> || du->dk_state < OPEN
> || (lp = dsgetlabel(dev, du->dk_slices)) == NULL)
> return (ENXIO);
--
Regards...
Gianmarco
"Unix expert since yesterday"
http://www.giovannelli.it
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-mobile" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?35290E05.BAEFD7E6>
