Showing error 1283

User: Jiri Slaby
Error type: Leaving function in locked state
Error type description: Some lock is not unlocked on all paths of a function, so it is leaked
File location: drivers/memstick/host/jmb38x_ms.c
Line in file: 362
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2012-05-21 20:30:05 UTC


Source:

   1/*
   2 *  jmb38x_ms.c - JMicron jmb38x MemoryStick card reader
   3 *
   4 *  Copyright (C) 2008 Alex Dubov <oakad@yahoo.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 */
  11
  12#include <linux/spinlock.h>
  13#include <linux/interrupt.h>
  14#include <linux/pci.h>
  15#include <linux/dma-mapping.h>
  16#include <linux/delay.h>
  17#include <linux/highmem.h>
  18#include <linux/memstick.h>
  19
  20#define DRIVER_NAME "jmb38x_ms"
  21
  22static int no_dma;
  23module_param(no_dma, bool, 0644);
  24
  25enum {
  26        DMA_ADDRESS       = 0x00,
  27        BLOCK             = 0x04,
  28        DMA_CONTROL       = 0x08,
  29        TPC_P0            = 0x0c,
  30        TPC_P1            = 0x10,
  31        TPC               = 0x14,
  32        HOST_CONTROL      = 0x18,
  33        DATA              = 0x1c,
  34        STATUS            = 0x20,
  35        INT_STATUS        = 0x24,
  36        INT_STATUS_ENABLE = 0x28,
  37        INT_SIGNAL_ENABLE = 0x2c,
  38        TIMER             = 0x30,
  39        TIMER_CONTROL     = 0x34,
  40        PAD_OUTPUT_ENABLE = 0x38,
  41        PAD_PU_PD         = 0x3c,
  42        CLOCK_DELAY       = 0x40,
  43        ADMA_ADDRESS      = 0x44,
  44        CLOCK_CONTROL     = 0x48,
  45        LED_CONTROL       = 0x4c,
  46        VERSION           = 0x50
  47};
  48
  49struct jmb38x_ms_host {
  50        struct jmb38x_ms        *chip;
  51        void __iomem            *addr;
  52        spinlock_t              lock;
  53        struct tasklet_struct   notify;
  54        int                     id;
  55        char                    host_id[32];
  56        int                     irq;
  57        unsigned int            block_pos;
  58        unsigned long           timeout_jiffies;
  59        struct timer_list       timer;
  60        struct memstick_request *req;
  61        unsigned char           cmd_flags;
  62        unsigned char           io_pos;
  63        unsigned int            io_word[2];
  64};
  65
  66struct jmb38x_ms {
  67        struct pci_dev        *pdev;
  68        int                   host_cnt;
  69        struct memstick_host  *hosts[];
  70};
  71
  72#define BLOCK_COUNT_MASK       0xffff0000
  73#define BLOCK_SIZE_MASK        0x00000fff
  74
  75#define DMA_CONTROL_ENABLE     0x00000001
  76
  77#define TPC_DATA_SEL           0x00008000
  78#define TPC_DIR                0x00004000
  79#define TPC_WAIT_INT           0x00002000
  80#define TPC_GET_INT            0x00000800
  81#define TPC_CODE_SZ_MASK       0x00000700
  82#define TPC_DATA_SZ_MASK       0x00000007
  83
  84#define HOST_CONTROL_TDELAY_EN 0x00040000
  85#define HOST_CONTROL_HW_OC_P   0x00010000
  86#define HOST_CONTROL_RESET_REQ 0x00008000
  87#define HOST_CONTROL_REI       0x00004000
  88#define HOST_CONTROL_LED       0x00000400
  89#define HOST_CONTROL_FAST_CLK  0x00000200
  90#define HOST_CONTROL_RESET     0x00000100
  91#define HOST_CONTROL_POWER_EN  0x00000080
  92#define HOST_CONTROL_CLOCK_EN  0x00000040
  93#define HOST_CONTROL_REO       0x00000008
  94#define HOST_CONTROL_IF_SHIFT  4
  95
  96#define HOST_CONTROL_IF_SERIAL 0x0
  97#define HOST_CONTROL_IF_PAR4   0x1
  98#define HOST_CONTROL_IF_PAR8   0x3
  99
 100#define STATUS_BUSY             0x00080000
 101#define STATUS_MS_DAT7          0x00040000
 102#define STATUS_MS_DAT6          0x00020000
 103#define STATUS_MS_DAT5          0x00010000
 104#define STATUS_MS_DAT4          0x00008000
 105#define STATUS_MS_DAT3          0x00004000
 106#define STATUS_MS_DAT2          0x00002000
 107#define STATUS_MS_DAT1          0x00001000
 108#define STATUS_MS_DAT0          0x00000800
 109#define STATUS_HAS_MEDIA        0x00000400
 110#define STATUS_FIFO_EMPTY       0x00000200
 111#define STATUS_FIFO_FULL        0x00000100
 112#define STATUS_MS_CED           0x00000080
 113#define STATUS_MS_ERR           0x00000040
 114#define STATUS_MS_BRQ           0x00000020
 115#define STATUS_MS_CNK           0x00000001
 116
 117#define INT_STATUS_TPC_ERR      0x00080000
 118#define INT_STATUS_CRC_ERR      0x00040000
 119#define INT_STATUS_TIMER_TO     0x00020000
 120#define INT_STATUS_HSK_TO       0x00010000
 121#define INT_STATUS_ANY_ERR      0x00008000
 122#define INT_STATUS_FIFO_WRDY    0x00000080
 123#define INT_STATUS_FIFO_RRDY    0x00000040
 124#define INT_STATUS_MEDIA_OUT    0x00000010
 125#define INT_STATUS_MEDIA_IN     0x00000008
 126#define INT_STATUS_DMA_BOUNDARY 0x00000004
 127#define INT_STATUS_EOTRAN       0x00000002
 128#define INT_STATUS_EOTPC        0x00000001
 129
 130#define INT_STATUS_ALL          0x000f801f
 131
 132#define PAD_OUTPUT_ENABLE_MS  0x0F3F
 133
 134#define PAD_PU_PD_OFF         0x7FFF0000
 135#define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000
 136#define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
 137
 138#define CLOCK_CONTROL_40MHZ   0x00000001
 139#define CLOCK_CONTROL_50MHZ   0x0000000a
 140#define CLOCK_CONTROL_60MHZ   0x00000008
 141#define CLOCK_CONTROL_62_5MHZ 0x0000000c
 142#define CLOCK_CONTROL_OFF     0x00000000
 143
 144#define PCI_CTL_CLOCK_DLY_ADDR   0x000000b0
 145#define PCI_CTL_CLOCK_DLY_MASK_A 0x00000f00
 146#define PCI_CTL_CLOCK_DLY_MASK_B 0x0000f000
 147
 148enum {
 149        CMD_READY    = 0x01,
 150        FIFO_READY   = 0x02,
 151        REG_DATA     = 0x04,
 152        DMA_DATA     = 0x08
 153};
 154
 155static unsigned int jmb38x_ms_read_data(struct jmb38x_ms_host *host,
 156                                        unsigned char *buf, unsigned int length)
 157{
 158        unsigned int off = 0;
 159
 160        while (host->io_pos && length) {
 161                buf[off++] = host->io_word[0] & 0xff;
 162                host->io_word[0] >>= 8;
 163                length--;
 164                host->io_pos--;
 165        }
 166
 167        if (!length)
 168                return off;
 169
 170        while (!(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) {
 171                if (length < 4)
 172                        break;
 173                *(unsigned int *)(buf + off) = __raw_readl(host->addr + DATA);
 174                length -= 4;
 175                off += 4;
 176        }
 177
 178        if (length
 179            && !(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) {
 180                host->io_word[0] = readl(host->addr + DATA);
 181                for (host->io_pos = 4; host->io_pos; --host->io_pos) {
 182                        buf[off++] = host->io_word[0] & 0xff;
 183                        host->io_word[0] >>= 8;
 184                        length--;
 185                        if (!length)
 186                                break;
 187                }
 188        }
 189
 190        return off;
 191}
 192
 193static unsigned int jmb38x_ms_read_reg_data(struct jmb38x_ms_host *host,
 194                                            unsigned char *buf,
 195                                            unsigned int length)
 196{
 197        unsigned int off = 0;
 198
 199        while (host->io_pos > 4 && length) {
 200                buf[off++] = host->io_word[0] & 0xff;
 201                host->io_word[0] >>= 8;
 202                length--;
 203                host->io_pos--;
 204        }
 205
 206        if (!length)
 207                return off;
 208
 209        while (host->io_pos && length) {
 210                buf[off++] = host->io_word[1] & 0xff;
 211                host->io_word[1] >>= 8;
 212                length--;
 213                host->io_pos--;
 214        }
 215
 216        return off;
 217}
 218
 219static unsigned int jmb38x_ms_write_data(struct jmb38x_ms_host *host,
 220                                         unsigned char *buf,
 221                                         unsigned int length)
 222{
 223        unsigned int off = 0;
 224
 225        if (host->io_pos) {
 226                while (host->io_pos < 4 && length) {
 227                        host->io_word[0] |=  buf[off++] << (host->io_pos * 8);
 228                        host->io_pos++;
 229                        length--;
 230                }
 231        }
 232
 233        if (host->io_pos == 4
 234            && !(STATUS_FIFO_FULL & readl(host->addr + STATUS))) {
 235                writel(host->io_word[0], host->addr + DATA);
 236                host->io_pos = 0;
 237                host->io_word[0] = 0;
 238        } else if (host->io_pos) {
 239                return off;
 240        }
 241
 242        if (!length)
 243                return off;
 244
 245        while (!(STATUS_FIFO_FULL & readl(host->addr + STATUS))) {
 246                if (length < 4)
 247                        break;
 248
 249                __raw_writel(*(unsigned int *)(buf + off),
 250                             host->addr + DATA);
 251                length -= 4;
 252                off += 4;
 253        }
 254
 255        switch (length) {
 256        case 3:
 257                host->io_word[0] |= buf[off + 2] << 16;
 258                host->io_pos++;
 259        case 2:
 260                host->io_word[0] |= buf[off + 1] << 8;
 261                host->io_pos++;
 262        case 1:
 263                host->io_word[0] |= buf[off];
 264                host->io_pos++;
 265        }
 266
 267        off += host->io_pos;
 268
 269        return off;
 270}
 271
 272static unsigned int jmb38x_ms_write_reg_data(struct jmb38x_ms_host *host,
 273                                             unsigned char *buf,
 274                                             unsigned int length)
 275{
 276        unsigned int off = 0;
 277
 278        while (host->io_pos < 4 && length) {
 279                host->io_word[0] &= ~(0xff << (host->io_pos * 8));
 280                host->io_word[0] |=  buf[off++] << (host->io_pos * 8);
 281                host->io_pos++;
 282                length--;
 283        }
 284
 285        if (!length)
 286                return off;
 287
 288        while (host->io_pos < 8 && length) {
 289                host->io_word[1] &= ~(0xff << (host->io_pos * 8));
 290                host->io_word[1] |=  buf[off++] << (host->io_pos * 8);
 291                host->io_pos++;
 292                length--;
 293        }
 294
 295        return off;
 296}
 297
 298static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
 299{
 300        unsigned int length;
 301        unsigned int off;
 302        unsigned int t_size, p_cnt;
 303        unsigned char *buf;
 304        struct page *pg;
 305        unsigned long flags = 0;
 306
 307        if (host->req->long_data) {
 308                length = host->req->sg.length - host->block_pos;
 309                off = host->req->sg.offset + host->block_pos;
 310        } else {
 311                length = host->req->data_len - host->block_pos;
 312                off = 0;
 313        }
 314
 315        while (length) {
 316                unsigned int uninitialized_var(p_off);
 317
 318                if (host->req->long_data) {
 319                        pg = nth_page(sg_page(&host->req->sg),
 320                                      off >> PAGE_SHIFT);
 321                        p_off = offset_in_page(off);
 322                        p_cnt = PAGE_SIZE - p_off;
 323                        p_cnt = min(p_cnt, length);
 324
 325                        local_irq_save(flags);
 326                        buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off;
 327                } else {
 328                        buf = host->req->data + host->block_pos;
 329                        p_cnt = host->req->data_len - host->block_pos;
 330                }
 331
 332                if (host->req->data_dir == WRITE)
 333                        t_size = !(host->cmd_flags & REG_DATA)
 334                                 ? jmb38x_ms_write_data(host, buf, p_cnt)
 335                                 : jmb38x_ms_write_reg_data(host, buf, p_cnt);
 336                else
 337                        t_size = !(host->cmd_flags & REG_DATA)
 338                                 ? jmb38x_ms_read_data(host, buf, p_cnt)
 339                                 : jmb38x_ms_read_reg_data(host, buf, p_cnt);
 340
 341                if (host->req->long_data) {
 342                        kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ);
 343                        local_irq_restore(flags);
 344                }
 345
 346                if (!t_size)
 347                        break;
 348                host->block_pos += t_size;
 349                length -= t_size;
 350                off += t_size;
 351        }
 352
 353        if (!length && host->req->data_dir == WRITE) {
 354                if (host->cmd_flags & REG_DATA) {
 355                        writel(host->io_word[0], host->addr + TPC_P0);
 356                        writel(host->io_word[1], host->addr + TPC_P1);
 357                } else if (host->io_pos) {
 358                        writel(host->io_word[0], host->addr + DATA);
 359                }
 360        }
 361
 362        return length;
 363}
 364
 365static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
 366{
 367        struct jmb38x_ms_host *host = memstick_priv(msh);
 368        unsigned char *data;
 369        unsigned int data_len, cmd, t_val;
 370
 371        if (!(STATUS_HAS_MEDIA & readl(host->addr + STATUS))) {
 372                dev_dbg(&msh->dev, "no media status\n");
 373                host->req->error = -ETIME;
 374                return host->req->error;
 375        }
 376
 377        dev_dbg(&msh->dev, "control %08x\n", readl(host->addr + HOST_CONTROL));
 378        dev_dbg(&msh->dev, "status %08x\n", readl(host->addr + INT_STATUS));
 379        dev_dbg(&msh->dev, "hstatus %08x\n", readl(host->addr + STATUS));
 380
 381        host->cmd_flags = 0;
 382        host->block_pos = 0;
 383        host->io_pos = 0;
 384        host->io_word[0] = 0;
 385        host->io_word[1] = 0;
 386
 387        cmd = host->req->tpc << 16;
 388        cmd |= TPC_DATA_SEL;
 389
 390        if (host->req->data_dir == READ)
 391                cmd |= TPC_DIR;
 392        if (host->req->need_card_int)
 393                cmd |= TPC_WAIT_INT;
 394
 395        data = host->req->data;
 396
 397        if (!no_dma)
 398                host->cmd_flags |= DMA_DATA;
 399
 400        if (host->req->long_data) {
 401                data_len = host->req->sg.length;
 402        } else {
 403                data_len = host->req->data_len;
 404                host->cmd_flags &= ~DMA_DATA;
 405        }
 406
 407        if (data_len <= 8) {
 408                cmd &= ~(TPC_DATA_SEL | 0xf);
 409                host->cmd_flags |= REG_DATA;
 410                cmd |= data_len & 0xf;
 411                host->cmd_flags &= ~DMA_DATA;
 412        }
 413
 414        if (host->cmd_flags & DMA_DATA) {
 415                if (1 != pci_map_sg(host->chip->pdev, &host->req->sg, 1,
 416                                    host->req->data_dir == READ
 417                                    ? PCI_DMA_FROMDEVICE
 418                                    : PCI_DMA_TODEVICE)) {
 419                        host->req->error = -ENOMEM;
 420                        return host->req->error;
 421                }
 422                data_len = sg_dma_len(&host->req->sg);
 423                writel(sg_dma_address(&host->req->sg),
 424                       host->addr + DMA_ADDRESS);
 425                writel(((1 << 16) & BLOCK_COUNT_MASK)
 426                       | (data_len & BLOCK_SIZE_MASK),
 427                       host->addr + BLOCK);
 428                writel(DMA_CONTROL_ENABLE, host->addr + DMA_CONTROL);
 429        } else if (!(host->cmd_flags & REG_DATA)) {
 430                writel(((1 << 16) & BLOCK_COUNT_MASK)
 431                       | (data_len & BLOCK_SIZE_MASK),
 432                       host->addr + BLOCK);
 433                        t_val = readl(host->addr + INT_STATUS_ENABLE);
 434                        t_val |= host->req->data_dir == READ
 435                                 ? INT_STATUS_FIFO_RRDY
 436                                 : INT_STATUS_FIFO_WRDY;
 437
 438                        writel(t_val, host->addr + INT_STATUS_ENABLE);
 439                        writel(t_val, host->addr + INT_SIGNAL_ENABLE);
 440        } else {
 441                cmd &= ~(TPC_DATA_SEL | 0xf);
 442                host->cmd_flags |= REG_DATA;
 443                cmd |= data_len & 0xf;
 444
 445                if (host->req->data_dir == WRITE) {
 446                        jmb38x_ms_transfer_data(host);
 447                        writel(host->io_word[0], host->addr + TPC_P0);
 448                        writel(host->io_word[1], host->addr + TPC_P1);
 449                }
 450        }
 451
 452        mod_timer(&host->timer, jiffies + host->timeout_jiffies);
 453        writel(HOST_CONTROL_LED | readl(host->addr + HOST_CONTROL),
 454               host->addr + HOST_CONTROL);
 455        host->req->error = 0;
 456
 457        writel(cmd, host->addr + TPC);
 458        dev_dbg(&msh->dev, "executing TPC %08x, len %x\n", cmd, data_len);
 459
 460        return 0;
 461}
 462
 463static void jmb38x_ms_complete_cmd(struct memstick_host *msh, int last)
 464{
 465        struct jmb38x_ms_host *host = memstick_priv(msh);
 466        unsigned int t_val = 0;
 467        int rc;
 468
 469        del_timer(&host->timer);
 470
 471        dev_dbg(&msh->dev, "c control %08x\n",
 472                readl(host->addr + HOST_CONTROL));
 473        dev_dbg(&msh->dev, "c status %08x\n",
 474                readl(host->addr + INT_STATUS));
 475        dev_dbg(&msh->dev, "c hstatus %08x\n", readl(host->addr + STATUS));
 476
 477        host->req->int_reg = readl(host->addr + STATUS) & 0xff;
 478
 479        writel(0, host->addr + BLOCK);
 480        writel(0, host->addr + DMA_CONTROL);
 481
 482        if (host->cmd_flags & DMA_DATA) {
 483                pci_unmap_sg(host->chip->pdev, &host->req->sg, 1,
 484                             host->req->data_dir == READ
 485                             ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
 486        } else {
 487                t_val = readl(host->addr + INT_STATUS_ENABLE);
 488                if (host->req->data_dir == READ)
 489                        t_val &= ~INT_STATUS_FIFO_RRDY;
 490                else
 491                        t_val &= ~INT_STATUS_FIFO_WRDY;
 492
 493                writel(t_val, host->addr + INT_STATUS_ENABLE);
 494                writel(t_val, host->addr + INT_SIGNAL_ENABLE);
 495        }
 496
 497        writel((~HOST_CONTROL_LED) & readl(host->addr + HOST_CONTROL),
 498               host->addr + HOST_CONTROL);
 499
 500        if (!last) {
 501                do {
 502                        rc = memstick_next_req(msh, &host->req);
 503                } while (!rc && jmb38x_ms_issue_cmd(msh));
 504        } else {
 505                do {
 506                        rc = memstick_next_req(msh, &host->req);
 507                        if (!rc)
 508                                host->req->error = -ETIME;
 509                } while (!rc);
 510        }
 511}
 512
 513static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id)
 514{
 515        struct memstick_host *msh = dev_id;
 516        struct jmb38x_ms_host *host = memstick_priv(msh);
 517        unsigned int irq_status;
 518
 519        spin_lock(&host->lock);
 520        irq_status = readl(host->addr + INT_STATUS);
 521        dev_dbg(&host->chip->pdev->dev, "irq_status = %08x\n", irq_status);
 522        if (irq_status == 0 || irq_status == (~0)) {
 523                spin_unlock(&host->lock);
 524                return IRQ_NONE;
 525        }
 526
 527        if (host->req) {
 528                if (irq_status & INT_STATUS_ANY_ERR) {
 529                        if (irq_status & INT_STATUS_CRC_ERR)
 530                                host->req->error = -EILSEQ;
 531                        else
 532                                host->req->error = -ETIME;
 533                } else {
 534                        if (host->cmd_flags & DMA_DATA) {
 535                                if (irq_status & INT_STATUS_EOTRAN)
 536                                        host->cmd_flags |= FIFO_READY;
 537                        } else {
 538                                if (irq_status & (INT_STATUS_FIFO_RRDY
 539                                                  | INT_STATUS_FIFO_WRDY))
 540                                        jmb38x_ms_transfer_data(host);
 541
 542                                if (irq_status & INT_STATUS_EOTRAN) {
 543                                        jmb38x_ms_transfer_data(host);
 544                                        host->cmd_flags |= FIFO_READY;
 545                                }
 546                        }
 547
 548                        if (irq_status & INT_STATUS_EOTPC) {
 549                                host->cmd_flags |= CMD_READY;
 550                                if (host->cmd_flags & REG_DATA) {
 551                                        if (host->req->data_dir == READ) {
 552                                                host->io_word[0]
 553                                                        = readl(host->addr
 554                                                                + TPC_P0);
 555                                                host->io_word[1]
 556                                                        = readl(host->addr
 557                                                                + TPC_P1);
 558                                                host->io_pos = 8;
 559
 560                                                jmb38x_ms_transfer_data(host);
 561                                        }
 562                                        host->cmd_flags |= FIFO_READY;
 563                                }
 564                        }
 565                }
 566        }
 567
 568        if (irq_status & (INT_STATUS_MEDIA_IN | INT_STATUS_MEDIA_OUT)) {
 569                dev_dbg(&host->chip->pdev->dev, "media changed\n");
 570                memstick_detect_change(msh);
 571        }
 572
 573        writel(irq_status, host->addr + INT_STATUS);
 574
 575        if (host->req
 576            && (((host->cmd_flags & CMD_READY)
 577                 && (host->cmd_flags & FIFO_READY))
 578                || host->req->error))
 579                jmb38x_ms_complete_cmd(msh, 0);
 580
 581        spin_unlock(&host->lock);
 582        return IRQ_HANDLED;
 583}
 584
 585static void jmb38x_ms_abort(unsigned long data)
 586{
 587        struct memstick_host *msh = (struct memstick_host *)data;
 588        struct jmb38x_ms_host *host = memstick_priv(msh);
 589        unsigned long flags;
 590
 591        dev_dbg(&host->chip->pdev->dev, "abort\n");
 592        spin_lock_irqsave(&host->lock, flags);
 593        if (host->req) {
 594                host->req->error = -ETIME;
 595                jmb38x_ms_complete_cmd(msh, 0);
 596        }
 597        spin_unlock_irqrestore(&host->lock, flags);
 598}
 599
 600static void jmb38x_ms_req_tasklet(unsigned long data)
 601{
 602        struct memstick_host *msh = (struct memstick_host *)data;
 603        struct jmb38x_ms_host *host = memstick_priv(msh);
 604        unsigned long flags;
 605        int rc;
 606
 607        spin_lock_irqsave(&host->lock, flags);
 608        if (!host->req) {
 609                do {
 610                        rc = memstick_next_req(msh, &host->req);
 611                        dev_dbg(&host->chip->pdev->dev, "tasklet req %d\n", rc);
 612                } while (!rc && jmb38x_ms_issue_cmd(msh));
 613        }
 614        spin_unlock_irqrestore(&host->lock, flags);
 615}
 616
 617static void jmb38x_ms_dummy_submit(struct memstick_host *msh)
 618{
 619        return;
 620}
 621
 622static void jmb38x_ms_submit_req(struct memstick_host *msh)
 623{
 624        struct jmb38x_ms_host *host = memstick_priv(msh);
 625
 626        tasklet_schedule(&host->notify);
 627}
 628
 629static int jmb38x_ms_reset(struct jmb38x_ms_host *host)
 630{
 631        int cnt;
 632
 633        writel(HOST_CONTROL_RESET_REQ | HOST_CONTROL_CLOCK_EN
 634               | readl(host->addr + HOST_CONTROL),
 635               host->addr + HOST_CONTROL);
 636        mmiowb();
 637
 638        for (cnt = 0; cnt < 20; ++cnt) {
 639                if (!(HOST_CONTROL_RESET_REQ
 640                      & readl(host->addr + HOST_CONTROL)))
 641                        goto reset_next;
 642
 643                ndelay(20);
 644        }
 645        dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n");
 646        /* return -EIO; */
 647
 648reset_next:
 649        writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN
 650               | readl(host->addr + HOST_CONTROL),
 651               host->addr + HOST_CONTROL);
 652        mmiowb();
 653
 654        for (cnt = 0; cnt < 20; ++cnt) {
 655                if (!(HOST_CONTROL_RESET
 656                      & readl(host->addr + HOST_CONTROL)))
 657                        goto reset_ok;
 658
 659                ndelay(20);
 660        }
 661        dev_dbg(&host->chip->pdev->dev, "reset timeout\n");
 662        return -EIO;
 663
 664reset_ok:
 665        mmiowb();
 666        writel(INT_STATUS_ALL, host->addr + INT_SIGNAL_ENABLE);
 667        writel(INT_STATUS_ALL, host->addr + INT_STATUS_ENABLE);
 668        return 0;
 669}
 670
 671static int jmb38x_ms_set_param(struct memstick_host *msh,
 672                               enum memstick_param param,
 673                               int value)
 674{
 675        struct jmb38x_ms_host *host = memstick_priv(msh);
 676        unsigned int host_ctl = readl(host->addr + HOST_CONTROL);
 677        unsigned int clock_ctl = CLOCK_CONTROL_40MHZ, clock_delay = 0;
 678        int rc = 0;
 679
 680        switch (param) {
 681        case MEMSTICK_POWER:
 682                if (value == MEMSTICK_POWER_ON) {
 683                        rc = jmb38x_ms_reset(host);
 684                        if (rc)
 685                                return rc;
 686
 687                        host_ctl = 7;
 688                        host_ctl |= HOST_CONTROL_POWER_EN
 689                                    | HOST_CONTROL_CLOCK_EN
 690                                    | HOST_CONTROL_HW_OC_P
 691                                    | HOST_CONTROL_TDELAY_EN;
 692                        writel(host_ctl, host->addr + HOST_CONTROL);
 693
 694                        writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
 695                                        : PAD_PU_PD_ON_MS_SOCK0,
 696                               host->addr + PAD_PU_PD);
 697
 698                        writel(PAD_OUTPUT_ENABLE_MS,
 699                               host->addr + PAD_OUTPUT_ENABLE);
 700
 701                        msleep(10);
 702                        dev_dbg(&host->chip->pdev->dev, "power on\n");
 703                } else if (value == MEMSTICK_POWER_OFF) {
 704                        host_ctl &= ~(HOST_CONTROL_POWER_EN
 705                                      | HOST_CONTROL_CLOCK_EN);
 706                        writel(host_ctl, host->addr +  HOST_CONTROL);
 707                        writel(0, host->addr + PAD_OUTPUT_ENABLE);
 708                        writel(PAD_PU_PD_OFF, host->addr + PAD_PU_PD);
 709                        dev_dbg(&host->chip->pdev->dev, "power off\n");
 710                } else
 711                        return -EINVAL;
 712                break;
 713        case MEMSTICK_INTERFACE:
 714                host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
 715                pci_read_config_dword(host->chip->pdev,
 716                                      PCI_CTL_CLOCK_DLY_ADDR,
 717                                      &clock_delay);
 718                clock_delay &= host->id ? ~PCI_CTL_CLOCK_DLY_MASK_B
 719                                        : ~PCI_CTL_CLOCK_DLY_MASK_A;
 720
 721                if (value == MEMSTICK_SERIAL) {
 722                        host_ctl &= ~HOST_CONTROL_FAST_CLK;
 723                        host_ctl &= ~HOST_CONTROL_REO;
 724                        host_ctl |= HOST_CONTROL_IF_SERIAL
 725                                    << HOST_CONTROL_IF_SHIFT;
 726                        host_ctl |= HOST_CONTROL_REI;
 727                        clock_ctl = CLOCK_CONTROL_40MHZ;
 728                } else if (value == MEMSTICK_PAR4) {
 729                        host_ctl |= HOST_CONTROL_FAST_CLK | HOST_CONTROL_REO;
 730                        host_ctl |= HOST_CONTROL_IF_PAR4
 731                                    << HOST_CONTROL_IF_SHIFT;
 732                        host_ctl &= ~HOST_CONTROL_REI;
 733                        clock_ctl = CLOCK_CONTROL_40MHZ;
 734                        clock_delay |= host->id ? (4 << 12) : (4 << 8);
 735                } else if (value == MEMSTICK_PAR8) {
 736                        host_ctl |= HOST_CONTROL_FAST_CLK;
 737                        host_ctl |= HOST_CONTROL_IF_PAR8
 738                                    << HOST_CONTROL_IF_SHIFT;
 739                        host_ctl &= ~(HOST_CONTROL_REI | HOST_CONTROL_REO);
 740                        clock_ctl = CLOCK_CONTROL_50MHZ;
 741                } else
 742                        return -EINVAL;
 743
 744                writel(host_ctl, host->addr + HOST_CONTROL);
 745                writel(clock_ctl, host->addr + CLOCK_CONTROL);
 746                pci_write_config_dword(host->chip->pdev,
 747                                       PCI_CTL_CLOCK_DLY_ADDR,
 748                                       clock_delay);
 749                break;
 750        };
 751        return 0;
 752}
 753
 754#ifdef CONFIG_PM
 755
 756static int jmb38x_ms_suspend(struct pci_dev *dev, pm_message_t state)
 757{
 758        struct jmb38x_ms *jm = pci_get_drvdata(dev);
 759        int cnt;
 760
 761        for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
 762                if (!jm->hosts[cnt])
 763                        break;
 764                memstick_suspend_host(jm->hosts[cnt]);
 765        }
 766
 767        pci_save_state(dev);
 768        pci_enable_wake(dev, pci_choose_state(dev, state), 0);
 769        pci_disable_device(dev);
 770        pci_set_power_state(dev, pci_choose_state(dev, state));
 771        return 0;
 772}
 773
 774static int jmb38x_ms_resume(struct pci_dev *dev)
 775{
 776        struct jmb38x_ms *jm = pci_get_drvdata(dev);
 777        int rc;
 778
 779        pci_set_power_state(dev, PCI_D0);
 780        pci_restore_state(dev);
 781        rc = pci_enable_device(dev);
 782        if (rc)
 783                return rc;
 784        pci_set_master(dev);
 785
 786        pci_read_config_dword(dev, 0xac, &rc);
 787        pci_write_config_dword(dev, 0xac, rc | 0x00470000);
 788
 789        for (rc = 0; rc < jm->host_cnt; ++rc) {
 790                if (!jm->hosts[rc])
 791                        break;
 792                memstick_resume_host(jm->hosts[rc]);
 793                memstick_detect_change(jm->hosts[rc]);
 794        }
 795
 796        return 0;
 797}
 798
 799#else
 800
 801#define jmb38x_ms_suspend NULL
 802#define jmb38x_ms_resume NULL
 803
 804#endif /* CONFIG_PM */
 805
 806static int jmb38x_ms_count_slots(struct pci_dev *pdev)
 807{
 808        int cnt, rc = 0;
 809
 810        for (cnt = 0; cnt < PCI_ROM_RESOURCE; ++cnt) {
 811                if (!(IORESOURCE_MEM & pci_resource_flags(pdev, cnt)))
 812                        break;
 813
 814                if (256 != pci_resource_len(pdev, cnt))
 815                        break;
 816
 817                ++rc;
 818        }
 819        return rc;
 820}
 821
 822static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt)
 823{
 824        struct memstick_host *msh;
 825        struct jmb38x_ms_host *host;
 826
 827        msh = memstick_alloc_host(sizeof(struct jmb38x_ms_host),
 828                                  &jm->pdev->dev);
 829        if (!msh)
 830                return NULL;
 831
 832        host = memstick_priv(msh);
 833        host->chip = jm;
 834        host->addr = ioremap(pci_resource_start(jm->pdev, cnt),
 835                             pci_resource_len(jm->pdev, cnt));
 836        if (!host->addr)
 837                goto err_out_free;
 838
 839        spin_lock_init(&host->lock);
 840        host->id = cnt;
 841        snprintf(host->host_id, sizeof(host->host_id), DRIVER_NAME ":slot%d",
 842                 host->id);
 843        host->irq = jm->pdev->irq;
 844        host->timeout_jiffies = msecs_to_jiffies(1000);
 845
 846        tasklet_init(&host->notify, jmb38x_ms_req_tasklet, (unsigned long)msh);
 847        msh->request = jmb38x_ms_submit_req;
 848        msh->set_param = jmb38x_ms_set_param;
 849
 850        msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8;
 851
 852        setup_timer(&host->timer, jmb38x_ms_abort, (unsigned long)msh);
 853
 854        if (!request_irq(host->irq, jmb38x_ms_isr, IRQF_SHARED, host->host_id,
 855                         msh))
 856                return msh;
 857
 858        iounmap(host->addr);
 859err_out_free:
 860        kfree(msh);
 861        return NULL;
 862}
 863
 864static void jmb38x_ms_free_host(struct memstick_host *msh)
 865{
 866        struct jmb38x_ms_host *host = memstick_priv(msh);
 867
 868        free_irq(host->irq, msh);
 869        iounmap(host->addr);
 870        memstick_free_host(msh);
 871}
 872
 873static int jmb38x_ms_probe(struct pci_dev *pdev,
 874                           const struct pci_device_id *dev_id)
 875{
 876        struct jmb38x_ms *jm;
 877        int pci_dev_busy = 0;
 878        int rc, cnt;
 879
 880        rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 881        if (rc)
 882                return rc;
 883
 884        rc = pci_enable_device(pdev);
 885        if (rc)
 886                return rc;
 887
 888        pci_set_master(pdev);
 889
 890        rc = pci_request_regions(pdev, DRIVER_NAME);
 891        if (rc) {
 892                pci_dev_busy = 1;
 893                goto err_out;
 894        }
 895
 896        pci_read_config_dword(pdev, 0xac, &rc);
 897        pci_write_config_dword(pdev, 0xac, rc | 0x00470000);
 898
 899        cnt = jmb38x_ms_count_slots(pdev);
 900        if (!cnt) {
 901                rc = -ENODEV;
 902                pci_dev_busy = 1;
 903                goto err_out;
 904        }
 905
 906        jm = kzalloc(sizeof(struct jmb38x_ms)
 907                     + cnt * sizeof(struct memstick_host *), GFP_KERNEL);
 908        if (!jm) {
 909                rc = -ENOMEM;
 910                goto err_out_int;
 911        }
 912
 913        jm->pdev = pdev;
 914        jm->host_cnt = cnt;
 915        pci_set_drvdata(pdev, jm);
 916
 917        for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
 918                jm->hosts[cnt] = jmb38x_ms_alloc_host(jm, cnt);
 919                if (!jm->hosts[cnt])
 920                        break;
 921
 922                rc = memstick_add_host(jm->hosts[cnt]);
 923
 924                if (rc) {
 925                        jmb38x_ms_free_host(jm->hosts[cnt]);
 926                        jm->hosts[cnt] = NULL;
 927                        break;
 928                }
 929        }
 930
 931        if (cnt)
 932                return 0;
 933
 934        rc = -ENODEV;
 935
 936        pci_set_drvdata(pdev, NULL);
 937        kfree(jm);
 938err_out_int:
 939        pci_release_regions(pdev);
 940err_out:
 941        if (!pci_dev_busy)
 942                pci_disable_device(pdev);
 943        return rc;
 944}
 945
 946static void jmb38x_ms_remove(struct pci_dev *dev)
 947{
 948        struct jmb38x_ms *jm = pci_get_drvdata(dev);
 949        struct jmb38x_ms_host *host;
 950        int cnt;
 951        unsigned long flags;
 952
 953        for (cnt = 0; cnt < jm->host_cnt; ++cnt) {
 954                if (!jm->hosts[cnt])
 955                        break;
 956
 957                host = memstick_priv(jm->hosts[cnt]);
 958
 959                jm->hosts[cnt]->request = jmb38x_ms_dummy_submit;
 960                tasklet_kill(&host->notify);
 961                writel(0, host->addr + INT_SIGNAL_ENABLE);
 962                writel(0, host->addr + INT_STATUS_ENABLE);
 963                mmiowb();
 964                dev_dbg(&jm->pdev->dev, "interrupts off\n");
 965                spin_lock_irqsave(&host->lock, flags);
 966                if (host->req) {
 967                        host->req->error = -ETIME;
 968                        jmb38x_ms_complete_cmd(jm->hosts[cnt], 1);
 969                }
 970                spin_unlock_irqrestore(&host->lock, flags);
 971
 972                memstick_remove_host(jm->hosts[cnt]);
 973                dev_dbg(&jm->pdev->dev, "host removed\n");
 974
 975                jmb38x_ms_free_host(jm->hosts[cnt]);
 976        }
 977
 978        pci_set_drvdata(dev, NULL);
 979        pci_release_regions(dev);
 980        pci_disable_device(dev);
 981        kfree(jm);
 982}
 983
 984static struct pci_device_id jmb38x_ms_id_tbl [] = {
 985        { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS, PCI_ANY_ID,
 986          PCI_ANY_ID, 0, 0, 0 },
 987        { }
 988};
 989
 990static struct pci_driver jmb38x_ms_driver = {
 991        .name = DRIVER_NAME,
 992        .id_table = jmb38x_ms_id_tbl,
 993        .probe = jmb38x_ms_probe,
 994        .remove = jmb38x_ms_remove,
 995        .suspend = jmb38x_ms_suspend,
 996        .resume = jmb38x_ms_resume
 997};
 998
 999static int __init jmb38x_ms_init(void)
1000{
1001        return pci_register_driver(&jmb38x_ms_driver);
1002}
1003
1004static void __exit jmb38x_ms_exit(void)
1005{
1006        pci_unregister_driver(&jmb38x_ms_driver);
1007}
1008
1009MODULE_AUTHOR("Alex Dubov");
1010MODULE_DESCRIPTION("JMicron jmb38x MemoryStick driver");
1011MODULE_LICENSE("GPL");
1012MODULE_DEVICE_TABLE(pci, jmb38x_ms_id_tbl);
1013
1014module_init(jmb38x_ms_init);
1015module_exit(jmb38x_ms_exit);