X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmtd%2Fmaps%2Fpcmciamtd.c;fp=drivers%2Fmtd%2Fmaps%2Fpcmciamtd.c;h=f0f8916da7adf1b9e0d6ad08ba0f8649e96f465f;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=c861134cbc48d253ccc3530568402b0de0665441;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index c861134cb..f0f8916da 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -28,7 +28,7 @@ #ifdef CONFIG_MTD_DEBUG static int debug = CONFIG_MTD_DEBUG_VERBOSE; -module_param(debug, int, 0); +MODULE_PARM(debug, "i"); MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy"); #undef DEBUG #define DEBUG(n, format, arg...) \ @@ -54,7 +54,7 @@ static const int debug = 0; #define MAX_PCMCIA_ADDR 0x4000000 struct pcmciamtd_dev { - struct pcmcia_device *p_dev; + dev_link_t link; /* PCMCIA link */ dev_node_t node; /* device node */ caddr_t win_base; /* ioremapped address of PCMCIA window */ unsigned int win_size; /* size of window */ @@ -89,17 +89,17 @@ static int mem_type; MODULE_LICENSE("GPL"); MODULE_AUTHOR("Simon Evans "); MODULE_DESCRIPTION(DRIVER_DESC); -module_param(bankwidth, int, 0); +MODULE_PARM(bankwidth, "i"); MODULE_PARM_DESC(bankwidth, "Set bankwidth (1=8 bit, 2=16 bit, default=2)"); -module_param(mem_speed, int, 0); +MODULE_PARM(mem_speed, "i"); MODULE_PARM_DESC(mem_speed, "Set memory access speed in ns"); -module_param(force_size, int, 0); +MODULE_PARM(force_size, "i"); MODULE_PARM_DESC(force_size, "Force size of card in MiB (1-64)"); -module_param(setvpp, int, 0); +MODULE_PARM(setvpp, "i"); MODULE_PARM_DESC(setvpp, "Set Vpp (0=Never, 1=On writes, 2=Always on, default=0)"); -module_param(vpp, int, 0); +MODULE_PARM(vpp, "i"); MODULE_PARM_DESC(vpp, "Vpp value in 1/10ths eg 33=3.3V 120=12V (Dangerous)"); -module_param(mem_type, int, 0); +MODULE_PARM(mem_type, "i"); MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)"); @@ -111,8 +111,8 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) memreq_t mrq; int ret; - if (!pcmcia_dev_present(dev->p_dev)) { - DEBUG(1, "device removed"); + if(!(dev->link.state & DEV_PRESENT)) { + DEBUG(1, "device removed state = 0x%4.4X", dev->link.state); return 0; } @@ -122,7 +122,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) dev->offset, mrq.CardOffset); mrq.Page = 0; if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) { - cs_error(dev->p_dev, MapMemPage, ret); + cs_error(dev->link.handle, MapMemPage, ret); return NULL; } dev->offset = mrq.CardOffset; @@ -238,7 +238,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v /* read/write{8,16} copy_{from,to} routines with direct access */ -#define DEV_REMOVED(x) (!(pcmcia_dev_present(((struct pcmciamtd_dev *)map->map_priv_1)->p_dev))) +#define DEV_REMOVED(x) (!(*(u_int *)x->map_priv_1 & DEV_PRESENT)) static map_word pcmcia_read8(struct map_info *map, unsigned long ofs) { @@ -319,7 +319,7 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f static void pcmciamtd_set_vpp(struct map_info *map, int on) { struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; - struct pcmcia_device *link = dev->p_dev; + dev_link_t *link = &dev->link; modconf_t mod; int ret; @@ -328,9 +328,9 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0; DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); - ret = pcmcia_modify_configuration(link, &mod); + ret = pcmcia_modify_configuration(link->handle, &mod); if(ret != CS_SUCCESS) { - cs_error(link, ModifyConfiguration, ret); + cs_error(link->handle, ModifyConfiguration, ret); } } @@ -340,7 +340,7 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) * still open, this will be postponed until it is closed. */ -static void pcmciamtd_release(struct pcmcia_device *link) +static void pcmciamtd_release(dev_link_t *link) { struct pcmciamtd_dev *dev = link->priv; @@ -353,11 +353,12 @@ static void pcmciamtd_release(struct pcmcia_device *link) } pcmcia_release_window(link->win); } - pcmcia_disable_device(link); + pcmcia_release_configuration(link->handle); + link->state &= ~DEV_CONFIG; } -static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name) +static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_name) { int rc; tuple_t tuple; @@ -370,16 +371,16 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, tuple.TupleOffset = 0; tuple.DesiredTuple = RETURN_FIRST_TUPLE; - rc = pcmcia_get_first_tuple(link, &tuple); + rc = pcmcia_get_first_tuple(link->handle, &tuple); while(rc == CS_SUCCESS) { - rc = pcmcia_get_tuple_data(link, &tuple); + rc = pcmcia_get_tuple_data(link->handle, &tuple); if(rc != CS_SUCCESS) { - cs_error(link, GetTupleData, rc); + cs_error(link->handle, GetTupleData, rc); break; } - rc = pcmcia_parse_tuple(link, &tuple, &parse); + rc = pcmcia_parse_tuple(link->handle, &tuple, &parse); if(rc != CS_SUCCESS) { - cs_error(link, ParseTuple, rc); + cs_error(link->handle, ParseTuple, rc); break; } @@ -450,7 +451,7 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); } - rc = pcmcia_get_next_tuple(link, &tuple); + rc = pcmcia_get_next_tuple(link->handle, &tuple); } if(!dev->pcmcia_map.size) dev->pcmcia_map.size = MAX_PCMCIA_ADDR; @@ -487,7 +488,7 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int pcmciamtd_config(struct pcmcia_device *link) +static void pcmciamtd_config(dev_link_t *link) { struct pcmciamtd_dev *dev = link->priv; struct mtd_info *mtd = NULL; @@ -503,10 +504,13 @@ static int pcmciamtd_config(struct pcmcia_device *link) DEBUG(3, "link=0x%p", link); + /* Configure card */ + link->state |= DEV_CONFIG; + DEBUG(2, "Validating CIS"); - ret = pcmcia_validate_cis(link, &cisinfo); + ret = pcmcia_validate_cis(link->handle, &cisinfo); if(ret != CS_SUCCESS) { - cs_error(link, GetTupleData, ret); + cs_error(link->handle, GetTupleData, ret); } else { DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains); } @@ -534,7 +538,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16; req.Base = 0; req.AccessSpeed = mem_speed; - link->win = (window_handle_t)link; + link->win = (window_handle_t)link->handle; req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR; dev->win_size = 0; @@ -542,7 +546,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) int ret; DEBUG(2, "requesting window with size = %dKiB memspeed = %d", req.Size >> 10, req.AccessSpeed); - ret = pcmcia_request_window(&link, &req, &link->win); + ret = pcmcia_request_window(&link->handle, &req, &link->win); DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size); if(ret) { req.Size >>= 1; @@ -558,19 +562,19 @@ static int pcmciamtd_config(struct pcmcia_device *link) if(!dev->win_size) { err("Cant allocate memory window"); pcmciamtd_release(link); - return -ENODEV; + return; } DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); /* Get write protect status */ - CS_CHECK(GetStatus, pcmcia_get_status(link, &status)); + CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status)); DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx", status.CardState, (unsigned long)link->win); dev->win_base = ioremap(req.Base, req.Size); if(!dev->win_base) { err("ioremap(%lu, %u) failed", req.Base, req.Size); pcmciamtd_release(link); - return -ENODEV; + return; } DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x", dev, req.Base, dev->win_base, req.Size); @@ -580,14 +584,17 @@ static int pcmciamtd_config(struct pcmcia_device *link) dev->pcmcia_map.map_priv_2 = (unsigned long)link->win; DEBUG(2, "Getting configuration"); - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &t)); + CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link->handle, &t)); DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2); dev->vpp = (vpp) ? vpp : t.Vpp1; link->conf.Attributes = 0; + link->conf.Vcc = t.Vcc; if(setvpp == 2) { - link->conf.Vpp = dev->vpp; + link->conf.Vpp1 = dev->vpp; + link->conf.Vpp2 = dev->vpp; } else { - link->conf.Vpp = 0; + link->conf.Vpp1 = 0; + link->conf.Vpp2 = 0; } link->conf.IntType = INT_MEMORY; @@ -599,10 +606,9 @@ static int pcmciamtd_config(struct pcmcia_device *link) link->conf.ConfigIndex = 0; link->conf.Present = t.Present; DEBUG(2, "Setting Configuration"); - ret = pcmcia_request_configuration(link, &link->conf); + ret = pcmcia_request_configuration(link->handle, &link->conf); if(ret != CS_SUCCESS) { - cs_error(link, RequestConfiguration, ret); - return -ENODEV; + cs_error(link->handle, RequestConfiguration, ret); } if(mem_type == 1) { @@ -610,7 +616,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) } else if(mem_type == 2) { mtd = do_map_probe("map_rom", &dev->pcmcia_map); } else { - for(i = 0; i < ARRAY_SIZE(probes); i++) { + for(i = 0; i < sizeof(probes) / sizeof(char *); i++) { DEBUG(1, "Trying %s", probes[i]); mtd = do_map_probe(probes[i], &dev->pcmcia_map); if(mtd) @@ -623,7 +629,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) if(!mtd) { DEBUG(1, "Cant find an MTD"); pcmciamtd_release(link); - return -ENODEV; + return; } dev->mtd_info = mtd; @@ -648,6 +654,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) use the faster non-remapping read/write functions */ if(mtd->size <= dev->win_size) { DEBUG(1, "Using non remapping memory functions"); + dev->pcmcia_map.map_priv_1 = (unsigned long)&(dev->link.state); dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base; if (dev->pcmcia_map.bankwidth == 1) { dev->pcmcia_map.read = pcmcia_read8; @@ -665,18 +672,19 @@ static int pcmciamtd_config(struct pcmcia_device *link) dev->mtd_info = NULL; err("Couldnt register MTD device"); pcmciamtd_release(link); - return -ENODEV; + return; } snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index); info("mtd%d: %s", mtd->index, mtd->name); - link->dev_node = &dev->node; - return 0; + link->state &= ~DEV_CONFIG_PENDING; + link->dev = &dev->node; + return; cs_failed: - cs_error(link, last_fn, last_ret); + cs_error(link->handle, last_fn, last_ret); err("CS Error, exiting"); pcmciamtd_release(link); - return -ENODEV; + return; } @@ -705,19 +713,21 @@ static int pcmciamtd_resume(struct pcmcia_device *dev) * when the device is released. */ -static void pcmciamtd_detach(struct pcmcia_device *link) +static void pcmciamtd_detach(struct pcmcia_device *p_dev) { - struct pcmciamtd_dev *dev = link->priv; + dev_link_t *link = dev_to_instance(p_dev); DEBUG(3, "link=0x%p", link); - if(dev->mtd_info) { - del_mtd_device(dev->mtd_info); - map_destroy(dev->mtd_info); - info("mtd%d: Removed", dev->mtd_info->index); - } + if(link->state & DEV_CONFIG) { + struct pcmciamtd_dev *dev = link->priv; + if(dev->mtd_info) { + del_mtd_device(dev->mtd_info); + info("mtd%d: Removed", dev->mtd_info->index); + } - pcmciamtd_release(link); + pcmciamtd_release(link); + } } @@ -726,9 +736,10 @@ static void pcmciamtd_detach(struct pcmcia_device *link) * with Card Services. */ -static int pcmciamtd_probe(struct pcmcia_device *link) +static int pcmciamtd_attach(struct pcmcia_device *p_dev) { struct pcmciamtd_dev *dev; + dev_link_t *link; /* Create new memory card device */ dev = kmalloc(sizeof(*dev), GFP_KERNEL); @@ -736,13 +747,20 @@ static int pcmciamtd_probe(struct pcmcia_device *link) DEBUG(1, "dev=0x%p", dev); memset(dev, 0, sizeof(*dev)); - dev->p_dev = link; + link = &dev->link; link->priv = dev; link->conf.Attributes = 0; link->conf.IntType = INT_MEMORY; - return pcmciamtd_config(link); + link->next = NULL; + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + pcmciamtd_config(link); + + return 0; } static struct pcmcia_device_id pcmciamtd_ids[] = { @@ -776,7 +794,7 @@ static struct pcmcia_driver pcmciamtd_driver = { .drv = { .name = "pcmciamtd" }, - .probe = pcmciamtd_probe, + .probe = pcmciamtd_attach, .remove = pcmciamtd_detach, .owner = THIS_MODULE, .id_table = pcmciamtd_ids,