ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/pcmciamtd.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 * $Id: pcmciamtd.c,v 1.55 2005/11/07 11:14:28 gleixner Exp $
3 *
4 * pcmciamtd.c - MTD driver for PCMCIA flash memory cards
5 *
6 * Author: Simon Evans <spse@secret.org.uk>
7 *
8 * Copyright (C) 2002 Simon Evans
9 *
10 * Licence: GPL
11 *
12 */
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/timer.h>
17 #include <linux/init.h>
18 #include <asm/io.h>
19 #include <asm/system.h>
21 #include <pcmcia/cs_types.h>
22 #include <pcmcia/cs.h>
23 #include <pcmcia/cistpl.h>
24 #include <pcmcia/ds.h>
26 #include <linux/mtd/map.h>
27 #include <linux/mtd/mtd.h>
29 #ifdef CONFIG_MTD_DEBUG
30 static int debug = CONFIG_MTD_DEBUG_VERBOSE;
31 module_param(debug, int, 0);
32 MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy");
33 #undef DEBUG
34 #define DEBUG(n, format, arg...) \
35 if (n <= debug) { \
36 printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \
37 }
39 #else
40 #undef DEBUG
41 #define DEBUG(n, arg...)
42 static const int debug = 0;
43 #endif
45 #define err(format, arg...) printk(KERN_ERR "pcmciamtd: " format "\n" , ## arg)
46 #define info(format, arg...) printk(KERN_INFO "pcmciamtd: " format "\n" , ## arg)
47 #define warn(format, arg...) printk(KERN_WARNING "pcmciamtd: " format "\n" , ## arg)
50 #define DRIVER_DESC "PCMCIA Flash memory card driver"
51 #define DRIVER_VERSION "$Revision: 1.55 $"
53 /* Size of the PCMCIA address space: 26 bits = 64 MB */
54 #define MAX_PCMCIA_ADDR 0x4000000
56 struct pcmciamtd_dev {
57 struct pcmcia_device *p_dev;
58 dev_node_t node; /* device node */
59 caddr_t win_base; /* ioremapped address of PCMCIA window */
60 unsigned int win_size; /* size of window */
61 unsigned int offset; /* offset into card the window currently points at */
62 struct map_info pcmcia_map;
63 struct mtd_info *mtd_info;
64 int vpp;
65 char mtd_name[sizeof(struct cistpl_vers_1_t)];
66 };
69 /* Module parameters */
71 /* 2 = do 16-bit transfers, 1 = do 8-bit transfers */
72 static int bankwidth = 2;
74 /* Speed of memory accesses, in ns */
75 static int mem_speed;
77 /* Force the size of an SRAM card */
78 static int force_size;
80 /* Force Vpp */
81 static int vpp;
83 /* Set Vpp */
84 static int setvpp;
86 /* Force card to be treated as FLASH, ROM or RAM */
87 static int mem_type;
89 MODULE_LICENSE("GPL");
90 MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
91 MODULE_DESCRIPTION(DRIVER_DESC);
92 module_param(bankwidth, int, 0);
93 MODULE_PARM_DESC(bankwidth, "Set bankwidth (1=8 bit, 2=16 bit, default=2)");
94 module_param(mem_speed, int, 0);
95 MODULE_PARM_DESC(mem_speed, "Set memory access speed in ns");
96 module_param(force_size, int, 0);
97 MODULE_PARM_DESC(force_size, "Force size of card in MiB (1-64)");
98 module_param(setvpp, int, 0);
99 MODULE_PARM_DESC(setvpp, "Set Vpp (0=Never, 1=On writes, 2=Always on, default=0)");
100 module_param(vpp, int, 0);
101 MODULE_PARM_DESC(vpp, "Vpp value in 1/10ths eg 33=3.3V 120=12V (Dangerous)");
102 module_param(mem_type, int, 0);
103 MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)");
106 /* read/write{8,16} copy_{from,to} routines with window remapping to access whole card */
107 static caddr_t remap_window(struct map_info *map, unsigned long to)
108 {
109 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
110 window_handle_t win = (window_handle_t)map->map_priv_2;
111 memreq_t mrq;
112 int ret;
114 if (!pcmcia_dev_present(dev->p_dev)) {
115 DEBUG(1, "device removed");
116 return 0;
117 }
119 mrq.CardOffset = to & ~(dev->win_size-1);
120 if(mrq.CardOffset != dev->offset) {
121 DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
122 dev->offset, mrq.CardOffset);
123 mrq.Page = 0;
124 if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) {
125 cs_error(dev->p_dev, MapMemPage, ret);
126 return NULL;
127 }
128 dev->offset = mrq.CardOffset;
129 }
130 return dev->win_base + (to & (dev->win_size-1));
131 }
134 static map_word pcmcia_read8_remap(struct map_info *map, unsigned long ofs)
135 {
136 caddr_t addr;
137 map_word d = {{0}};
139 addr = remap_window(map, ofs);
140 if(!addr)
141 return d;
143 d.x[0] = readb(addr);
144 DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02x", ofs, addr, d.x[0]);
145 return d;
146 }
149 static map_word pcmcia_read16_remap(struct map_info *map, unsigned long ofs)
150 {
151 caddr_t addr;
152 map_word d = {{0}};
154 addr = remap_window(map, ofs);
155 if(!addr)
156 return d;
158 d.x[0] = readw(addr);
159 DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04x", ofs, addr, d.x[0]);
160 return d;
161 }
164 static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long from, ssize_t len)
165 {
166 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
167 unsigned long win_size = dev->win_size;
169 DEBUG(3, "to = %p from = %lu len = %u", to, from, len);
170 while(len) {
171 int toread = win_size - (from & (win_size-1));
172 caddr_t addr;
174 if(toread > len)
175 toread = len;
177 addr = remap_window(map, from);
178 if(!addr)
179 return;
181 DEBUG(4, "memcpy from %p to %p len = %d", addr, to, toread);
182 memcpy_fromio(to, addr, toread);
183 len -= toread;
184 to += toread;
185 from += toread;
186 }
187 }
190 static void pcmcia_write8_remap(struct map_info *map, map_word d, unsigned long adr)
191 {
192 caddr_t addr = remap_window(map, adr);
194 if(!addr)
195 return;
197 DEBUG(3, "adr = 0x%08lx (%p) data = 0x%02x", adr, addr, d.x[0]);
198 writeb(d.x[0], addr);
199 }
202 static void pcmcia_write16_remap(struct map_info *map, map_word d, unsigned long adr)
203 {
204 caddr_t addr = remap_window(map, adr);
205 if(!addr)
206 return;
208 DEBUG(3, "adr = 0x%08lx (%p) data = 0x%04x", adr, addr, d.x[0]);
209 writew(d.x[0], addr);
210 }
213 static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const void *from, ssize_t len)
214 {
215 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
216 unsigned long win_size = dev->win_size;
218 DEBUG(3, "to = %lu from = %p len = %u", to, from, len);
219 while(len) {
220 int towrite = win_size - (to & (win_size-1));
221 caddr_t addr;
223 if(towrite > len)
224 towrite = len;
226 addr = remap_window(map, to);
227 if(!addr)
228 return;
230 DEBUG(4, "memcpy from %p to %p len = %d", from, addr, towrite);
231 memcpy_toio(addr, from, towrite);
232 len -= towrite;
233 to += towrite;
234 from += towrite;
235 }
236 }
239 /* read/write{8,16} copy_{from,to} routines with direct access */
241 #define DEV_REMOVED(x) (!(pcmcia_dev_present(((struct pcmciamtd_dev *)map->map_priv_1)->p_dev)))
243 static map_word pcmcia_read8(struct map_info *map, unsigned long ofs)
244 {
245 caddr_t win_base = (caddr_t)map->map_priv_2;
246 map_word d = {{0}};
248 if(DEV_REMOVED(map))
249 return d;
251 d.x[0] = readb(win_base + ofs);
252 DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02x", ofs, win_base + ofs, d.x[0]);
253 return d;
254 }
257 static map_word pcmcia_read16(struct map_info *map, unsigned long ofs)
258 {
259 caddr_t win_base = (caddr_t)map->map_priv_2;
260 map_word d = {{0}};
262 if(DEV_REMOVED(map))
263 return d;
265 d.x[0] = readw(win_base + ofs);
266 DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04x", ofs, win_base + ofs, d.x[0]);
267 return d;
268 }
271 static void pcmcia_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
272 {
273 caddr_t win_base = (caddr_t)map->map_priv_2;
275 if(DEV_REMOVED(map))
276 return;
278 DEBUG(3, "to = %p from = %lu len = %u", to, from, len);
279 memcpy_fromio(to, win_base + from, len);
280 }
283 static void pcmcia_write8(struct map_info *map, u8 d, unsigned long adr)
284 {
285 caddr_t win_base = (caddr_t)map->map_priv_2;
287 if(DEV_REMOVED(map))
288 return;
290 DEBUG(3, "adr = 0x%08lx (%p) data = 0x%02x", adr, win_base + adr, d);
291 writeb(d, win_base + adr);
292 }
295 static void pcmcia_write16(struct map_info *map, u16 d, unsigned long adr)
296 {
297 caddr_t win_base = (caddr_t)map->map_priv_2;
299 if(DEV_REMOVED(map))
300 return;
302 DEBUG(3, "adr = 0x%08lx (%p) data = 0x%04x", adr, win_base + adr, d);
303 writew(d, win_base + adr);
304 }
307 static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
308 {
309 caddr_t win_base = (caddr_t)map->map_priv_2;
311 if(DEV_REMOVED(map))
312 return;
314 DEBUG(3, "to = %lu from = %p len = %u", to, from, len);
315 memcpy_toio(win_base + to, from, len);
316 }
319 static void pcmciamtd_set_vpp(struct map_info *map, int on)
320 {
321 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
322 struct pcmcia_device *link = dev->p_dev;
323 modconf_t mod;
324 int ret;
326 mod.Attributes = CONF_VPP1_CHANGE_VALID | CONF_VPP2_CHANGE_VALID;
327 mod.Vcc = 0;
328 mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0;
330 DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
331 ret = pcmcia_modify_configuration(link, &mod);
332 if(ret != CS_SUCCESS) {
333 cs_error(link, ModifyConfiguration, ret);
334 }
335 }
338 /* After a card is removed, pcmciamtd_release() will unregister the
339 * device, and release the PCMCIA configuration. If the device is
340 * still open, this will be postponed until it is closed.
341 */
343 static void pcmciamtd_release(struct pcmcia_device *link)
344 {
345 struct pcmciamtd_dev *dev = link->priv;
347 DEBUG(3, "link = 0x%p", link);
349 if (link->win) {
350 if(dev->win_base) {
351 iounmap(dev->win_base);
352 dev->win_base = NULL;
353 }
354 pcmcia_release_window(link->win);
355 }
356 pcmcia_disable_device(link);
357 }
360 static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
361 {
362 int rc;
363 tuple_t tuple;
364 cisparse_t parse;
365 u_char buf[64];
367 tuple.Attributes = 0;
368 tuple.TupleData = (cisdata_t *)buf;
369 tuple.TupleDataMax = sizeof(buf);
370 tuple.TupleOffset = 0;
371 tuple.DesiredTuple = RETURN_FIRST_TUPLE;
373 rc = pcmcia_get_first_tuple(link, &tuple);
374 while(rc == CS_SUCCESS) {
375 rc = pcmcia_get_tuple_data(link, &tuple);
376 if(rc != CS_SUCCESS) {
377 cs_error(link, GetTupleData, rc);
378 break;
379 }
380 rc = pcmcia_parse_tuple(link, &tuple, &parse);
381 if(rc != CS_SUCCESS) {
382 cs_error(link, ParseTuple, rc);
383 break;
384 }
386 switch(tuple.TupleCode) {
387 case CISTPL_FORMAT: {
388 cistpl_format_t *t = &parse.format;
389 (void)t; /* Shut up, gcc */
390 DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
391 t->type, t->edc, t->offset, t->length);
392 break;
394 }
396 case CISTPL_DEVICE: {
397 cistpl_device_t *t = &parse.device;
398 int i;
399 DEBUG(2, "Common memory:");
400 dev->pcmcia_map.size = t->dev[0].size;
401 for(i = 0; i < t->ndev; i++) {
402 DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
403 DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
404 DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
405 DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
406 }
407 break;
408 }
410 case CISTPL_VERS_1: {
411 cistpl_vers_1_t *t = &parse.version_1;
412 int i;
413 if(t->ns) {
414 dev->mtd_name[0] = '\0';
415 for(i = 0; i < t->ns; i++) {
416 if(i)
417 strcat(dev->mtd_name, " ");
418 strcat(dev->mtd_name, t->str+t->ofs[i]);
419 }
420 }
421 DEBUG(2, "Found name: %s", dev->mtd_name);
422 break;
423 }
425 case CISTPL_JEDEC_C: {
426 cistpl_jedec_t *t = &parse.jedec;
427 int i;
428 for(i = 0; i < t->nid; i++) {
429 DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
430 }
431 break;
432 }
434 case CISTPL_DEVICE_GEO: {
435 cistpl_device_geo_t *t = &parse.device_geo;
436 int i;
437 dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
438 for(i = 0; i < t->ngeo; i++) {
439 DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
440 DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
441 DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
442 DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
443 DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
444 DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
445 }
446 break;
447 }
449 default:
450 DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
451 }
453 rc = pcmcia_get_next_tuple(link, &tuple);
454 }
455 if(!dev->pcmcia_map.size)
456 dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
458 if(!dev->pcmcia_map.bankwidth)
459 dev->pcmcia_map.bankwidth = 2;
461 if(force_size) {
462 dev->pcmcia_map.size = force_size << 20;
463 DEBUG(2, "size forced to %dM", force_size);
464 }
466 if(bankwidth) {
467 dev->pcmcia_map.bankwidth = bankwidth;
468 DEBUG(2, "bankwidth forced to %d", bankwidth);
469 }
471 dev->pcmcia_map.name = dev->mtd_name;
472 if(!dev->mtd_name[0]) {
473 strcpy(dev->mtd_name, "PCMCIA Memory card");
474 *new_name = 1;
475 }
477 DEBUG(1, "Device: Size: %lu Width:%d Name: %s",
478 dev->pcmcia_map.size, dev->pcmcia_map.bankwidth << 3, dev->mtd_name);
479 }
482 /* pcmciamtd_config() is scheduled to run after a CARD_INSERTION event
483 * is received, to configure the PCMCIA socket, and to make the
484 * MTD device available to the system.
485 */
487 #define CS_CHECK(fn, ret) \
488 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
490 static int pcmciamtd_config(struct pcmcia_device *link)
491 {
492 struct pcmciamtd_dev *dev = link->priv;
493 struct mtd_info *mtd = NULL;
494 cs_status_t status;
495 win_req_t req;
496 int last_ret = 0, last_fn = 0;
497 int ret;
498 int i;
499 config_info_t t;
500 static char *probes[] = { "jedec_probe", "cfi_probe" };
501 cisinfo_t cisinfo;
502 int new_name = 0;
504 DEBUG(3, "link=0x%p", link);
506 DEBUG(2, "Validating CIS");
507 ret = pcmcia_validate_cis(link, &cisinfo);
508 if(ret != CS_SUCCESS) {
509 cs_error(link, GetTupleData, ret);
510 } else {
511 DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains);
512 }
514 card_settings(dev, link, &new_name);
516 dev->pcmcia_map.phys = NO_XIP;
517 dev->pcmcia_map.copy_from = pcmcia_copy_from_remap;
518 dev->pcmcia_map.copy_to = pcmcia_copy_to_remap;
519 if (dev->pcmcia_map.bankwidth == 1) {
520 dev->pcmcia_map.read = pcmcia_read8_remap;
521 dev->pcmcia_map.write = pcmcia_write8_remap;
522 } else {
523 dev->pcmcia_map.read = pcmcia_read16_remap;
524 dev->pcmcia_map.write = pcmcia_write16_remap;
525 }
526 if(setvpp == 1)
527 dev->pcmcia_map.set_vpp = pcmciamtd_set_vpp;
529 /* Request a memory window for PCMCIA. Some architeures can map windows upto the maximum
530 that PCMCIA can support (64MiB) - this is ideal and we aim for a window the size of the
531 whole card - otherwise we try smaller windows until we succeed */
533 req.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE;
534 req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16;
535 req.Base = 0;
536 req.AccessSpeed = mem_speed;
537 link->win = (window_handle_t)link;
538 req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR;
539 dev->win_size = 0;
541 do {
542 int ret;
543 DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
544 req.Size >> 10, req.AccessSpeed);
545 ret = pcmcia_request_window(&link, &req, &link->win);
546 DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
547 if(ret) {
548 req.Size >>= 1;
549 } else {
550 DEBUG(2, "Got window of size %dKiB", req.Size >> 10);
551 dev->win_size = req.Size;
552 break;
553 }
554 } while(req.Size >= 0x1000);
556 DEBUG(2, "dev->win_size = %d", dev->win_size);
558 if(!dev->win_size) {
559 err("Cant allocate memory window");
560 pcmciamtd_release(link);
561 return -ENODEV;
562 }
563 DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
565 /* Get write protect status */
566 CS_CHECK(GetStatus, pcmcia_get_status(link, &status));
567 DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx",
568 status.CardState, (unsigned long)link->win);
569 dev->win_base = ioremap(req.Base, req.Size);
570 if(!dev->win_base) {
571 err("ioremap(%lu, %u) failed", req.Base, req.Size);
572 pcmciamtd_release(link);
573 return -ENODEV;
574 }
575 DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x",
576 dev, req.Base, dev->win_base, req.Size);
578 dev->offset = 0;
579 dev->pcmcia_map.map_priv_1 = (unsigned long)dev;
580 dev->pcmcia_map.map_priv_2 = (unsigned long)link->win;
582 DEBUG(2, "Getting configuration");
583 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &t));
584 DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2);
585 dev->vpp = (vpp) ? vpp : t.Vpp1;
586 link->conf.Attributes = 0;
587 if(setvpp == 2) {
588 link->conf.Vpp = dev->vpp;
589 } else {
590 link->conf.Vpp = 0;
591 }
593 link->conf.IntType = INT_MEMORY;
594 link->conf.ConfigBase = t.ConfigBase;
595 link->conf.Status = t.Status;
596 link->conf.Pin = t.Pin;
597 link->conf.Copy = t.Copy;
598 link->conf.ExtStatus = t.ExtStatus;
599 link->conf.ConfigIndex = 0;
600 link->conf.Present = t.Present;
601 DEBUG(2, "Setting Configuration");
602 ret = pcmcia_request_configuration(link, &link->conf);
603 if(ret != CS_SUCCESS) {
604 cs_error(link, RequestConfiguration, ret);
605 return -ENODEV;
606 }
608 if(mem_type == 1) {
609 mtd = do_map_probe("map_ram", &dev->pcmcia_map);
610 } else if(mem_type == 2) {
611 mtd = do_map_probe("map_rom", &dev->pcmcia_map);
612 } else {
613 for(i = 0; i < ARRAY_SIZE(probes); i++) {
614 DEBUG(1, "Trying %s", probes[i]);
615 mtd = do_map_probe(probes[i], &dev->pcmcia_map);
616 if(mtd)
617 break;
619 DEBUG(1, "FAILED: %s", probes[i]);
620 }
621 }
623 if(!mtd) {
624 DEBUG(1, "Cant find an MTD");
625 pcmciamtd_release(link);
626 return -ENODEV;
627 }
629 dev->mtd_info = mtd;
630 mtd->owner = THIS_MODULE;
632 if(new_name) {
633 int size = 0;
634 char unit = ' ';
635 /* Since we are using a default name, make it better by adding in the
636 size */
637 if(mtd->size < 1048576) { /* <1MiB in size, show size in KiB */
638 size = mtd->size >> 10;
639 unit = 'K';
640 } else {
641 size = mtd->size >> 20;
642 unit = 'M';
643 }
644 snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%ciB %s", size, unit, "PCMCIA Memory card");
645 }
647 /* If the memory found is fits completely into the mapped PCMCIA window,
648 use the faster non-remapping read/write functions */
649 if(mtd->size <= dev->win_size) {
650 DEBUG(1, "Using non remapping memory functions");
651 dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base;
652 if (dev->pcmcia_map.bankwidth == 1) {
653 dev->pcmcia_map.read = pcmcia_read8;
654 dev->pcmcia_map.write = pcmcia_write8;
655 } else {
656 dev->pcmcia_map.read = pcmcia_read16;
657 dev->pcmcia_map.write = pcmcia_write16;
658 }
659 dev->pcmcia_map.copy_from = pcmcia_copy_from;
660 dev->pcmcia_map.copy_to = pcmcia_copy_to;
661 }
663 if(add_mtd_device(mtd)) {
664 map_destroy(mtd);
665 dev->mtd_info = NULL;
666 err("Couldnt register MTD device");
667 pcmciamtd_release(link);
668 return -ENODEV;
669 }
670 snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index);
671 info("mtd%d: %s", mtd->index, mtd->name);
672 link->dev_node = &dev->node;
673 return 0;
675 cs_failed:
676 cs_error(link, last_fn, last_ret);
677 err("CS Error, exiting");
678 pcmciamtd_release(link);
679 return -ENODEV;
680 }
683 static int pcmciamtd_suspend(struct pcmcia_device *dev)
684 {
685 DEBUG(2, "EVENT_PM_RESUME");
687 /* get_lock(link); */
689 return 0;
690 }
692 static int pcmciamtd_resume(struct pcmcia_device *dev)
693 {
694 DEBUG(2, "EVENT_PM_SUSPEND");
696 /* free_lock(link); */
698 return 0;
699 }
702 /* This deletes a driver "instance". The device is de-registered
703 * with Card Services. If it has been released, all local data
704 * structures are freed. Otherwise, the structures will be freed
705 * when the device is released.
706 */
708 static void pcmciamtd_detach(struct pcmcia_device *link)
709 {
710 struct pcmciamtd_dev *dev = link->priv;
712 DEBUG(3, "link=0x%p", link);
714 if(dev->mtd_info) {
715 del_mtd_device(dev->mtd_info);
716 map_destroy(dev->mtd_info);
717 info("mtd%d: Removed", dev->mtd_info->index);
718 }
720 pcmciamtd_release(link);
721 }
724 /* pcmciamtd_attach() creates an "instance" of the driver, allocating
725 * local data structures for one device. The device is registered
726 * with Card Services.
727 */
729 static int pcmciamtd_probe(struct pcmcia_device *link)
730 {
731 struct pcmciamtd_dev *dev;
733 /* Create new memory card device */
734 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
735 if (!dev) return -ENOMEM;
736 DEBUG(1, "dev=0x%p", dev);
738 memset(dev, 0, sizeof(*dev));
739 dev->p_dev = link;
740 link->priv = dev;
742 link->conf.Attributes = 0;
743 link->conf.IntType = INT_MEMORY;
745 return pcmciamtd_config(link);
746 }
748 static struct pcmcia_device_id pcmciamtd_ids[] = {
749 PCMCIA_DEVICE_FUNC_ID(1),
750 PCMCIA_DEVICE_PROD_ID123("IO DATA", "PCS-2M", "2MB SRAM", 0x547e66dc, 0x1fed36cd, 0x36eadd21),
751 PCMCIA_DEVICE_PROD_ID12("IBM", "2MB SRAM", 0xb569a6e5, 0x36eadd21),
752 PCMCIA_DEVICE_PROD_ID12("IBM", "4MB FLASH", 0xb569a6e5, 0x8bc54d2a),
753 PCMCIA_DEVICE_PROD_ID12("IBM", "8MB FLASH", 0xb569a6e5, 0x6df1be3e),
754 PCMCIA_DEVICE_PROD_ID12("Intel", "S2E20SW", 0x816cc815, 0xd14c9dcf),
755 PCMCIA_DEVICE_PROD_ID12("Intel", "S2E8 SW", 0x816cc815, 0xa2d7dedb),
756 PCMCIA_DEVICE_PROD_ID12("intel", "SERIES2-02 ", 0x40ade711, 0x145cea5c),
757 PCMCIA_DEVICE_PROD_ID12("intel", "SERIES2-04 ", 0x40ade711, 0x42064dda),
758 PCMCIA_DEVICE_PROD_ID12("intel", "SERIES2-20 ", 0x40ade711, 0x25ee5cb0),
759 PCMCIA_DEVICE_PROD_ID12("intel", "VALUE SERIES 100 ", 0x40ade711, 0xdf8506d8),
760 PCMCIA_DEVICE_PROD_ID12("KINGMAX TECHNOLOGY INC.", "SRAM 256K Bytes", 0x54d0c69c, 0xad12c29c),
761 PCMCIA_DEVICE_PROD_ID12("Maxtor", "MAXFL MobileMax Flash Memory Card", 0xb68968c8, 0x2dfb47b0),
762 PCMCIA_DEVICE_PROD_ID12("SEIKO EPSON", "WWB101EN20", 0xf9876baf, 0xad0b207b),
763 PCMCIA_DEVICE_PROD_ID12("SEIKO EPSON", "WWB513EN20", 0xf9876baf, 0xe8d884ad),
764 PCMCIA_DEVICE_PROD_ID12("Starfish, Inc.", "REX-3000", 0x05ddca47, 0xe7d67bca),
765 PCMCIA_DEVICE_PROD_ID12("Starfish, Inc.", "REX-4100", 0x05ddca47, 0x7bc32944),
766 /* the following was commented out in pcmcia-cs-3.2.7 */
767 /* PCMCIA_DEVICE_PROD_ID12("RATOC Systems,Inc.", "SmartMedia ADAPTER PC Card", 0xf4a2fefe, 0x5885b2ae), */
768 #ifdef CONFIG_MTD_PCMCIA_ANONYMOUS
769 { .match_flags = PCMCIA_DEV_ID_MATCH_ANONYMOUS, },
770 #endif
771 PCMCIA_DEVICE_NULL
772 };
773 MODULE_DEVICE_TABLE(pcmcia, pcmciamtd_ids);
775 static struct pcmcia_driver pcmciamtd_driver = {
776 .drv = {
777 .name = "pcmciamtd"
778 },
779 .probe = pcmciamtd_probe,
780 .remove = pcmciamtd_detach,
781 .owner = THIS_MODULE,
782 .id_table = pcmciamtd_ids,
783 .suspend = pcmciamtd_suspend,
784 .resume = pcmciamtd_resume,
785 };
788 static int __init init_pcmciamtd(void)
789 {
790 info(DRIVER_DESC " " DRIVER_VERSION);
792 if(bankwidth && bankwidth != 1 && bankwidth != 2) {
793 info("bad bankwidth (%d), using default", bankwidth);
794 bankwidth = 2;
795 }
796 if(force_size && (force_size < 1 || force_size > 64)) {
797 info("bad force_size (%d), using default", force_size);
798 force_size = 0;
799 }
800 if(mem_type && mem_type != 1 && mem_type != 2) {
801 info("bad mem_type (%d), using default", mem_type);
802 mem_type = 0;
803 }
804 return pcmcia_register_driver(&pcmciamtd_driver);
805 }
808 static void __exit exit_pcmciamtd(void)
809 {
810 DEBUG(1, DRIVER_DESC " unloading");
811 pcmcia_unregister_driver(&pcmciamtd_driver);
812 }
814 module_init(init_pcmciamtd);
815 module_exit(exit_pcmciamtd);