linux-old/drivers/mtd/maps/pcmciamtd.c
<<
>>
Prefs
   1/*
   2 * $Id: pcmciamtd.c,v 1.39 2003/01/06 17:51:38 spse 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 */
  13
  14#include <linux/module.h>
  15#include <linux/slab.h>
  16#include <linux/timer.h>
  17#include <asm/io.h>
  18#include <asm/system.h>
  19
  20#include <pcmcia/version.h>
  21#include <pcmcia/cs_types.h>
  22#include <pcmcia/cs.h>
  23#include <pcmcia/cistpl.h>
  24#include <pcmcia/ds.h>
  25
  26#include <linux/mtd/map.h>
  27
  28#ifdef CONFIG_MTD_DEBUG
  29static int debug = CONFIG_MTD_DEBUG_VERBOSE;
  30MODULE_PARM(debug, "i");
  31MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy");
  32#undef DEBUG
  33#define DEBUG(n, format, arg...) \
  34        if (n <= debug) {        \
  35                printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \
  36        }
  37
  38#else
  39#undef DEBUG
  40#define DEBUG(n, arg...)
  41static const int debug = 0;
  42#endif
  43
  44#define err(format, arg...) printk(KERN_ERR "pcmciamtd: " format "\n" , ## arg)
  45#define info(format, arg...) printk(KERN_INFO "pcmciamtd: " format "\n" , ## arg)
  46#define warn(format, arg...) printk(KERN_WARNING "pcmciamtd: " format "\n" , ## arg)
  47
  48
  49#define DRIVER_DESC     "PCMCIA Flash memory card driver"
  50#define DRIVER_VERSION  "$Revision: 1.39 $"
  51
  52/* Size of the PCMCIA address space: 26 bits = 64 MB */
  53#define MAX_PCMCIA_ADDR 0x4000000
  54
  55struct pcmciamtd_dev {
  56        dev_link_t      link;           /* PCMCIA link */
  57        dev_node_t      node;           /* device node */
  58        caddr_t         win_base;       /* ioremapped address of PCMCIA window */
  59        unsigned int    win_size;       /* size of window */
  60        unsigned int    offset;         /* offset into card the window currently points at */
  61        struct map_info pcmcia_map;
  62        struct mtd_info *mtd_info;
  63        int             vpp;
  64        char            mtd_name[sizeof(struct cistpl_vers_1_t)];
  65};
  66
  67
  68static dev_info_t dev_info = "pcmciamtd";
  69static dev_link_t *dev_list;
  70
  71/* Module parameters */
  72
  73/* 2 = do 16-bit transfers, 1 = do 8-bit transfers */
  74static int buswidth = 2;
  75
  76/* Speed of memory accesses, in ns */
  77static int mem_speed;
  78
  79/* Force the size of an SRAM card */
  80static int force_size;
  81
  82/* Force Vpp */
  83static int vpp;
  84
  85/* Set Vpp */
  86static int setvpp;
  87
  88/* Force card to be treated as FLASH, ROM or RAM */
  89static int mem_type;
  90
  91MODULE_LICENSE("GPL");
  92MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
  93MODULE_DESCRIPTION(DRIVER_DESC);
  94MODULE_PARM(buswidth, "i");
  95MODULE_PARM_DESC(buswidth, "Set buswidth (1=8 bit, 2=16 bit, default=2)");
  96MODULE_PARM(mem_speed, "i");
  97MODULE_PARM_DESC(mem_speed, "Set memory access speed in ns");
  98MODULE_PARM(force_size, "i");
  99MODULE_PARM_DESC(force_size, "Force size of card in MB (1-64)");
 100MODULE_PARM(setvpp, "i");
 101MODULE_PARM_DESC(setvpp, "Set Vpp (0=Never, 1=On writes, 2=Always on, default=0)");
 102MODULE_PARM(vpp, "i");
 103MODULE_PARM_DESC(vpp, "Vpp value in 1/10ths eg 33=3.3V 120=12V (Dangerous)");
 104MODULE_PARM(mem_type, "i");
 105MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)");
 106
 107
 108
 109static inline void cs_error(client_handle_t handle, int func, int ret)
 110{
 111        error_info_t err = { func, ret };
 112        CardServices(ReportError, handle, &err);
 113}
 114
 115
 116/* read/write{8,16} copy_{from,to} routines with window remapping to access whole card */
 117
 118static caddr_t remap_window(struct map_info *map, unsigned long to)
 119{
 120        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
 121        window_handle_t win = (window_handle_t)map->map_priv_2;
 122        memreq_t mrq;
 123        int ret;
 124
 125        if(!(dev->link.state & DEV_PRESENT)) {
 126                DEBUG(1, "device removed state = 0x%4.4X", dev->link.state);
 127                return 0;
 128        }
 129
 130        mrq.CardOffset = to & ~(dev->win_size-1);
 131        if(mrq.CardOffset != dev->offset) {
 132                DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
 133                      dev->offset, mrq.CardOffset);
 134                mrq.Page = 0;
 135                if( (ret = CardServices(MapMemPage, win, &mrq)) != CS_SUCCESS) {
 136                        cs_error(dev->link.handle, MapMemPage, ret);
 137                        return NULL;
 138                }
 139                dev->offset = mrq.CardOffset;
 140        }
 141        return dev->win_base + (to & (dev->win_size-1));
 142}
 143
 144
 145static u8 pcmcia_read8_remap(struct map_info *map, unsigned long ofs)
 146{
 147        caddr_t addr;
 148        u8 d;
 149
 150        addr = remap_window(map, ofs);
 151        if(!addr)
 152                return 0;
 153
 154        d = readb(addr);
 155        DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02x", ofs, addr, d);
 156        return d;
 157}
 158
 159
 160static u16 pcmcia_read16_remap(struct map_info *map, unsigned long ofs)
 161{
 162        caddr_t addr;
 163        u16 d;
 164
 165        addr = remap_window(map, ofs);
 166        if(!addr)
 167                return 0;
 168
 169        d = readw(addr);
 170        DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04x", ofs, addr, d);
 171        return d;
 172}
 173
 174
 175static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long from, ssize_t len)
 176{
 177        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
 178        unsigned long win_size = dev->win_size;
 179
 180        DEBUG(3, "to = %p from = %lu len = %u", to, from, len);
 181        while(len) {
 182                int toread = win_size - (from & (win_size-1));
 183                caddr_t addr;
 184
 185                if(toread > len)
 186                        toread = len;
 187                
 188                addr = remap_window(map, from);
 189                if(!addr)
 190                        return;
 191
 192                DEBUG(4, "memcpy from %p to %p len = %d", addr, to, toread);
 193                memcpy_fromio(to, addr, toread);
 194                len -= toread;
 195                to += toread;
 196                from += toread;
 197        }
 198}
 199
 200
 201static void pcmcia_write8_remap(struct map_info *map, u8 d, unsigned long adr)
 202{
 203        caddr_t addr = remap_window(map, adr);
 204
 205        if(!addr)
 206                return;
 207
 208        DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%02x", adr, addr, d);
 209        writeb(d, addr);
 210}
 211
 212
 213static void pcmcia_write16_remap(struct map_info *map, u16 d, unsigned long adr)
 214{
 215        caddr_t addr = remap_window(map, adr);
 216        if(!addr)
 217                return;
 218
 219        DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%04x", adr, addr, d);
 220        writew(d, addr);
 221}
 222
 223
 224static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const void *from, ssize_t len)
 225{
 226        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
 227        unsigned long win_size = dev->win_size;
 228
 229        DEBUG(3, "to = %lu from = %p len = %u", to, from, len);
 230        while(len) {
 231                int towrite = win_size - (to & (win_size-1));
 232                caddr_t addr;
 233
 234                if(towrite > len)
 235                        towrite = len;
 236
 237                addr = remap_window(map, to);
 238                if(!addr)
 239                        return;
 240
 241                DEBUG(4, "memcpy from %p to %p len = %d", from, addr, towrite);
 242                memcpy_toio(addr, from, towrite);
 243                len -= towrite;
 244                to += towrite;
 245                from += towrite;
 246        }
 247}
 248
 249
 250/* read/write{8,16} copy_{from,to} routines with direct access */
 251
 252#define DEV_REMOVED(x)  (!(*(u_int *)x->map_priv_1 & DEV_PRESENT))
 253
 254static u8 pcmcia_read8(struct map_info *map, unsigned long ofs)
 255{
 256        caddr_t win_base = (caddr_t)map->map_priv_2;
 257        u8 d;
 258
 259        if(DEV_REMOVED(map))
 260                return 0;
 261
 262        d = readb(win_base + ofs);
 263        DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02x", ofs, win_base + ofs, d);
 264        return d;
 265}
 266
 267
 268static u16 pcmcia_read16(struct map_info *map, unsigned long ofs)
 269{
 270        caddr_t win_base = (caddr_t)map->map_priv_2;
 271        u16 d;
 272
 273        if(DEV_REMOVED(map))
 274                return 0;
 275
 276        d = readw(win_base + ofs);
 277        DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04x", ofs, win_base + ofs, d);
 278        return d;
 279}
 280
 281
 282static void pcmcia_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
 283{
 284        caddr_t win_base = (caddr_t)map->map_priv_2;
 285
 286        if(DEV_REMOVED(map))
 287                return;
 288
 289        DEBUG(3, "to = %p from = %lu len = %u", to, from, len);
 290        memcpy_fromio(to, win_base + from, len);
 291}
 292
 293
 294static void pcmcia_write8(struct map_info *map, u8 d, unsigned long adr)
 295{
 296        caddr_t win_base = (caddr_t)map->map_priv_2;
 297
 298        if(DEV_REMOVED(map))
 299                return;
 300
 301        DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%02x", adr, win_base + adr, d);
 302        writeb(d, win_base + adr);
 303}
 304
 305
 306static void pcmcia_write16(struct map_info *map, u16 d, unsigned long adr)
 307{
 308        caddr_t win_base = (caddr_t)map->map_priv_2;
 309
 310        if(DEV_REMOVED(map))
 311                return;
 312
 313        DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%04x", adr, win_base + adr, d);
 314        writew(d, win_base + adr);
 315}
 316
 317
 318static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
 319{
 320        caddr_t win_base = (caddr_t)map->map_priv_2;
 321
 322        if(DEV_REMOVED(map))
 323                return;
 324
 325        DEBUG(3, "to = %lu from = %p len = %u", to, from, len);
 326        memcpy_toio(win_base + to, from, len);
 327}
 328
 329
 330static void pcmciamtd_set_vpp(struct map_info *map, int on)
 331{
 332        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
 333        dev_link_t *link = &dev->link;
 334        modconf_t mod;
 335        int ret;
 336
 337        mod.Attributes = CONF_VPP1_CHANGE_VALID | CONF_VPP2_CHANGE_VALID;
 338        mod.Vcc = 0;
 339        mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0;
 340
 341        DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
 342        ret = CardServices(ModifyConfiguration, link->handle, &mod);
 343        if(ret != CS_SUCCESS) {
 344                cs_error(link->handle, ModifyConfiguration, ret);
 345        }
 346}
 347
 348
 349/* After a card is removed, pcmciamtd_release() will unregister the
 350 * device, and release the PCMCIA configuration.  If the device is
 351 * still open, this will be postponed until it is closed.
 352 */
 353
 354static void pcmciamtd_release(u_long arg)
 355{
 356        dev_link_t *link = (dev_link_t *)arg;
 357        struct pcmciamtd_dev *dev = link->priv;
 358
 359        DEBUG(3, "link = 0x%p", link);
 360
 361        if (link->win) {
 362                if(dev->win_base) {
 363                        iounmap(dev->win_base);
 364                        dev->win_base = NULL;
 365                }
 366                CardServices(ReleaseWindow, link->win);
 367        }
 368        CardServices(ReleaseConfiguration, link->handle);
 369        link->state &= ~DEV_CONFIG;
 370}
 371
 372
 373static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_name)
 374{
 375        int rc;
 376        tuple_t tuple;
 377        cisparse_t parse;
 378        u_char buf[64];
 379
 380        tuple.Attributes = 0;
 381        tuple.TupleData = (cisdata_t *)buf;
 382        tuple.TupleDataMax = sizeof(buf);
 383        tuple.TupleOffset = 0;
 384        tuple.DesiredTuple = RETURN_FIRST_TUPLE;
 385
 386        rc = CardServices(GetFirstTuple, link->handle, &tuple);
 387        while(rc == CS_SUCCESS) {
 388                rc = CardServices(GetTupleData, link->handle, &tuple);
 389                if(rc != CS_SUCCESS) {
 390                        cs_error(link->handle, GetTupleData, rc);
 391                        break;
 392                }
 393                rc = CardServices(ParseTuple, link->handle, &tuple, &parse);
 394                if(rc != CS_SUCCESS) {
 395                        cs_error(link->handle, ParseTuple, rc);
 396                        break;
 397                }
 398                
 399                switch(tuple.TupleCode) {
 400                case  CISTPL_FORMAT: {
 401                        cistpl_format_t *t = &parse.format;
 402                        (void)t; /* Shut up, gcc */
 403                        DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
 404                              t->type, t->edc, t->offset, t->length);
 405                        break;
 406                        
 407                }
 408                        
 409                case CISTPL_DEVICE: {
 410                        cistpl_device_t *t = &parse.device;
 411                        int i;
 412                        DEBUG(2, "Common memory:");
 413                        dev->pcmcia_map.size = t->dev[0].size;
 414                        for(i = 0; i < t->ndev; i++) {
 415                                DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
 416                                DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
 417                                DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
 418                                DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
 419                        }
 420                        break;
 421                }
 422                        
 423                case CISTPL_VERS_1: {
 424                        cistpl_vers_1_t *t = &parse.version_1;
 425                        int i;
 426                        if(t->ns) {
 427                                dev->mtd_name[0] = '\0';
 428                                for(i = 0; i < t->ns; i++) {
 429                                        if(i)
 430                                                strcat(dev->mtd_name, " ");
 431                                        strcat(dev->mtd_name, t->str+t->ofs[i]);
 432                                }
 433                        }
 434                        DEBUG(2, "Found name: %s", dev->mtd_name);
 435                        break;
 436                }
 437                        
 438                case CISTPL_JEDEC_C: {
 439                        cistpl_jedec_t *t = &parse.jedec;
 440                        int i;
 441                        for(i = 0; i < t->nid; i++) {
 442                                DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
 443                        }
 444                        break;
 445                }
 446                        
 447                case CISTPL_DEVICE_GEO: {
 448                        cistpl_device_geo_t *t = &parse.device_geo;
 449                        int i;
 450                        dev->pcmcia_map.buswidth = t->geo[0].buswidth;
 451                        for(i = 0; i < t->ngeo; i++) {
 452                                DEBUG(2, "region: %d buswidth = %u", i, t->geo[i].buswidth);
 453                                DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
 454                                DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
 455                                DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
 456                                DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
 457                                DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
 458                        }
 459                        break;
 460                }
 461                        
 462                default:
 463                        DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
 464                }
 465                
 466                rc = CardServices(GetNextTuple, link->handle, &tuple, &parse);
 467        }
 468        if(!dev->pcmcia_map.size)
 469                dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
 470
 471        if(!dev->pcmcia_map.buswidth)
 472                dev->pcmcia_map.buswidth = 2;
 473
 474        if(force_size) {
 475                dev->pcmcia_map.size = force_size << 20;
 476                DEBUG(2, "size forced to %dM", force_size);
 477        }
 478
 479        if(buswidth) {
 480                dev->pcmcia_map.buswidth = buswidth;
 481                DEBUG(2, "buswidth forced to %d", buswidth);
 482        }               
 483
 484        dev->pcmcia_map.name = dev->mtd_name;
 485        if(!dev->mtd_name[0]) {
 486                strcpy(dev->mtd_name, "PCMCIA Memory card");
 487                *new_name = 1;
 488        }
 489
 490        DEBUG(1, "Device: Size: %lu Width:%d Name: %s",
 491              dev->pcmcia_map.size, dev->pcmcia_map.buswidth << 3, dev->mtd_name);
 492}
 493
 494
 495/* pcmciamtd_config() is scheduled to run after a CARD_INSERTION event
 496 * is received, to configure the PCMCIA socket, and to make the
 497 * MTD device available to the system.
 498 */
 499
 500#define CS_CHECK(fn, args...) \
 501while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
 502
 503static void pcmciamtd_config(dev_link_t *link)
 504{
 505        struct pcmciamtd_dev *dev = link->priv;
 506        struct mtd_info *mtd = NULL;
 507        cs_status_t status;
 508        win_req_t req;
 509        int last_ret = 0, last_fn = 0;
 510        int ret;
 511        int i;
 512        config_info_t t;
 513        static char *probes[] = { "jedec_probe", "cfi_probe" };
 514        cisinfo_t cisinfo;
 515        int new_name = 0;
 516
 517        DEBUG(3, "link=0x%p", link);
 518
 519        /* Configure card */
 520        link->state |= DEV_CONFIG;
 521
 522        DEBUG(2, "Validating CIS");
 523        ret = CardServices(ValidateCIS, link->handle, &cisinfo);
 524        if(ret != CS_SUCCESS) {
 525                cs_error(link->handle, GetTupleData, ret);
 526        } else {
 527                DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains);
 528        }
 529
 530        card_settings(dev, link, &new_name);
 531
 532        dev->pcmcia_map.read8 = pcmcia_read8_remap;
 533        dev->pcmcia_map.read16 = pcmcia_read16_remap;
 534        dev->pcmcia_map.copy_from = pcmcia_copy_from_remap;
 535        dev->pcmcia_map.write8 = pcmcia_write8_remap;
 536        dev->pcmcia_map.write16 = pcmcia_write16_remap;
 537        dev->pcmcia_map.copy_to = pcmcia_copy_to_remap;
 538        if(setvpp == 1)
 539                dev->pcmcia_map.set_vpp = pcmciamtd_set_vpp;
 540
 541        /* Request a memory window for PCMCIA. Some architeures can map windows upto the maximum
 542           that PCMCIA can support (64Mb) - this is ideal and we aim for a window the size of the
 543           whole card - otherwise we try smaller windows until we succeed */
 544
 545        req.Attributes =  WIN_MEMORY_TYPE_CM | WIN_ENABLE;
 546        req.Attributes |= (dev->pcmcia_map.buswidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16;
 547        req.Base = 0;
 548        req.AccessSpeed = mem_speed;
 549        link->win = (window_handle_t)link->handle;
 550        req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR;
 551        dev->win_size = 0;
 552
 553        do {
 554                int ret;
 555                DEBUG(2, "requesting window with size = %dKB memspeed = %d",
 556                      req.Size >> 10, req.AccessSpeed);
 557                link->win = (window_handle_t)link->handle;
 558                ret = CardServices(RequestWindow, &link->win, &req);
 559                DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
 560                if(ret) {
 561                        req.Size >>= 1;
 562                } else {
 563                        DEBUG(2, "Got window of size %dKB", req.Size >> 10);
 564                        dev->win_size = req.Size;
 565                        break;
 566                }
 567        } while(req.Size >= 0x1000);
 568
 569        DEBUG(2, "dev->win_size = %d", dev->win_size);
 570
 571        if(!dev->win_size) {
 572                err("Cant allocate memory window");
 573                pcmciamtd_release((u_long)link);
 574                return;
 575        }
 576        DEBUG(1, "Allocated a window of %dKB", dev->win_size >> 10);
 577                
 578        /* Get write protect status */
 579        CS_CHECK(GetStatus, link->handle, &status);
 580        DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx",
 581              status.CardState, (unsigned long)link->win);
 582        dev->win_base = ioremap(req.Base, req.Size);
 583        if(!dev->win_base) {
 584                err("ioremap(%lu, %u) failed", req.Base, req.Size);
 585                pcmciamtd_release((u_long)link);
 586                return;
 587        }
 588        DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x",
 589              dev, req.Base, dev->win_base, req.Size);
 590
 591        dev->offset = 0;
 592        dev->pcmcia_map.map_priv_1 = (unsigned long)dev;
 593        dev->pcmcia_map.map_priv_2 = (unsigned long)link->win;
 594
 595        DEBUG(2, "Getting configuration");
 596        CS_CHECK(GetConfigurationInfo, link->handle, &t);
 597        DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2);
 598        dev->vpp = (vpp) ? vpp : t.Vpp1;
 599        link->conf.Attributes = 0;
 600        link->conf.Vcc = t.Vcc;
 601        if(setvpp == 2) {
 602                link->conf.Vpp1 = dev->vpp;
 603                link->conf.Vpp2 = dev->vpp;
 604        } else {
 605                link->conf.Vpp1 = 0;
 606                link->conf.Vpp2 = 0;
 607        }
 608
 609        link->conf.IntType = INT_MEMORY;
 610        link->conf.ConfigBase = t.ConfigBase;
 611        link->conf.Status = t.Status;
 612        link->conf.Pin = t.Pin;
 613        link->conf.Copy = t.Copy;
 614        link->conf.ExtStatus = t.ExtStatus;
 615        link->conf.ConfigIndex = 0;
 616        link->conf.Present = t.Present;
 617        DEBUG(2, "Setting Configuration");
 618        ret = CardServices(RequestConfiguration, link->handle, &link->conf);
 619        if(ret != CS_SUCCESS) {
 620                cs_error(link->handle, RequestConfiguration, ret);
 621        }
 622
 623        if(mem_type == 1) {
 624                mtd = do_map_probe("map_ram", &dev->pcmcia_map);
 625        } else if(mem_type == 2) {
 626                mtd = do_map_probe("map_rom", &dev->pcmcia_map);
 627        } else {
 628                for(i = 0; i < sizeof(probes) / sizeof(char *); i++) {
 629                        DEBUG(1, "Trying %s", probes[i]);
 630                        mtd = do_map_probe(probes[i], &dev->pcmcia_map);
 631                        if(mtd)
 632                                break;
 633                        
 634                        DEBUG(1, "FAILED: %s", probes[i]);
 635                }
 636        }
 637        
 638        if(!mtd) {
 639                DEBUG(1, "Cant find an MTD");
 640                pcmciamtd_release((u_long)link);
 641                return;
 642        }
 643
 644        dev->mtd_info = mtd;
 645        mtd->module = THIS_MODULE;
 646
 647        if(new_name) {
 648                int size = 0;
 649                char unit = ' ';
 650                /* Since we are using a default name, make it better by adding in the
 651                   size */
 652                if(mtd->size < 1048576) { /* <1MB in size, show size in K */
 653                        size = mtd->size >> 10;
 654                        unit = 'K';
 655                } else {
 656                        size = mtd->size >> 20;
 657                        unit = 'M';
 658                }
 659                snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%cB %s", size, unit, "PCMCIA Memory card");
 660        }
 661
 662        /* If the memory found is fits completely into the mapped PCMCIA window,
 663           use the faster non-remapping read/write functions */
 664        if(mtd->size <= dev->win_size) {
 665                DEBUG(1, "Using non remapping memory functions");
 666                dev->pcmcia_map.map_priv_1 = (unsigned long)&(dev->link.state);
 667                dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base;
 668                dev->pcmcia_map.read8 = pcmcia_read8;
 669                dev->pcmcia_map.read16 = pcmcia_read16;
 670                dev->pcmcia_map.copy_from = pcmcia_copy_from;
 671                dev->pcmcia_map.write8 = pcmcia_write8;
 672                dev->pcmcia_map.write16 = pcmcia_write16;
 673                dev->pcmcia_map.copy_to = pcmcia_copy_to;
 674        }
 675
 676        if(add_mtd_device(mtd)) {
 677                map_destroy(mtd);
 678                dev->mtd_info = NULL;
 679                err("Couldnt register MTD device");
 680                pcmciamtd_release((u_long)link);
 681                return;
 682        }
 683        snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index);
 684        info("mtd%d: %s", mtd->index, mtd->name);
 685        link->state &= ~DEV_CONFIG_PENDING;
 686        link->dev = &dev->node;
 687        return;
 688
 689 cs_failed:
 690        cs_error(link->handle, last_fn, last_ret);
 691        err("CS Error, exiting");
 692        pcmciamtd_release((u_long)link);
 693        return;
 694}
 695
 696
 697/* The card status event handler.  Mostly, this schedules other
 698 * stuff to run after an event is received.  A CARD_REMOVAL event
 699 * also sets some flags to discourage the driver from trying
 700 * to talk to the card any more.
 701 */
 702
 703static int pcmciamtd_event(event_t event, int priority,
 704                        event_callback_args_t *args)
 705{
 706        dev_link_t *link = args->client_data;
 707
 708        DEBUG(1, "event=0x%06x", event);
 709        switch (event) {
 710        case CS_EVENT_CARD_REMOVAL:
 711                DEBUG(2, "EVENT_CARD_REMOVAL");
 712                link->state &= ~DEV_PRESENT;
 713                if (link->state & DEV_CONFIG) {
 714                        struct pcmciamtd_dev *dev = link->priv;
 715                        if(dev->mtd_info) {
 716                                del_mtd_device(dev->mtd_info);
 717                                info("mtd%d: Removed", dev->mtd_info->index);
 718                        }
 719                        mod_timer(&link->release, jiffies + HZ/20);
 720                }
 721                break;
 722        case CS_EVENT_CARD_INSERTION:
 723                DEBUG(2, "EVENT_CARD_INSERTION");
 724                link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
 725                pcmciamtd_config(link);
 726                break;
 727        case CS_EVENT_PM_SUSPEND:
 728                DEBUG(2, "EVENT_PM_SUSPEND");
 729                link->state |= DEV_SUSPEND;
 730                /* Fall through... */
 731        case CS_EVENT_RESET_PHYSICAL:
 732                DEBUG(2, "EVENT_RESET_PHYSICAL");
 733                /* get_lock(link); */
 734                break;
 735        case CS_EVENT_PM_RESUME:
 736                DEBUG(2, "EVENT_PM_RESUME");
 737                link->state &= ~DEV_SUSPEND;
 738                /* Fall through... */
 739        case CS_EVENT_CARD_RESET:
 740                DEBUG(2, "EVENT_CARD_RESET");
 741                /* free_lock(link); */
 742                break;
 743        default:
 744                DEBUG(2, "Unknown event %d", event);
 745        }
 746        return 0;
 747}
 748
 749
 750/* This deletes a driver "instance".  The device is de-registered
 751 * with Card Services.  If it has been released, all local data
 752 * structures are freed.  Otherwise, the structures will be freed
 753 * when the device is released.
 754 */
 755
 756static void pcmciamtd_detach(dev_link_t *link)
 757{
 758        DEBUG(3, "link=0x%p", link);
 759
 760        del_timer(&link->release);
 761
 762        if(link->state & DEV_CONFIG) {
 763                pcmciamtd_release((u_long)link);
 764        }
 765
 766        if (link->handle) {
 767                int ret;
 768                DEBUG(2, "Deregistering with card services");
 769                ret = CardServices(DeregisterClient, link->handle);
 770                if (ret != CS_SUCCESS)
 771                        cs_error(link->handle, DeregisterClient, ret);
 772        }
 773
 774        link->state |= DEV_STALE_LINK;
 775}
 776
 777
 778/* pcmciamtd_attach() creates an "instance" of the driver, allocating
 779 * local data structures for one device.  The device is registered
 780 * with Card Services.
 781 */
 782
 783static dev_link_t *pcmciamtd_attach(void)
 784{
 785        struct pcmciamtd_dev *dev;
 786        dev_link_t *link;
 787        client_reg_t client_reg;
 788        int ret;
 789
 790        /* Create new memory card device */
 791        dev = kmalloc(sizeof(*dev), GFP_KERNEL);
 792        if (!dev) return NULL;
 793        DEBUG(1, "dev=0x%p", dev);
 794
 795        memset(dev, 0, sizeof(*dev));
 796        link = &dev->link;
 797        link->priv = dev;
 798
 799        init_timer(&link->release);
 800        link->release.function = &pcmciamtd_release;
 801        link->release.data = (u_long)link;
 802
 803        link->conf.Attributes = 0;
 804        link->conf.IntType = INT_MEMORY;
 805
 806        link->next = dev_list;
 807        dev_list = link;
 808
 809        /* Register with Card Services */
 810        client_reg.dev_info = &dev_info;
 811        client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
 812        client_reg.EventMask =
 813                CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
 814                CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
 815                CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
 816        client_reg.event_handler = &pcmciamtd_event;
 817        client_reg.Version = 0x0210;
 818        client_reg.event_callback_args.client_data = link;
 819        DEBUG(2, "Calling RegisterClient");
 820        ret = CardServices(RegisterClient, &link->handle, &client_reg);
 821        if (ret != 0) {
 822                cs_error(link->handle, RegisterClient, ret);
 823                pcmciamtd_detach(link);
 824                return NULL;
 825        }
 826        DEBUG(2, "link = %p", link);
 827        return link;
 828}
 829
 830
 831static int __init init_pcmciamtd(void)
 832{
 833        servinfo_t serv;
 834
 835        info(DRIVER_DESC " " DRIVER_VERSION);
 836        CardServices(GetCardServicesInfo, &serv);
 837        if (serv.Revision != CS_RELEASE_CODE) {
 838                err("Card Services release does not match!");
 839                return -1;
 840        }
 841
 842        if(buswidth && buswidth != 1 && buswidth != 2) {
 843                info("bad buswidth (%d), using default", buswidth);
 844                buswidth = 2;
 845        }
 846        if(force_size && (force_size < 1 || force_size > 64)) {
 847                info("bad force_size (%d), using default", force_size);
 848                force_size = 0;
 849        }
 850        if(mem_type && mem_type != 1 && mem_type != 2) {
 851                info("bad mem_type (%d), using default", mem_type);
 852                mem_type = 0;
 853        }
 854        register_pccard_driver(&dev_info, &pcmciamtd_attach, &pcmciamtd_detach);
 855        return 0;
 856}
 857
 858
 859static void __exit exit_pcmciamtd(void)
 860{
 861        DEBUG(1, DRIVER_DESC " unloading");
 862        unregister_pccard_driver(&dev_info);
 863
 864        while(dev_list) {
 865                dev_link_t *link = dev_list;
 866
 867                dev_list = link->next;
 868                if (link) {
 869                        struct pcmciamtd_dev *dev = link->priv;
 870                        
 871                        if(dev) {
 872                                if(link->state & DEV_PRESENT) {
 873                                        if (!(link->state & DEV_STALE_LINK)) {
 874                                                pcmciamtd_detach(link);
 875                                        }
 876                                        link->state &= ~DEV_PRESENT;
 877                                        if(dev->mtd_info) {
 878                                                del_mtd_device(dev->mtd_info);
 879                                                info("mtd%d: Removed",
 880                                                     dev->mtd_info->index);
 881                                        }
 882                                }
 883                                if(dev->mtd_info) {
 884                                        DEBUG(2, "Destroying map for mtd%d",
 885                                              dev->mtd_info->index);
 886                                        map_destroy(dev->mtd_info);
 887                                }
 888                                kfree(dev);
 889                        }
 890                }
 891        }
 892}
 893
 894module_init(init_pcmciamtd);
 895module_exit(exit_pcmciamtd);
 896