0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/module.h>
0013 #include <linux/slab.h>
0014 #include <linux/timer.h>
0015 #include <linux/init.h>
0016 #include <asm/io.h>
0017
0018 #include <pcmcia/cistpl.h>
0019 #include <pcmcia/ds.h>
0020
0021 #include <linux/mtd/map.h>
0022 #include <linux/mtd/mtd.h>
0023
0024 #define info(format, arg...) printk(KERN_INFO "pcmciamtd: " format "\n" , ## arg)
0025
0026 #define DRIVER_DESC "PCMCIA Flash memory card driver"
0027
0028
0029 #define MAX_PCMCIA_ADDR 0x4000000
0030
0031 struct pcmciamtd_dev {
0032 struct pcmcia_device *p_dev;
0033 void __iomem *win_base;
0034 unsigned int win_size;
0035 unsigned int offset;
0036 struct map_info pcmcia_map;
0037 struct mtd_info *mtd_info;
0038 int vpp;
0039 char mtd_name[sizeof(struct cistpl_vers_1_t)];
0040 };
0041
0042
0043
0044
0045
0046 static int bankwidth = 2;
0047
0048
0049 static int mem_speed;
0050
0051
0052 static int force_size;
0053
0054
0055 static int vpp;
0056
0057
0058 static int setvpp;
0059
0060
0061 static int mem_type;
0062
0063 MODULE_LICENSE("GPL");
0064 MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
0065 MODULE_DESCRIPTION(DRIVER_DESC);
0066 module_param(bankwidth, int, 0);
0067 MODULE_PARM_DESC(bankwidth, "Set bankwidth (1=8 bit, 2=16 bit, default=2)");
0068 module_param(mem_speed, int, 0);
0069 MODULE_PARM_DESC(mem_speed, "Set memory access speed in ns");
0070 module_param(force_size, int, 0);
0071 MODULE_PARM_DESC(force_size, "Force size of card in MiB (1-64)");
0072 module_param(setvpp, int, 0);
0073 MODULE_PARM_DESC(setvpp, "Set Vpp (0=Never, 1=On writes, 2=Always on, default=0)");
0074 module_param(vpp, int, 0);
0075 MODULE_PARM_DESC(vpp, "Vpp value in 1/10ths eg 33=3.3V 120=12V (Dangerous)");
0076 module_param(mem_type, int, 0);
0077 MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)");
0078
0079
0080
0081
0082
0083 static void __iomem *remap_window(struct map_info *map, unsigned long to)
0084 {
0085 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
0086 struct resource *win = (struct resource *) map->map_priv_2;
0087 unsigned int offset;
0088 int ret;
0089
0090 if (!pcmcia_dev_present(dev->p_dev)) {
0091 pr_debug("device removed\n");
0092 return NULL;
0093 }
0094
0095 offset = to & ~(dev->win_size-1);
0096 if (offset != dev->offset) {
0097 pr_debug("Remapping window from 0x%8.8x to 0x%8.8x\n",
0098 dev->offset, offset);
0099 ret = pcmcia_map_mem_page(dev->p_dev, win, offset);
0100 if (ret != 0)
0101 return NULL;
0102 dev->offset = offset;
0103 }
0104 return dev->win_base + (to & (dev->win_size-1));
0105 }
0106
0107
0108 static map_word pcmcia_read8_remap(struct map_info *map, unsigned long ofs)
0109 {
0110 void __iomem *addr;
0111 map_word d = {{0}};
0112
0113 addr = remap_window(map, ofs);
0114 if(!addr)
0115 return d;
0116
0117 d.x[0] = readb(addr);
0118 pr_debug("ofs = 0x%08lx (%p) data = 0x%02lx\n", ofs, addr, d.x[0]);
0119 return d;
0120 }
0121
0122
0123 static map_word pcmcia_read16_remap(struct map_info *map, unsigned long ofs)
0124 {
0125 void __iomem *addr;
0126 map_word d = {{0}};
0127
0128 addr = remap_window(map, ofs);
0129 if(!addr)
0130 return d;
0131
0132 d.x[0] = readw(addr);
0133 pr_debug("ofs = 0x%08lx (%p) data = 0x%04lx\n", ofs, addr, d.x[0]);
0134 return d;
0135 }
0136
0137
0138 static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long from, ssize_t len)
0139 {
0140 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
0141 unsigned long win_size = dev->win_size;
0142
0143 pr_debug("to = %p from = %lu len = %zd\n", to, from, len);
0144 while(len) {
0145 int toread = win_size - (from & (win_size-1));
0146 void __iomem *addr;
0147
0148 if(toread > len)
0149 toread = len;
0150
0151 addr = remap_window(map, from);
0152 if(!addr)
0153 return;
0154
0155 pr_debug("memcpy from %p to %p len = %d\n", addr, to, toread);
0156 memcpy_fromio(to, addr, toread);
0157 len -= toread;
0158 to += toread;
0159 from += toread;
0160 }
0161 }
0162
0163
0164 static void pcmcia_write8_remap(struct map_info *map, map_word d, unsigned long adr)
0165 {
0166 void __iomem *addr = remap_window(map, adr);
0167
0168 if(!addr)
0169 return;
0170
0171 pr_debug("adr = 0x%08lx (%p) data = 0x%02lx\n", adr, addr, d.x[0]);
0172 writeb(d.x[0], addr);
0173 }
0174
0175
0176 static void pcmcia_write16_remap(struct map_info *map, map_word d, unsigned long adr)
0177 {
0178 void __iomem *addr = remap_window(map, adr);
0179 if(!addr)
0180 return;
0181
0182 pr_debug("adr = 0x%08lx (%p) data = 0x%04lx\n", adr, addr, d.x[0]);
0183 writew(d.x[0], addr);
0184 }
0185
0186
0187 static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const void *from, ssize_t len)
0188 {
0189 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
0190 unsigned long win_size = dev->win_size;
0191
0192 pr_debug("to = %lu from = %p len = %zd\n", to, from, len);
0193 while(len) {
0194 int towrite = win_size - (to & (win_size-1));
0195 void __iomem *addr;
0196
0197 if(towrite > len)
0198 towrite = len;
0199
0200 addr = remap_window(map, to);
0201 if(!addr)
0202 return;
0203
0204 pr_debug("memcpy from %p to %p len = %d\n", from, addr, towrite);
0205 memcpy_toio(addr, from, towrite);
0206 len -= towrite;
0207 to += towrite;
0208 from += towrite;
0209 }
0210 }
0211
0212
0213
0214
0215 #define DEV_REMOVED(x) (!(pcmcia_dev_present(((struct pcmciamtd_dev *)map->map_priv_1)->p_dev)))
0216
0217 static map_word pcmcia_read8(struct map_info *map, unsigned long ofs)
0218 {
0219 void __iomem *win_base = (void __iomem *)map->map_priv_2;
0220 map_word d = {{0}};
0221
0222 if(DEV_REMOVED(map))
0223 return d;
0224
0225 d.x[0] = readb(win_base + ofs);
0226 pr_debug("ofs = 0x%08lx (%p) data = 0x%02lx\n",
0227 ofs, win_base + ofs, d.x[0]);
0228 return d;
0229 }
0230
0231
0232 static map_word pcmcia_read16(struct map_info *map, unsigned long ofs)
0233 {
0234 void __iomem *win_base = (void __iomem *)map->map_priv_2;
0235 map_word d = {{0}};
0236
0237 if(DEV_REMOVED(map))
0238 return d;
0239
0240 d.x[0] = readw(win_base + ofs);
0241 pr_debug("ofs = 0x%08lx (%p) data = 0x%04lx\n",
0242 ofs, win_base + ofs, d.x[0]);
0243 return d;
0244 }
0245
0246
0247 static void pcmcia_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
0248 {
0249 void __iomem *win_base = (void __iomem *)map->map_priv_2;
0250
0251 if(DEV_REMOVED(map))
0252 return;
0253
0254 pr_debug("to = %p from = %lu len = %zd\n", to, from, len);
0255 memcpy_fromio(to, win_base + from, len);
0256 }
0257
0258
0259 static void pcmcia_write8(struct map_info *map, map_word d, unsigned long adr)
0260 {
0261 void __iomem *win_base = (void __iomem *)map->map_priv_2;
0262
0263 if(DEV_REMOVED(map))
0264 return;
0265
0266 pr_debug("adr = 0x%08lx (%p) data = 0x%02lx\n",
0267 adr, win_base + adr, d.x[0]);
0268 writeb(d.x[0], win_base + adr);
0269 }
0270
0271
0272 static void pcmcia_write16(struct map_info *map, map_word d, unsigned long adr)
0273 {
0274 void __iomem *win_base = (void __iomem *)map->map_priv_2;
0275
0276 if(DEV_REMOVED(map))
0277 return;
0278
0279 pr_debug("adr = 0x%08lx (%p) data = 0x%04lx\n",
0280 adr, win_base + adr, d.x[0]);
0281 writew(d.x[0], win_base + adr);
0282 }
0283
0284
0285 static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
0286 {
0287 void __iomem *win_base = (void __iomem *)map->map_priv_2;
0288
0289 if(DEV_REMOVED(map))
0290 return;
0291
0292 pr_debug("to = %lu from = %p len = %zd\n", to, from, len);
0293 memcpy_toio(win_base + to, from, len);
0294 }
0295
0296
0297 static DEFINE_MUTEX(pcmcia_vpp_lock);
0298 static int pcmcia_vpp_refcnt;
0299 static void pcmciamtd_set_vpp(struct map_info *map, int on)
0300 {
0301 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
0302 struct pcmcia_device *link = dev->p_dev;
0303
0304 pr_debug("dev = %p on = %d vpp = %d\n\n", dev, on, dev->vpp);
0305 mutex_lock(&pcmcia_vpp_lock);
0306 if (on) {
0307 if (++pcmcia_vpp_refcnt == 1)
0308 pcmcia_fixup_vpp(link, dev->vpp);
0309 } else {
0310 if (--pcmcia_vpp_refcnt == 0)
0311 pcmcia_fixup_vpp(link, 0);
0312 }
0313 mutex_unlock(&pcmcia_vpp_lock);
0314 }
0315
0316
0317 static void pcmciamtd_release(struct pcmcia_device *link)
0318 {
0319 struct pcmciamtd_dev *dev = link->priv;
0320
0321 pr_debug("link = 0x%p\n", link);
0322
0323 if (link->resource[2]->end) {
0324 if(dev->win_base) {
0325 iounmap(dev->win_base);
0326 dev->win_base = NULL;
0327 }
0328 }
0329 pcmcia_disable_device(link);
0330 }
0331
0332
0333 static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
0334 tuple_t *tuple,
0335 void *priv_data)
0336 {
0337 cisparse_t parse;
0338
0339 if (!pcmcia_parse_tuple(tuple, &parse)) {
0340 cistpl_format_t *t = &parse.format;
0341 (void)t;
0342 pr_debug("Format type: %u, Error Detection: %u, offset = %u, length =%u\n",
0343 t->type, t->edc, t->offset, t->length);
0344 }
0345 return -ENOSPC;
0346 }
0347
0348 static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev,
0349 tuple_t *tuple,
0350 void *priv_data)
0351 {
0352 cisparse_t parse;
0353 int i;
0354
0355 if (!pcmcia_parse_tuple(tuple, &parse)) {
0356 cistpl_jedec_t *t = &parse.jedec;
0357 for (i = 0; i < t->nid; i++)
0358 pr_debug("JEDEC: 0x%02x 0x%02x\n",
0359 t->id[i].mfr, t->id[i].info);
0360 }
0361 return -ENOSPC;
0362 }
0363
0364 static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
0365 tuple_t *tuple,
0366 void *priv_data)
0367 {
0368 struct pcmciamtd_dev *dev = priv_data;
0369 cisparse_t parse;
0370 cistpl_device_t *t = &parse.device;
0371 int i;
0372
0373 if (pcmcia_parse_tuple(tuple, &parse))
0374 return -EINVAL;
0375
0376 pr_debug("Common memory:\n");
0377 dev->pcmcia_map.size = t->dev[0].size;
0378
0379 for (i = 0; i < t->ndev; i++) {
0380 pr_debug("Region %d, type = %u\n", i, t->dev[i].type);
0381 pr_debug("Region %d, wp = %u\n", i, t->dev[i].wp);
0382 pr_debug("Region %d, speed = %u ns\n", i, t->dev[i].speed);
0383 pr_debug("Region %d, size = %u bytes\n", i, t->dev[i].size);
0384 }
0385 return 0;
0386 }
0387
0388 static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev,
0389 tuple_t *tuple,
0390 void *priv_data)
0391 {
0392 struct pcmciamtd_dev *dev = priv_data;
0393 cisparse_t parse;
0394 cistpl_device_geo_t *t = &parse.device_geo;
0395 int i;
0396
0397 if (pcmcia_parse_tuple(tuple, &parse))
0398 return -EINVAL;
0399
0400 dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
0401
0402 for (i = 0; i < t->ngeo; i++) {
0403 pr_debug("region: %d bankwidth = %u\n", i, t->geo[i].buswidth);
0404 pr_debug("region: %d erase_block = %u\n", i, t->geo[i].erase_block);
0405 pr_debug("region: %d read_block = %u\n", i, t->geo[i].read_block);
0406 pr_debug("region: %d write_block = %u\n", i, t->geo[i].write_block);
0407 pr_debug("region: %d partition = %u\n", i, t->geo[i].partition);
0408 pr_debug("region: %d interleave = %u\n", i, t->geo[i].interleave);
0409 }
0410 return 0;
0411 }
0412
0413
0414 static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev, int *new_name)
0415 {
0416 int i;
0417
0418 if (p_dev->prod_id[0]) {
0419 dev->mtd_name[0] = '\0';
0420 for (i = 0; i < 4; i++) {
0421 if (i)
0422 strcat(dev->mtd_name, " ");
0423 if (p_dev->prod_id[i])
0424 strcat(dev->mtd_name, p_dev->prod_id[i]);
0425 }
0426 pr_debug("Found name: %s\n", dev->mtd_name);
0427 }
0428
0429 pcmcia_loop_tuple(p_dev, CISTPL_FORMAT, pcmciamtd_cistpl_format, NULL);
0430 pcmcia_loop_tuple(p_dev, CISTPL_JEDEC_C, pcmciamtd_cistpl_jedec, NULL);
0431 pcmcia_loop_tuple(p_dev, CISTPL_DEVICE, pcmciamtd_cistpl_device, dev);
0432 pcmcia_loop_tuple(p_dev, CISTPL_DEVICE_GEO, pcmciamtd_cistpl_geo, dev);
0433
0434 if(!dev->pcmcia_map.size)
0435 dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
0436
0437 if(!dev->pcmcia_map.bankwidth)
0438 dev->pcmcia_map.bankwidth = 2;
0439
0440 if(force_size) {
0441 dev->pcmcia_map.size = force_size << 20;
0442 pr_debug("size forced to %dM\n", force_size);
0443 }
0444
0445 if(bankwidth) {
0446 dev->pcmcia_map.bankwidth = bankwidth;
0447 pr_debug("bankwidth forced to %d\n", bankwidth);
0448 }
0449
0450 dev->pcmcia_map.name = dev->mtd_name;
0451 if(!dev->mtd_name[0]) {
0452 strcpy(dev->mtd_name, "PCMCIA Memory card");
0453 *new_name = 1;
0454 }
0455
0456 pr_debug("Device: Size: %lu Width:%d Name: %s\n",
0457 dev->pcmcia_map.size,
0458 dev->pcmcia_map.bankwidth << 3, dev->mtd_name);
0459 }
0460
0461
0462 static int pcmciamtd_config(struct pcmcia_device *link)
0463 {
0464 struct pcmciamtd_dev *dev = link->priv;
0465 struct mtd_info *mtd = NULL;
0466 int ret;
0467 int i, j = 0;
0468 static char *probes[] = { "jedec_probe", "cfi_probe" };
0469 int new_name = 0;
0470
0471 pr_debug("link=0x%p\n", link);
0472
0473 card_settings(dev, link, &new_name);
0474
0475 dev->pcmcia_map.phys = NO_XIP;
0476 dev->pcmcia_map.copy_from = pcmcia_copy_from_remap;
0477 dev->pcmcia_map.copy_to = pcmcia_copy_to_remap;
0478 if (dev->pcmcia_map.bankwidth == 1) {
0479 dev->pcmcia_map.read = pcmcia_read8_remap;
0480 dev->pcmcia_map.write = pcmcia_write8_remap;
0481 } else {
0482 dev->pcmcia_map.read = pcmcia_read16_remap;
0483 dev->pcmcia_map.write = pcmcia_write16_remap;
0484 }
0485 if(setvpp == 1)
0486 dev->pcmcia_map.set_vpp = pcmciamtd_set_vpp;
0487
0488
0489
0490
0491
0492
0493
0494 link->resource[2]->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE;
0495 link->resource[2]->flags |= (dev->pcmcia_map.bankwidth == 1) ?
0496 WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16;
0497 link->resource[2]->start = 0;
0498 link->resource[2]->end = (force_size) ? force_size << 20 :
0499 MAX_PCMCIA_ADDR;
0500 dev->win_size = 0;
0501
0502 do {
0503 int ret;
0504 pr_debug("requesting window with size = %luKiB memspeed = %d\n",
0505 (unsigned long) resource_size(link->resource[2]) >> 10,
0506 mem_speed);
0507 ret = pcmcia_request_window(link, link->resource[2], mem_speed);
0508 pr_debug("ret = %d dev->win_size = %d\n", ret, dev->win_size);
0509 if(ret) {
0510 j++;
0511 link->resource[2]->start = 0;
0512 link->resource[2]->end = (force_size) ?
0513 force_size << 20 : MAX_PCMCIA_ADDR;
0514 link->resource[2]->end >>= j;
0515 } else {
0516 pr_debug("Got window of size %luKiB\n", (unsigned long)
0517 resource_size(link->resource[2]) >> 10);
0518 dev->win_size = resource_size(link->resource[2]);
0519 break;
0520 }
0521 } while (link->resource[2]->end >= 0x1000);
0522
0523 pr_debug("dev->win_size = %d\n", dev->win_size);
0524
0525 if(!dev->win_size) {
0526 dev_err(&dev->p_dev->dev, "Cannot allocate memory window\n");
0527 pcmciamtd_release(link);
0528 return -ENODEV;
0529 }
0530 pr_debug("Allocated a window of %dKiB\n", dev->win_size >> 10);
0531
0532
0533 dev->win_base = ioremap(link->resource[2]->start,
0534 resource_size(link->resource[2]));
0535 if(!dev->win_base) {
0536 dev_err(&dev->p_dev->dev, "ioremap(%pR) failed\n",
0537 link->resource[2]);
0538 pcmciamtd_release(link);
0539 return -ENODEV;
0540 }
0541 pr_debug("mapped window dev = %p @ %pR, base = %p\n",
0542 dev, link->resource[2], dev->win_base);
0543
0544 dev->offset = 0;
0545 dev->pcmcia_map.map_priv_1 = (unsigned long)dev;
0546 dev->pcmcia_map.map_priv_2 = (unsigned long)link->resource[2];
0547
0548 dev->vpp = (vpp) ? vpp : link->socket->socket.Vpp;
0549 if(setvpp == 2) {
0550 link->vpp = dev->vpp;
0551 } else {
0552 link->vpp = 0;
0553 }
0554
0555 link->config_index = 0;
0556 pr_debug("Setting Configuration\n");
0557 ret = pcmcia_enable_device(link);
0558 if (ret != 0) {
0559 if (dev->win_base) {
0560 iounmap(dev->win_base);
0561 dev->win_base = NULL;
0562 }
0563 return -ENODEV;
0564 }
0565
0566 if(mem_type == 1) {
0567 mtd = do_map_probe("map_ram", &dev->pcmcia_map);
0568 } else if(mem_type == 2) {
0569 mtd = do_map_probe("map_rom", &dev->pcmcia_map);
0570 } else {
0571 for(i = 0; i < ARRAY_SIZE(probes); i++) {
0572 pr_debug("Trying %s\n", probes[i]);
0573 mtd = do_map_probe(probes[i], &dev->pcmcia_map);
0574 if(mtd)
0575 break;
0576
0577 pr_debug("FAILED: %s\n", probes[i]);
0578 }
0579 }
0580
0581 if(!mtd) {
0582 pr_debug("Can not find an MTD\n");
0583 pcmciamtd_release(link);
0584 return -ENODEV;
0585 }
0586
0587 dev->mtd_info = mtd;
0588 mtd->owner = THIS_MODULE;
0589
0590 if(new_name) {
0591 int size = 0;
0592 char unit = ' ';
0593
0594
0595
0596 if(mtd->size < 1048576) {
0597 size = mtd->size >> 10;
0598 unit = 'K';
0599 } else {
0600 size = mtd->size >> 20;
0601 unit = 'M';
0602 }
0603 snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%ciB %s", size, unit, "PCMCIA Memory card");
0604 }
0605
0606
0607
0608 if(mtd->size <= dev->win_size) {
0609 pr_debug("Using non remapping memory functions\n");
0610 dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base;
0611 if (dev->pcmcia_map.bankwidth == 1) {
0612 dev->pcmcia_map.read = pcmcia_read8;
0613 dev->pcmcia_map.write = pcmcia_write8;
0614 } else {
0615 dev->pcmcia_map.read = pcmcia_read16;
0616 dev->pcmcia_map.write = pcmcia_write16;
0617 }
0618 dev->pcmcia_map.copy_from = pcmcia_copy_from;
0619 dev->pcmcia_map.copy_to = pcmcia_copy_to;
0620 }
0621
0622 if (mtd_device_register(mtd, NULL, 0)) {
0623 map_destroy(mtd);
0624 dev->mtd_info = NULL;
0625 dev_err(&dev->p_dev->dev,
0626 "Could not register the MTD device\n");
0627 pcmciamtd_release(link);
0628 return -ENODEV;
0629 }
0630 dev_info(&dev->p_dev->dev, "mtd%d: %s\n", mtd->index, mtd->name);
0631 return 0;
0632 }
0633
0634
0635 static int pcmciamtd_suspend(struct pcmcia_device *dev)
0636 {
0637 pr_debug("EVENT_PM_RESUME\n");
0638
0639
0640
0641 return 0;
0642 }
0643
0644 static int pcmciamtd_resume(struct pcmcia_device *dev)
0645 {
0646 pr_debug("EVENT_PM_SUSPEND\n");
0647
0648
0649
0650 return 0;
0651 }
0652
0653
0654 static void pcmciamtd_detach(struct pcmcia_device *link)
0655 {
0656 struct pcmciamtd_dev *dev = link->priv;
0657
0658 pr_debug("link=0x%p\n", link);
0659
0660 if(dev->mtd_info) {
0661 mtd_device_unregister(dev->mtd_info);
0662 dev_info(&dev->p_dev->dev, "mtd%d: Removing\n",
0663 dev->mtd_info->index);
0664 map_destroy(dev->mtd_info);
0665 }
0666
0667 pcmciamtd_release(link);
0668 }
0669
0670
0671 static int pcmciamtd_probe(struct pcmcia_device *link)
0672 {
0673 struct pcmciamtd_dev *dev;
0674
0675
0676 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
0677 if (!dev) return -ENOMEM;
0678 pr_debug("dev=0x%p\n", dev);
0679
0680 dev->p_dev = link;
0681 link->priv = dev;
0682
0683 return pcmciamtd_config(link);
0684 }
0685
0686 static const struct pcmcia_device_id pcmciamtd_ids[] = {
0687 PCMCIA_DEVICE_FUNC_ID(1),
0688 PCMCIA_DEVICE_PROD_ID123("IO DATA", "PCS-2M", "2MB SRAM", 0x547e66dc, 0x1fed36cd, 0x36eadd21),
0689 PCMCIA_DEVICE_PROD_ID12("IBM", "2MB SRAM", 0xb569a6e5, 0x36eadd21),
0690 PCMCIA_DEVICE_PROD_ID12("IBM", "4MB FLASH", 0xb569a6e5, 0x8bc54d2a),
0691 PCMCIA_DEVICE_PROD_ID12("IBM", "8MB FLASH", 0xb569a6e5, 0x6df1be3e),
0692 PCMCIA_DEVICE_PROD_ID12("Intel", "S2E20SW", 0x816cc815, 0xd14c9dcf),
0693 PCMCIA_DEVICE_PROD_ID12("Intel", "S2E8 SW", 0x816cc815, 0xa2d7dedb),
0694 PCMCIA_DEVICE_PROD_ID12("intel", "SERIES2-02 ", 0x40ade711, 0x145cea5c),
0695 PCMCIA_DEVICE_PROD_ID12("intel", "SERIES2-04 ", 0x40ade711, 0x42064dda),
0696 PCMCIA_DEVICE_PROD_ID12("intel", "SERIES2-20 ", 0x40ade711, 0x25ee5cb0),
0697 PCMCIA_DEVICE_PROD_ID12("intel", "VALUE SERIES 100 ", 0x40ade711, 0xdf8506d8),
0698 PCMCIA_DEVICE_PROD_ID12("KINGMAX TECHNOLOGY INC.", "SRAM 256K Bytes", 0x54d0c69c, 0xad12c29c),
0699 PCMCIA_DEVICE_PROD_ID12("Maxtor", "MAXFL MobileMax Flash Memory Card", 0xb68968c8, 0x2dfb47b0),
0700 PCMCIA_DEVICE_PROD_ID123("M-Systems", "M-SYS Flash Memory Card", "(c) M-Systems", 0x7ed2ad87, 0x675dc3fb, 0x7aef3965),
0701 PCMCIA_DEVICE_PROD_ID12("PRETEC", " 2MB SRAM CARD", 0xebf91155, 0x805360ca),
0702 PCMCIA_DEVICE_PROD_ID12("PRETEC", " 4MB SRAM CARD", 0xebf91155, 0x20b6bf17),
0703 PCMCIA_DEVICE_PROD_ID12("SEIKO EPSON", "WWB101EN20", 0xf9876baf, 0xad0b207b),
0704 PCMCIA_DEVICE_PROD_ID12("SEIKO EPSON", "WWB513EN20", 0xf9876baf, 0xe8d884ad),
0705 PCMCIA_DEVICE_PROD_ID12("SMART Modular Technologies", " 4MB FLASH Card", 0x96fd8277, 0x737a5b05),
0706 PCMCIA_DEVICE_PROD_ID12("Starfish, Inc.", "REX-3000", 0x05ddca47, 0xe7d67bca),
0707 PCMCIA_DEVICE_PROD_ID12("Starfish, Inc.", "REX-4100", 0x05ddca47, 0x7bc32944),
0708
0709
0710 #ifdef CONFIG_MTD_PCMCIA_ANONYMOUS
0711 { .match_flags = PCMCIA_DEV_ID_MATCH_ANONYMOUS, },
0712 #endif
0713 PCMCIA_DEVICE_NULL
0714 };
0715 MODULE_DEVICE_TABLE(pcmcia, pcmciamtd_ids);
0716
0717 static struct pcmcia_driver pcmciamtd_driver = {
0718 .name = "pcmciamtd",
0719 .probe = pcmciamtd_probe,
0720 .remove = pcmciamtd_detach,
0721 .owner = THIS_MODULE,
0722 .id_table = pcmciamtd_ids,
0723 .suspend = pcmciamtd_suspend,
0724 .resume = pcmciamtd_resume,
0725 };
0726
0727
0728 static int __init init_pcmciamtd(void)
0729 {
0730 if(bankwidth && bankwidth != 1 && bankwidth != 2) {
0731 info("bad bankwidth (%d), using default", bankwidth);
0732 bankwidth = 2;
0733 }
0734 if(force_size && (force_size < 1 || force_size > 64)) {
0735 info("bad force_size (%d), using default", force_size);
0736 force_size = 0;
0737 }
0738 if(mem_type && mem_type != 1 && mem_type != 2) {
0739 info("bad mem_type (%d), using default", mem_type);
0740 mem_type = 0;
0741 }
0742 return pcmcia_register_driver(&pcmciamtd_driver);
0743 }
0744
0745
0746 static void __exit exit_pcmciamtd(void)
0747 {
0748 pr_debug(DRIVER_DESC " unloading");
0749 pcmcia_unregister_driver(&pcmciamtd_driver);
0750 }
0751
0752 module_init(init_pcmciamtd);
0753 module_exit(exit_pcmciamtd);