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>