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