hi eric,
I'd love to test your patch but somehow the patch doesn't apply cleanly!
all hunks failed!
did you make this patch against the initial driver from linuxnet.com or
against a version already patched??
regards
andre
ps the second version of the patch against 2.6.16 contains your
suggested changes, sorry for not mention that!
Eric Piel wrote:
> 06/20/2006 11:56 PM, Andre Puschmann wrote/a écrit:
>> hey,
>> sorry but the patch isn't working so far ..
>> probably there is still some crap in there .. it was just a quick hack!
>> somehow i am not sure how they really changed the pcmcia-subsystem from
>> 2.6.15 to 2.6.16 to 2.6.17 .. but i am working on it :-)
>>
>> the attached patch is for 2.6.17 against the original driver from
>> linuxnet.com ..
>>
>> can anybody please test, what "lspcmcia" shows when the module is
>> loaded?!
>> my output looks like this:
>>
>> <log>
>> Socket 0 Bridge: [yenta_cardbus] (bus ID: 0000:02:01.0)
>> Socket 1 Bridge: [yenta_cardbus] (bus ID: 0000:02:01.1)
>> Socket 1 Device 0: [-- no driver --] (bus ID: 1.0)
>> </log>
>>
>>
> I've taken Andre's patch (actually, it was the first version) and
> modified some more stuff. It's against the original version (but text
> recoded to unix format) and compiles for 2.6.17. It seems to be working
> a little bit, the driver loads fine and pcscd seems happy to communicate
> with it (from the log). You can compile with "make debug=1" to see more
> things in dmesg.
>
> You still have to create manually the device node (with
> "smartcardreader_conf start" for instance) but I'll try to create a udev
> rule for easiness...
>
> Now I've got to find a smartcard to test the driver... I don't dear
> using my credit card nor my GSM card to debug it ;-) Does anyone know if
> a French telephone card is supposed to work?
>
> Can anyone try this driver version with some "known to work hardware"?
>
> See you,
> Eric
>
>
> ------------------------------------------------------------------------
>
> --- OZSCR_2.0.3_Kern_2.6/src/ozscrlx-2.6.13/ozscrlx.c 2006-06-17
> 10:31:09.000000000 +0200
> +++ OZSCR_2.0.3_Kern_2.6.17/src/ozscrlx-2.6.13/ozscrlx.c 2006-06-20
> 00:21:36.000000000 +0200
> @@ -135,7 +135,7 @@ static NTSTATUS CmdDeactivate( PREADER_E
> static NTSTATUS CBTransmit( PREADER_EXTENSION pRdrExt );
>
> /* Parameters that can be set with 'insmod' */
> -static char rcs_id[] = "O2Micro SmartCardBus Reader for kernel 2.6 (above
> 2.6.13)";
> +static char rcs_id[] = "O2Micro SmartCardBus Reader for kernel 2.6 (above
> 2.6.17)";
> static char *version = rcs_id;
> static unsigned int ozscr_major = OZSCR_MAJOR;
>
> @@ -150,17 +150,17 @@ static u_long irq_mask = 0xffff;
> * and ejection events. They are invoked from the OZSCR event
> * handler.
> */
> -static int ozscr_event(event_t event,int priority, event_callback_args_t
> *args);
> -static void ozscr_config(dev_link_t *link);
> -static void ozscr_release(u_long arg);
> +//static int ozscr_event(event_t event,int priority, event_callback_args_t
> *args);
> +static int ozscr_config(struct pcmcia_device *p_dev);
> +static void ozscr_release(struct pcmcia_device *p_dev);
>
> /*
> * The attach() and detach() entry points are used to create and destroy
> * "instances" of the driver, where each instance represents everything
> * needed to manage one actual PCMCIA card.
> */
> -static dev_link_t* ozscr_attach(void);
> -static void ozscr_detach(dev_link_t *);
> +static int ozscr_attach(struct pcmcia_device *p_dev);
> +static void ozscr_detach(struct pcmcia_device *p_dev);
>
> /*
> * Prototypes of card access functions(File Operations)
> @@ -178,9 +178,9 @@ static dev_info_t dev_info = "ozscrlx_cs
> /*
> * A linked list of "instances" of the OZSCR device. Each actual
> * PCMCIA card corresponds to one device instance, and is described
> - * by one dev_link_t structure (defined in ds.h).
> + * by one pcmcia_device structure (defined in ds.h).
> */
> -static dev_link_t *dev_list = NULL;
> +static struct pcmcia_device *dev_list = NULL;
>
> /*
> * Private data for OZSCR reader. Need to provide a dev_node_t
> @@ -197,19 +197,28 @@ typedef struct ozscr_dev_t {
> } ozscr_drv_t;
>
>
> +static struct pcmcia_device_id ozscrlx_ids[] = {
> + PCMCIA_DEVICE_PROD_ID123("O2Micro", "SmartCardBus Reader", "V1.0",
> 0x97299583, 0xB8501BA9, 0xE611E659),
> + PCMCIA_DEVICE_NULL
> +};
> +MODULE_DEVICE_TABLE(pcmcia, ozscrlx_ids);
> +
> static struct pcmcia_driver ozscrlx_driver = {
> - .owner =THIS_MODULE,
> - .drv ={
> - .name ="ozscrlx_cs",
> + .owner = THIS_MODULE,
> + .drv = {
> + .name = "ozscrlx_cs",
> },
> - .attach =ozscr_attach,
> - .event =ozscr_event,
> - .detach =ozscr_detach,
> + .id_table = ozscrlx_ids,
> + .probe = ozscr_attach,
> + .remove = ozscr_detach,
> + // nothing special for the two next methods
> +// .suspend = ozscr_suspend,
> +// .resume = ozscr_resume,
> };
>
> /* Parameters that can be set with "insmod" */
> -static int mem_speed = 0; /* in ns */
> -MODULE_PARM(mem_speed, "i");
> +static int mem_speed; /* in ns */
> +module_param(mem_speed, int, 0400);
> static UCHAR ct; /*Contact current value*/
> static PPSCR_REGISTERS sync_IOBase;
> static PUCHAR sync_membase;
> @@ -221,26 +230,15 @@ static READER_EXTENSION ozscr_reader;
> */
> static irqreturn_t ozscr_interrupt(int irq, void *dev_id, struct pt_regs
> *regs)
> {
> - dev_link_t *link;
> - struct ozscr_dev_t *dev;
> - u_char ack;
> + struct ozscr_dev_t *dev = (struct ozscr_dev_t *)dev_id;
> + u_char ack;
>
> #ifdef PCMCIA_DEBUG
> printk(KERN_INFO "OZSCRLX: interrupt\n");
> #endif
> -
> - /* Find device that caused the interrupt.*/
> - for (link = dev_list; link; link = link->next)
> - {
> - dev = (struct ozscr_dev_t *)link->priv;
> - if (dev && dev->irq == irq)
> - break;
> - }
> -
> - if (!DEV_OK(link))
> - return IRQ_NONE;
> -
> - dev = (struct ozscr_dev_t *)link->priv;
> + // not needed anymore ?
> + // if (!DEV_OK(link))
> + // return IRQ_NONE;
>
> /* Acknowledge interrupt to reader.*/
> ack = inb(dev->io_base);
> @@ -258,27 +256,25 @@ static int ozscr_open(struct inode *inod
> #undef FUNC_NAME
> #define FUNC_NAME "ozscr_open: "
>
> - int minor = MINOR(inode->i_rdev);
> - dev_link_t *link;
> - struct ozscr_dev_t *dev;
> + int minor = iminor(inode);
> + struct pcmcia_device *p_dev;
>
> #ifdef PCMCIA_DEBUG
> printk(KERN_INFO MODULE_NAME FUNC_NAME "minor(%d)\n", minor);
> #endif
> + // XXX
> + p_dev = dev_list;
> + // for (p_dev = dev_list; p_dev; p_dev = p_dev->next)
> + // if (p_dev->dev && p_dev->dev->minor == minor)
> + // break;
>
> - for (link = dev_list; link; link = link->next)
> - if (link->dev && link->dev->minor == minor)
> - break;
> -
> - if (!DEV_OK(link))
> + if (!pcmcia_dev_present(p_dev))
> return (-ENODEV);
>
> - dev = (struct ozscr_dev_t *)link->priv;
> -
> /* Only one process may use the reader*/
> - if (link->open > 0)
> + if (p_dev->open > 0)
> return (-EBUSY);
> - ++link->open;
> + ++p_dev->open;
> return 0;
> }
>
> @@ -292,29 +288,28 @@ static int ozscr_close(struct inode *ino
>
> #define FUNC_NAME "ozscr_close: "
>
> - int minor = MINOR(inode->i_rdev);
> - dev_link_t *link;
> - struct ozscr_dev_t *dev;
> + int minor = iminor(inode);
> + struct pcmcia_device *p_dev;
> + struct ozscr_dev_t *dev;
>
> #ifdef PCMCIA_DEBUG
> printk(KERN_INFO MODULE_NAME FUNC_NAME "minor(%d)\n", minor);
> #endif
>
> - for (link = dev_list; link; link = link->next)
> - if (link->dev && link->dev->minor == minor)
> - break;
> -
> - if (!DEV_OK(link))
> - return 0;
> + // XXX
> + p_dev = dev_list;
> + //for (p_dev = dev_list; p_dev; p_dev = p_dev->next)
> + // if (p_dev->dev && p_dev->dev->minor == minor)
> + // break;
>
> - dev = (struct ozscr_dev_t *)link->priv;
> + if (!pcmcia_dev_present(p_dev))
> + return (-ENODEV);
>
> /* Make device available again, regardless of errors during close.*/
> - --(link->open);
> + --(p_dev->open);
>
> - /* If card was removed clean up*/
> - if (link->state & DEV_STALE_CONFIG)
> - ozscr_release((u_long)link);
> + /* clean up*/
> + ozscr_release(p_dev);
>
> return 0;
> }
> @@ -338,26 +333,27 @@ ozscr_ioctl(struct inode *inode, struct
> #undef FUNC_NAME
> #define FUNC_NAME "ozscr_ioctl: "
>
> - int minor = MINOR(inode->i_rdev);
> - dev_link_t *link;
> + int minor = iminor(inode);
> + struct pcmcia_device *p_dev;
> struct ozscr_dev_t *dev;
> int ret = 0; /* return value */
> u_int size; /* size for data transfers */
> ULONG ATRLength;
> - UCHAR ATRBuffer[ ATR_SIZE ]; /* TLVList[16]; */
> + UCHAR ATRBuffer[ATR_SIZE]; /* TLVList[16]; */
> PREADER_EXTENSION pRdrExt = &ozscr_reader;
>
> struct ozscr_apdu apdu;
>
> - for (link = dev_list; link!=NULL; link = link->next)
> - if ((link->dev != NULL) && (link->dev->minor == minor))
> - break;
> - if (!DEV_OK(link))
> - {
> - return -ENODEV;
> - }
> + // XXX
> + p_dev = dev_list;
> + //for (p_dev = dev_list; p_dev!=NULL; p_dev = p_dev->next)
> + // if ((p_dev->dev != NULL) && (p_dev->dev->minor == minor))
> + // break;
>
> - dev = (struct ozscr_dev_t *)link->priv;
> + if (!pcmcia_dev_present(p_dev))
> + return (-ENODEV);
> +
> + dev = (struct ozscr_dev_t *)p_dev->priv;
> size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
> if (cmd & IOC_IN)
> if (!access_ok(VERIFY_READ, (char *)arg, size))
> @@ -508,11 +504,11 @@ ozscr_ioctl(struct inode *inode, struct
>
>
> /*
> - * Card service configruation
> + * Card service configuration
> * Helper function to get a tuple, get it's data and parse it.
> */
> static int
> -get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
> +get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
> {
> int i;
>
> @@ -536,17 +532,16 @@ get_tuple(client_handle_t handle, tuple_
>
>
> /*
> - * ozscrconfig() is scheduled to run after a CARD_INSERTION event
> + * ozscr_config() is scheduled to run after at the end of an attach event
> * is received, to configure the PCMCIA socket, and to make the
> * device available to the system.
> */
> -static void ozscr_config(dev_link_t *link)
> +static int ozscr_config(struct pcmcia_device *p_dev)
> {
> #undef FUNC_NAME
> #define FUNC_NAME "ozscr_config: "
>
> - client_handle_t handle = link->handle;
> - struct ozscr_dev_t *dev = link->priv;
> + struct ozscr_dev_t *dev = p_dev->priv;
> tuple_t tuple;
> cisparse_t parse;
> cistpl_cftable_entry_t *cf = &parse.cftable_entry;
> @@ -555,9 +550,6 @@ static void ozscr_config(dev_link_t *lin
> win_req_t req;
> memreq_t mem;
>
> -#ifdef PCMCIA_DEBUG
> - printk(KERN_INFO MODULE_NAME FUNC_NAME "Device Link(0x%p)\n", link);
> -#endif
>
> /* This reads the card's CONFIG tuple to find its configuration
> registers. */
> tuple.Attributes = 0;
> @@ -570,16 +562,14 @@ static void ozscr_config(dev_link_t *lin
> printk(KERN_INFO MODULE_NAME FUNC_NAME "get tuple\n");
> #endif
>
> - if((i = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS)
> + if ((i = pcmcia_get_first_tuple(p_dev, &tuple)) != CS_SUCCESS)
> {
> - cs_error(link->handle, ParseTuple, i);
> - link->state &= ~DEV_CONFIG_PENDING;
> + cs_error(p_dev, ParseTuple, i);
> goto error_return;
> }
> - if((i = get_tuple(handle, &tuple, &parse)) != CS_SUCCESS)
> + if ((i = get_tuple(p_dev, &tuple, &parse)) != CS_SUCCESS)
> {
> - cs_error(link->handle, ParseTuple, i);
> - link->state &= ~DEV_CONFIG_PENDING;
> + cs_error(p_dev, ParseTuple, i);
> goto error_return;
> }
>
> @@ -587,16 +577,15 @@ static void ozscr_config(dev_link_t *lin
> printk(KERN_INFO MODULE_NAME FUNC_NAME "GetFirstTuple Complete\n");
> #endif
>
> - link->conf.ConfigBase = parse.config.base;
> - link->conf.Present = parse.config.rmask[0];
> + p_dev->conf.ConfigBase = parse.config.base;
> + p_dev->conf.Present = parse.config.rmask[0];
>
> /* Configure card Find I/O port for the card.*/
> - link->state |= DEV_CONFIG;
> tuple.TupleOffset = 0;
> tuple.Attributes = 0;
>
> - tuple.TupleData = buf;
> - tuple.TupleDataMax = OZSCR_BUFSZ - 1;
> + tuple.TupleData = buf;
> + tuple.TupleDataMax = OZSCR_BUFSZ - 1;
>
> tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
>
> @@ -604,61 +593,54 @@ static void ozscr_config(dev_link_t *lin
> printk(KERN_INFO MODULE_NAME FUNC_NAME "config card (Find IO port)\n");
> #endif
>
> - if((i = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS)
> - {
> - cs_error(link->handle, ParseTuple, i);
> - link->state &= ~DEV_CONFIG_PENDING;
> + if ((i = pcmcia_get_first_tuple(p_dev, &tuple)) != CS_SUCCESS) {
> + cs_error(p_dev, ParseTuple, i);
> goto error_return;
> }
> - i = get_tuple(handle, &tuple, &parse);
> - while (i == CS_SUCCESS)
> - {
> - if (cf->io.nwin > 0)
> - {
> - link->conf.ConfigIndex = cf->index;
> - link->io.BasePort1 = cf->io.win[0].base;
> - i = pcmcia_request_io(link->handle, &link->io);
> + i = get_tuple(p_dev, &tuple, &parse);
> + while (i == CS_SUCCESS) {
> + if (cf->io.nwin > 0) {
> + p_dev->conf.ConfigIndex = cf->index;
> + p_dev->io.BasePort1 = cf->io.win[0].base;
> + i = pcmcia_request_io(p_dev, &p_dev->io);
>
> if (i == CS_SUCCESS)
> break;
> }
> - if((i = pcmcia_get_next_tuple(handle, &tuple)) != CS_SUCCESS)
> - {
> - cs_error(link->handle, ParseTuple, i);
> - link->state &= ~DEV_CONFIG_PENDING;
> + if ((i = pcmcia_get_next_tuple(p_dev, &tuple)) != CS_SUCCESS) {
> + cs_error(p_dev, ParseTuple, i);
> goto error_return;
> }
> - i = get_tuple(handle, &tuple, &parse);
> + i = get_tuple(p_dev, &tuple, &parse);
> }
>
> - if (i != CS_SUCCESS)
> - {
> - cs_error(link->handle, RequestIO, i);
> + if (i != CS_SUCCESS) {
> + cs_error(p_dev, RequestIO, i);
> goto error_return;
> }
> #ifdef PCMCIA_DEBUG
> - printk(KERN_INFO MODULE_NAME FUNC_NAME "IO Port 0x%03x\n",
> link->io.BasePort1);
> + printk(KERN_INFO MODULE_NAME FUNC_NAME "IO Port 0x%03x\n",
> p_dev->io.BasePort1);
> printk(KERN_INFO MODULE_NAME FUNC_NAME "Begin to request IRQ\n");
> #endif
> /* Configure card Now allocate an interrupt line. (IRQ)*/
> - if ((i = pcmcia_request_irq(handle, &link->irq)) != CS_SUCCESS)
> + if ((i = pcmcia_request_irq(p_dev, &p_dev->irq)) != CS_SUCCESS)
> {
> #ifdef PCMCIA_DEBUG
> printk(KERN_INFO MODULE_NAME FUNC_NAME "Request IRQ fail!\n");
> #endif
> - cs_error(link->handle, RequestIRQ, i);
> + cs_error(p_dev, RequestIRQ, i);
> goto error_return;
> }
> #ifdef PCMCIA_DEBUG
> printk(KERN_INFO MODULE_NAME FUNC_NAME "Request IRQ successful");
> - printk("(IRQ: %d)\n", link->irq.AssignedIRQ );
> + printk("(IRQ: %d)\n", p_dev->irq.AssignedIRQ );
> #endif
>
> /* Set up the I/O window and the interrupt mapping.*/
> - i = pcmcia_request_configuration(link->handle, &link->conf);
> - if ( i != CS_SUCCESS)
> + i = pcmcia_request_configuration(p_dev, &p_dev->conf);
> + if (i != CS_SUCCESS)
> {
> - cs_error(link->handle, RequestConfiguration, i);
> + cs_error(p_dev, RequestConfiguration, i);
> goto error_return;
> }
> #ifdef PCMCIA_DEBUG
> @@ -671,25 +653,25 @@ static void ozscr_config(dev_link_t *lin
> req.Base = 0;
> req.Size = 0x1000; /* Request 2K memory */
> req.AccessSpeed = mem_speed;
> - link->win = (window_handle_t)link->handle;
> - if ((i = pcmcia_request_window(&link->handle, &req, &link->win)) !=
> CS_SUCCESS)
> + p_dev->win = (window_handle_t)p_dev;
> + if ((i = pcmcia_request_window(&p_dev, &req, &p_dev->win)) != CS_SUCCESS)
> {
> #ifdef PCMCIA_DEBUG
> printk(KERN_INFO MODULE_NAME FUNC_NAME "Request memory fail!\n");
> #endif
> - cs_error(link->handle, RequestWindow, i);
> + cs_error(p_dev, RequestWindow, i);
> goto error_return;
> }
> dev->cm_base = (caddr_t)req.Base;
> dev->am_base = ioremap(req.Base,0x1000);
> mem.CardOffset = 0x0;
> mem.Page = 0;
> - if ((i = pcmcia_map_mem_page(link->win, &mem)))
> + if ((i = pcmcia_map_mem_page(p_dev->win, &mem)))
> {
> #ifdef PCMCIA_DEBUG
> printk(KERN_INFO MODULE_NAME FUNC_NAME "Map Memory Page fail!\n");
> #endif
> - cs_error(link->handle, MapMemPage, i);
> + cs_error(p_dev, MapMemPage, i);
> goto error_return;
> }
>
> @@ -700,27 +682,26 @@ static void ozscr_config(dev_link_t *lin
> /* Initialize the dev_node_t structure */
> sprintf(dev->node.dev_name, "ozscrlx");
> dev->node.major = ozscr_major;
> - dev->node.minor = 0;
> + dev->node.minor = 0; // XXX can this support more than one device? -eric
> -> if not then there is no need of all the fuzz with dev_list
> dev->cm_base = (caddr_t)req.Base;
> - dev->io_base = link->io.BasePort1;
> - dev->irq = link->irq.AssignedIRQ;
> -
> - link->dev = &dev->node;
> + dev->io_base = p_dev->io.BasePort1;
> + dev->irq = p_dev->irq.AssignedIRQ;
>
> - link->state &= ~DEV_CONFIG_PENDING;
> + //p_dev->dev = &dev->node;
>
> #ifdef PCMCIA_DEBUG
> printk(KERN_INFO MODULE_NAME FUNC_NAME "OZSCR device loaded\n");
> #endif
> - return;
> + return 0;
>
> error_return:
>
> /* If any step failed, release any partially configured state */
> - ozscr_release((u_long)link);
> - return;
> + ozscr_release(p_dev);
> + return -ENODEV;
> }
>
> +#if 0
> /*
> * The card status event handler. Mostly, this schedules other
> * stuff to run after an event is received. A CARD_REMOVAL event
> @@ -769,7 +750,7 @@ static int ozscr_event(event_t event, in
> {
> flush_scheduled_work();
> }
> - ozscr_release((u_long)link);
> + ozscr_release(p_dev);
> break;
> case CS_EVENT_PM_SUSPEND:
> #ifdef PCMCIA_DEBUG
> @@ -807,140 +788,100 @@ static int ozscr_event(event_t event, in
> }
> return 0;
> }
> -
> -
> +#endif
>
> /*
> * ozscr_attach() creates an "instance" of the driver, allocating
> * local data structures for one device. The device is registered
> * with Card Services.
> *
> - * The dev_link structure is initialized, but we don't actually
> + * The pcmcia_device structure is initialized, but we don't actually
> * configure the card at this point -- we wait until we receive a
> * card insertion event.
> */
> -static dev_link_t *ozscr_attach(void)
> +
> +static int ozscr_attach(struct pcmcia_device *p_dev)
> {
> #undef FUNC_NAME
>
> #define FUNC_NAME "ozscr_attach: "
>
> - client_reg_t client_reg;
> - dev_link_t *link=NULL;
> +// client_reg_t client_reg;
> struct ozscr_dev_t *local=NULL;
> - int ret=0;
> + int ret = -ENOMEM;
> PREADER_EXTENSION pRdrExt=NULL;
>
> #ifdef PCMCIA_DEBUG
> printk(KERN_INFO MODULE_NAME FUNC_NAME "function begins\n");
> #endif
> - /* Initialize the dev_link_t structure */
> - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
> - if (link == NULL)
> - {
> -#ifdef PCMCIA_DEBUG
> - printk(KERN_INFO MODULE_NAME FUNC_NAME "allocate dev_link_t
> fail\n");
> -#endif
> -
> - goto ErrHandle;
> - }
> - memset(link, 0, sizeof(struct dev_link_t));
>
> /* Allocate space for private device-specific data */
> - local = kmalloc(sizeof(struct ozscr_dev_t), GFP_KERNEL);
> + local = kzalloc(sizeof(struct ozscr_dev_t), GFP_KERNEL);
> if (local == NULL)
> {
> #ifdef PCMCIA_DEBUG
> - printk(KERN_INFO MODULE_NAME FUNC_NAME "allocate dev_link_t fail\n");
> + printk(KERN_INFO MODULE_NAME FUNC_NAME "allocate ozscr_dev_t
> fail\n");
> #endif
> goto ErrHandle;
> }
> - memset(local, 0, sizeof(struct ozscr_dev_t));
>
> /* Allocate space for private device-specific data */
> - pRdrExt = kmalloc(sizeof(PREADER_EXTENSION), GFP_KERNEL);
> -
> + // XXX here there used to be a bug preventing zeroing the memory
> + pRdrExt = kzalloc(sizeof(PREADER_EXTENSION), GFP_KERNEL);
> if (pRdrExt == NULL)
> {
> #ifdef PCMCIA_DEBUG
> - printk(KERN_INFO MODULE_NAME FUNC_NAME "allocate dev_link_t fail\n");
> + printk(KERN_INFO MODULE_NAME FUNC_NAME "allocate pRdrExt fail\n");
> #endif
> goto ErrHandle;
> }
> - memset(local, 0, sizeof(PREADER_EXTENSION));
> -
> - link->priv = local;
> + p_dev->priv = local;
>
> /* The io structure describes IO port mapping */
> - link->io.NumPorts1 = 32;
> - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
> - link->io.NumPorts2 = 0;
> - link->io.IOAddrLines = 5;
> + p_dev->io.NumPorts1 = 32;
> + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
> + p_dev->io.NumPorts2 = 0;
> + p_dev->io.IOAddrLines = 5;
>
> /* Interrupt setup */
> - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE|IRQ_HANDLE_PRESENT;
> - link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
> - link->irq.IRQInfo2 = irq_mask;
> - link->irq.Handler = &ozscr_interrupt;
> - link->irq.Instance = &ozscr_reader;
> + p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE|IRQ_HANDLE_PRESENT;
> + p_dev->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
> + p_dev->irq.IRQInfo2 = irq_mask;
> + p_dev->irq.Handler = &ozscr_interrupt;
> + p_dev->irq.Instance = &ozscr_reader;
>
> /* General socket nfiguration */
> - link->conf.Attributes = CONF_ENABLE_IRQ;
> - link->conf.Vcc = 50;
> - link->conf.Vpp1 = link->conf.Vpp2 = 50;
> - link->conf.IntType = INT_MEMORY_AND_IO;
> - link->conf.Present = PRESENT_OPTION | PRESENT_STATUS;
> + p_dev->conf.Attributes = CONF_ENABLE_IRQ;
> + p_dev->conf.Vpp = 50;
> + p_dev->conf.IntType = INT_MEMORY_AND_IO;
> + p_dev->conf.Present = PRESENT_OPTION | PRESENT_STATUS;
> +
> +// link->next = dev_list; /* build linked to handle multiple instances */
> + //XXX
> + dev_list = p_dev;
> +
> + ret = ozscr_config(p_dev);
> + if (ret)
> + goto ErrHandle;
>
> - link->next = dev_list; /* build linked to handle multiple instances */
> - dev_list = link;
> + // Moved it after config, so local have been initialiased -eric
> + pRdrExt->IOBase = (PPSCR_REGISTERS)local->io_base;
> + pRdrExt->membase = local->am_base;
>
> - client_reg.dev_info = &dev_info;
> - client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
> - client_reg.Version = 0x0210;
> - client_reg.event_callback_args.client_data = link;
> + CmdResetInterface(pRdrExt);
>
> - ret = pcmcia_register_client(&link->handle, &client_reg);
> - if (ret != CS_SUCCESS)
> - {
> -#ifdef PCMCIA_DEBUG
> - printk(KERN_INFO MODULE_NAME FUNC_NAME "register client fail!\n");
> -#endif
> - goto ErrHandle;
> - }
> #ifdef PCMCIA_DEBUG
> printk(KERN_INFO MODULE_NAME FUNC_NAME "function complete\n");
> #endif
> - pRdrExt->IOBase = (PPSCR_REGISTERS)local->io_base;
> - pRdrExt->membase = local->am_base;
>
> - CmdResetInterface(pRdrExt);
> - return link;
> + // XXX free pRdrExt ?
> + return 0;
>
> ErrHandle:
> -
> - if (ret != 0)
> - {
> - cs_error(link->handle, RegisterClient, ret);
> - ozscr_detach(link); link = NULL;
> - }
> /* Free the allocated memory space */
> - if (link != NULL)
> - {
> - kfree(link);
> - link = NULL;
> - }
> - if (local != NULL)
> - {
> - kfree(local);
> - local = NULL;
> - }
> - if (pRdrExt != NULL)
> - {
> - kfree(pRdrExt);
> - pRdrExt = NULL;
> - }
> -
> - return NULL;
> + kfree(local);
> + kfree(pRdrExt);
> + return ret;
> }
>
>
> @@ -951,17 +892,10 @@ ErrHandle:
> * through a timer while the device is still open when the card has
> * been removed.
> */
> -static void
> -ozscr_release(u_long arg)
> +static void ozscr_release(struct pcmcia_device *p_dev)
> {
> -
> - dev_link_t *link = (dev_link_t *)arg;
> -
> #undef FUNC_NAME
> #define FUNC_NAME "ozscr_release: "
> -#ifdef PCMCIA_DEBUG
> - printk(KERN_INFO MODULE_NAME FUNC_NAME "Device Link(0x%p)\n", link);
> -#endif
>
> /*
> * If the device is still in use we may not release resources
> @@ -970,28 +904,10 @@ ozscr_release(u_long arg)
> * eventually freed through ozscr_detach.
> */
>
> - if (link->open)
> - {
> -#ifdef PCMCIA_DEBUG
> - printk(KERN_INFO MODULE_NAME FUNC_NAME "release postponed,%s still
> open\n", link->dev->dev_name);
> -#endif
> - link->state |= DEV_STALE_CONFIG;
> - return;
> - }
> -
> /* Unlink the device chain */
> - link->dev = NULL;
> -
> - /* Don't bother checking to see if these succeed or not */
> - pcmcia_release_window(link->win);
> - pcmcia_release_configuration(link->handle);
> -
> - pcmcia_release_io(link->handle, &link->io);
> - pcmcia_release_irq(link->handle, &link->irq);
> - link->state &= ~DEV_CONFIG;
> + // XXX ? -eric
>
> - if (link->state & DEV_STALE_LINK)
> - ozscr_detach(link);
> + pcmcia_disable_device(p_dev);
>
> return;
> }
> @@ -1001,61 +917,26 @@ ozscr_release(u_long arg)
> * with Card Services. If it has been released, all local data
> * structures are freed.
> */
> -static void
> -ozscr_detach(dev_link_t *link)
> +static void ozscr_detach(struct pcmcia_device *p_dev)
> {
> -
> #undef FUNC_NAME
> #define FUNC_NAME "ozscr_detach: "
>
> - dev_link_t **linkp;
> -
> -#ifdef PCMCIA_DEBUG
> - printk(KERN_INFO MODULE_NAME FUNC_NAME "Device Link (0x%p)\n", link);
> -#endif
> -
> - /*
> - * Locate device structure
> - */
> - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
> - {
> - if (*linkp == link)
> - break;
> - }
> - if (*linkp == NULL)
> - return;
> -
> - if (link->state & DEV_CONFIG)
> - {
> -#ifdef PCMCIA_DEBUG
> - printk(KERN_INFO MODULE_NAME FUNC_NAME ": detach of %s postponed"
> - " - device still configured", link->dev->dev_name);
> -#endif
> -
> - ozscr_release((u_long)*linkp);
> - if (link->state & DEV_STALE_CONFIG)
> - {
> - link->state |= DEV_STALE_LINK;
> - return;
> - }
> - }
> + /* Break the link with Card Services */
> +// if (link->handle)
> +// pcmcia_deregister_client(link->handle);
>
> + //needed ? XXX -eric
> + flush_scheduled_work();
>
> - /* Break the link with Card Services */
> - if (link->handle)
> - pcmcia_deregister_client(link->handle);
> + ozscr_release(p_dev);
> + kfree(p_dev->priv);
>
> - /* Unlink device structure, free pieces */
> - *linkp = link->next;
>
> - if (link->priv)
> - {
> - kfree(link->priv);
> - }
> - kfree(link);
> + // XXX we have to manage the linked list
> + dev_list = NULL; //XXX
>
> return;
> -
> }
>
> ssize_t ozscr_read(
> @@ -1126,22 +1007,20 @@ init_ozscrlx(void)
>
> }
>
> -static void
> -exit_ozscrlx(void)
> +static void exit_ozscrlx(void)
> {
> #undef FUNC_NAME
> -
> #define FUNC_NAME "exit_ozscrlx: "
> #ifdef PCMCIA_DEBUG
> printk(KERN_INFO MODULE_NAME FUNC_NAME "unloading module\n");
> #endif
> unregister_chrdev(ozscr_major, "ozscrlx");
> pcmcia_unregister_driver(&ozscrlx_driver);
> +
> + // XXX we need to free all the registered devices
> while (dev_list != NULL)
> {
> - if (dev_list->state & DEV_CONFIG)
> - ozscr_release((u_long)dev_list);
> - ozscr_detach(dev_list);
> + ozscr_detach(dev_list);
> }
>
> return;
> @@ -4537,4 +4416,3 @@ module_exit(exit_ozscrlx);
> MODULE_LICENSE("GPL");
>
>
> -
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Muscle mailing list
> [email protected]
> http://lists.drizzle.com/mailman/listinfo/muscle
_______________________________________________
Muscle mailing list
[email protected]
http://lists.drizzle.com/mailman/listinfo/muscle