From: Dominik Brodowski Fix up cm40x0 drivers for recent PCMCIA changes in -mm. Signed-off-by: Dominik Brodowski Signed-off-by: Andrew Morton --- drivers/char/pcmcia/cm4000_cs.c | 162 ++++++++++++---------------------------- drivers/char/pcmcia/cm4040_cs.c | 152 +++++++++++-------------------------- 2 files changed, 97 insertions(+), 217 deletions(-) diff -puN drivers/char/pcmcia/cm4000_cs.c~pcmcia-fix-up-cm40x0-drivers drivers/char/pcmcia/cm4000_cs.c --- devel/drivers/char/pcmcia/cm4000_cs.c~pcmcia-fix-up-cm40x0-drivers 2005-09-16 01:04:08.000000000 -0700 +++ devel-akpm/drivers/char/pcmcia/cm4000_cs.c 2005-09-16 01:04:08.000000000 -0700 @@ -66,7 +66,6 @@ static char *version = "cm4000_cs.c v2.4 #define T_100MSEC msecs_to_jiffies(100) #define T_500MSEC msecs_to_jiffies(500) -static void cm4000_detach(dev_link_t *link); static void cm4000_release(dev_link_t *link); static int major; /* major number we get from the kernel */ @@ -156,7 +155,6 @@ struct cm4000_dev { /*sbuf*/ 512*sizeof(char) - \ /*queue*/ 4*sizeof(wait_queue_head_t)) -static dev_info_t dev_info = MODULE_NAME; static dev_link_t *dev_table[CM4000_MAX_DEV]; /* This table doesn't use spaces after the comma between fields and thus @@ -1863,68 +1861,36 @@ cs_release: link->state &= ~DEV_CONFIG_PENDING; } -static int cm4000_event(event_t event, int priority, - event_callback_args_t *args) +static int cm4000_suspend(struct pcmcia_device *p_dev) { - dev_link_t *link; + dev_link_t *link = dev_to_instance(p_dev); struct cm4000_dev *dev; - int devno; - link = args->client_data; dev = link->priv; - DEBUGP(3, dev, "-> cm4000_event\n"); - for (devno = 0; devno < CM4000_MAX_DEV; devno++) - if (dev_table[devno] == link) - break; + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + stop_monitor(dev); - if (devno == CM4000_MAX_DEV) - return CS_BAD_ADAPTER; + return 0; +} - switch (event) { - case CS_EVENT_CARD_INSERTION: - DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n"); - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - cm4000_config(link, devno); - break; - case CS_EVENT_CARD_REMOVAL: - DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); - link->state &= ~DEV_PRESENT; - stop_monitor(dev); - break; - case CS_EVENT_PM_SUSPEND: - DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND " - "(fall-through to CS_EVENT_RESET_PHYSICAL)\n"); - link->state |= DEV_SUSPEND; - /* fall-through */ - case CS_EVENT_RESET_PHYSICAL: - DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n"); - if (link->state & DEV_CONFIG) { - DEBUGP(5, dev, "ReleaseConfiguration\n"); - pcmcia_release_configuration(link->handle); - } - stop_monitor(dev); - break; - case CS_EVENT_PM_RESUME: - DEBUGP(5, dev, "CS_EVENT_PM_RESUME " - "(fall-through to CS_EVENT_CARD_RESET)\n"); - link->state &= ~DEV_SUSPEND; - /* fall-through */ - case CS_EVENT_CARD_RESET: - DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n"); - if ((link->state & DEV_CONFIG)) { - DEBUGP(5, dev, "RequestConfiguration\n"); - pcmcia_request_configuration(link->handle, &link->conf); - } - if (link->open) - start_monitor(dev); - break; - default: - DEBUGP(5, dev, "unknown event %.2x\n", event); - break; - } - DEBUGP(3, dev, "<- cm4000_event\n"); - return CS_SUCCESS; +static int cm4000_resume(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + struct cm4000_dev *dev; + + dev = link->priv; + + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); + + if (link->open) + start_monitor(dev); + + return 0; } static void cm4000_release(dev_link_t *link) @@ -1934,11 +1900,10 @@ static void cm4000_release(dev_link_t *l pcmcia_release_io(link->handle, &link->io); } -static dev_link_t *cm4000_attach(void) +static int cm4000_attach(struct pcmcia_device *p_dev) { struct cm4000_dev *dev; dev_link_t *link; - client_reg_t client_reg; int i; for (i = 0; i < CM4000_MAX_DEV; i++) @@ -1947,76 +1912,55 @@ static dev_link_t *cm4000_attach(void) if (i == CM4000_MAX_DEV) { printk(KERN_NOTICE MODULE_NAME ": all devices in use\n"); - return NULL; + return -ENODEV; } /* create a new cm4000_cs device */ dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL); if (dev == NULL) - return NULL; + return -ENOMEM; link = &dev->link; link->priv = dev; link->conf.IntType = INT_MEMORY_AND_IO; dev_table[i] = link; - /* register with card services */ - client_reg.dev_info = &dev_info; - client_reg.EventMask = - CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | - CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | - CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; - client_reg.Version = 0x0210; - client_reg.event_callback_args.client_data = link; - - i = pcmcia_register_client(&link->handle, &client_reg); - if (i) { - cs_error(link->handle, RegisterClient, i); - cm4000_detach(link); - return NULL; - } - init_waitqueue_head(&dev->devq); init_waitqueue_head(&dev->ioq); init_waitqueue_head(&dev->atrq); init_waitqueue_head(&dev->readq); - return link; + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + cm4000_config(link, i); + + return 0; } -static void cm4000_detach_by_devno(int devno, dev_link_t * link) +static void cm4000_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct cm4000_dev *dev = link->priv; + int devno; + + /* find device */ + for (devno = 0; devno < CM4000_MAX_DEV; devno++) + if (dev_table[devno] == link) + break; + if (devno == CM4000_MAX_DEV) + return; - DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno); + link->state &= ~DEV_PRESENT; + stop_monitor(dev); - if (link->state & DEV_CONFIG) { - DEBUGP(5, dev, "device still configured (try to release it)\n"); + if (link->state & DEV_CONFIG) cm4000_release(link); - } - - if (link->handle) { - pcmcia_deregister_client(link->handle); - } dev_table[devno] = NULL; kfree(dev); - return; -} -static void cm4000_detach(dev_link_t * link) -{ - int i; - - /* find device */ - for (i = 0; i < CM4000_MAX_DEV; i++) - if (dev_table[i] == link) - break; - - if (i == CM4000_MAX_DEV) - return; - - cm4000_detach_by_devno(i, link); return; } @@ -2041,35 +1985,31 @@ static struct pcmcia_driver cm4000_drive .drv = { .name = "cm4000_cs", }, - .attach = cm4000_attach, - .detach = cm4000_detach, - .event = cm4000_event, + .probe = cm4000_attach, + .remove = cm4000_detach, + .suspend = cm4000_suspend, + .resume = cm4000_resume, .id_table = cm4000_ids, }; static int __init cmm_init(void) { printk(KERN_INFO "%s\n", version); - pcmcia_register_driver(&cm4000_driver); major = register_chrdev(0, DEVICE_NAME, &cm4000_fops); if (major < 0) { printk(KERN_WARNING MODULE_NAME ": could not get major number\n"); return -1; } + pcmcia_register_driver(&cm4000_driver); return 0; } static void __exit cmm_exit(void) { - int i; - printk(KERN_INFO MODULE_NAME ": unloading\n"); pcmcia_unregister_driver(&cm4000_driver); - for (i = 0; i < CM4000_MAX_DEV; i++) - if (dev_table[i]) - cm4000_detach_by_devno(i, dev_table[i]); unregister_chrdev(major, DEVICE_NAME); }; diff -puN drivers/char/pcmcia/cm4040_cs.c~pcmcia-fix-up-cm40x0-drivers drivers/char/pcmcia/cm4040_cs.c --- devel/drivers/char/pcmcia/cm4040_cs.c~pcmcia-fix-up-cm40x0-drivers 2005-09-16 01:04:08.000000000 -0700 +++ devel-akpm/drivers/char/pcmcia/cm4040_cs.c 2005-09-16 01:04:08.000000000 -0700 @@ -65,7 +65,6 @@ static char *version = #define POLL_PERIOD msecs_to_jiffies(10) static void reader_release(dev_link_t *link); -static void reader_detach(dev_link_t *link); static int major; @@ -622,67 +621,29 @@ cs_release: link->state &= ~DEV_CONFIG_PENDING; } -static int reader_event(event_t event, int priority, - event_callback_args_t *args) +static int reader_suspend(struct pcmcia_device *p_dev) { - dev_link_t *link; - struct reader_dev *dev; - int devno; + dev_link_t *link = dev_to_instance(p_dev); - link = args->client_data; - dev = link->priv; - DEBUGP(3, dev, "-> reader_event\n"); - for (devno = 0; devno < CM_MAX_DEV; devno++) { - if (dev_table[devno] == link) - break; - } - if (devno == CM_MAX_DEV) - return CS_BAD_ADAPTER; + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); - switch (event) { - case CS_EVENT_CARD_INSERTION: - DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n"); - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - reader_config(link, devno); - break; - case CS_EVENT_CARD_REMOVAL: - DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); - link->state &= ~DEV_PRESENT; - break; - case CS_EVENT_PM_SUSPEND: - DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND " - "(fall-through to CS_EVENT_RESET_PHYSICAL)\n"); - link->state |= DEV_SUSPEND; - - case CS_EVENT_RESET_PHYSICAL: - DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n"); - if (link->state & DEV_CONFIG) { - DEBUGP(5, dev, "ReleaseConfiguration\n"); - pcmcia_release_configuration(link->handle); - } - break; - case CS_EVENT_PM_RESUME: - DEBUGP(5, dev, "CS_EVENT_PM_RESUME " - "(fall-through to CS_EVENT_CARD_RESET)\n"); - link->state &= ~DEV_SUSPEND; - - case CS_EVENT_CARD_RESET: - DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n"); - if ((link->state & DEV_CONFIG)) { - DEBUGP(5, dev, "RequestConfiguration\n"); - pcmcia_request_configuration(link->handle, - &link->conf); - } - break; - default: - DEBUGP(5, dev, "reader_event: unknown event %.2x\n", - event); - break; - } - DEBUGP(3, dev, "<- reader_event\n"); - return CS_SUCCESS; + return 0; +} + +static int reader_resume(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); + + return 0; } + static void reader_release(dev_link_t *link) { cm4040_reader_release(link->priv); @@ -690,11 +651,10 @@ static void reader_release(dev_link_t *l pcmcia_release_io(link->handle, &link->io); } -static dev_link_t *reader_attach(void) +static int reader_attach(struct pcmcia_device *p_dev) { struct reader_dev *dev; dev_link_t *link; - client_reg_t client_reg; int i; for (i = 0; i < CM_MAX_DEV; i++) { @@ -703,11 +663,11 @@ static dev_link_t *reader_attach(void) } if (i == CM_MAX_DEV) - return NULL; + return -ENODEV; dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL); if (dev == NULL) - return NULL; + return -ENOMEM; dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT; dev->buffer_status = 0; @@ -718,20 +678,6 @@ static dev_link_t *reader_attach(void) link->conf.IntType = INT_MEMORY_AND_IO; dev_table[i] = link; - client_reg.dev_info = &dev_info; - client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; - client_reg.EventMask= - CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | - CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | - CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; - client_reg.Version = 0x0210; - client_reg.event_callback_args.client_data = link; - i = pcmcia_register_client(&link->handle, &client_reg); - if (i) { - cs_error(link->handle, RegisterClient, i); - reader_detach(link); - return NULL; - } init_waitqueue_head(&dev->devq); init_waitqueue_head(&dev->poll_wait); init_waitqueue_head(&dev->read_wait); @@ -739,38 +685,37 @@ static dev_link_t *reader_attach(void) init_timer(&dev->poll_timer); dev->poll_timer.function = &cm4040_do_poll; - return link; -} - -static void reader_detach_by_devno(int devno, dev_link_t *link) -{ - struct reader_dev *dev = link->priv; + link->handle = p_dev; + p_dev->instance = link; - if (link->state & DEV_CONFIG) { - DEBUGP(5, dev, "device still configured (try to release it)\n"); - reader_release(link); - } + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + reader_config(link, i); - pcmcia_deregister_client(link->handle); - dev_table[devno] = NULL; - DEBUGP(5, dev, "freeing dev=%p\n", dev); - kfree(dev); - return; + return 0; } -static void reader_detach(dev_link_t *link) +static void reader_detach(struct pcmcia_device *p_dev) { - int i; + dev_link_t *link = dev_to_instance(p_dev); + struct reader_dev *dev = link->priv; + int devno; /* find device */ - for (i = 0; i < CM_MAX_DEV; i++) { - if (dev_table[i] == link) + for (devno = 0; devno < CM_MAX_DEV; devno++) { + if (dev_table[devno] == link) break; } - if (i == CM_MAX_DEV) + if (devno == CM_MAX_DEV) return; - reader_detach_by_devno(i, link); + link->state &= ~DEV_PRESENT; + + if (link->state & DEV_CONFIG) + reader_release(link); + + dev_table[devno] = NULL; + kfree(dev); + return; } @@ -796,35 +741,30 @@ static struct pcmcia_driver reader_drive .drv = { .name = "cm4040_cs", }, - .attach = reader_attach, - .detach = reader_detach, - .event = reader_event, + .probe = reader_attach, + .remove = reader_detach, + .suspend = reader_suspend, + .resume = reader_resume, .id_table = cm4040_ids, }; static int __init cm4040_init(void) { printk(KERN_INFO "%s\n", version); - pcmcia_register_driver(&reader_driver); major = register_chrdev(0, DEVICE_NAME, &reader_fops); if (major < 0) { printk(KERN_WARNING MODULE_NAME ": could not get major number\n"); return -1; } + pcmcia_register_driver(&reader_driver); return 0; } static void __exit cm4040_exit(void) { - int i; - printk(KERN_INFO MODULE_NAME ": unloading\n"); pcmcia_unregister_driver(&reader_driver); - for (i = 0; i < CM_MAX_DEV; i++) { - if (dev_table[i]) - reader_detach_by_devno(i, dev_table[i]); - } unregister_chrdev(major, DEVICE_NAME); } _