OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [mtd/] [nand/] [alauda.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * MTD driver for Alauda chips
3
 *
4
 * Copyright (C) 2007 Joern Engel <joern@logfs.org>
5
 *
6
 * Based on drivers/usb/usb-skeleton.c which is:
7
 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
8
 * and on drivers/usb/storage/alauda.c, which is:
9
 *   (c) 2005 Daniel Drake <dsd@gentoo.org>
10
 *
11
 * Idea and initial work by Arnd Bergmann <arnd@arndb.de>
12
 */
13
#include <linux/kernel.h>
14
#include <linux/errno.h>
15
#include <linux/init.h>
16
#include <linux/slab.h>
17
#include <linux/module.h>
18
#include <linux/kref.h>
19
#include <linux/usb.h>
20
#include <linux/mutex.h>
21
#include <linux/mtd/mtd.h>
22
#include <linux/mtd/nand_ecc.h>
23
 
24
/* Control commands */
25
#define ALAUDA_GET_XD_MEDIA_STATUS      0x08
26
#define ALAUDA_ACK_XD_MEDIA_CHANGE      0x0a
27
#define ALAUDA_GET_XD_MEDIA_SIG         0x86
28
 
29
/* Common prefix */
30
#define ALAUDA_BULK_CMD                 0x40
31
 
32
/* The two ports */
33
#define ALAUDA_PORT_XD                  0x00
34
#define ALAUDA_PORT_SM                  0x01
35
 
36
/* Bulk commands */
37
#define ALAUDA_BULK_READ_PAGE           0x84
38
#define ALAUDA_BULK_READ_OOB            0x85 /* don't use, there's a chip bug */
39
#define ALAUDA_BULK_READ_BLOCK          0x94
40
#define ALAUDA_BULK_ERASE_BLOCK         0xa3
41
#define ALAUDA_BULK_WRITE_PAGE          0xa4
42
#define ALAUDA_BULK_WRITE_BLOCK         0xb4
43
#define ALAUDA_BULK_RESET_MEDIA         0xe0
44
 
45
/* Address shifting */
46
#define PBA_LO(pba) ((pba & 0xF) << 5)
47
#define PBA_HI(pba) (pba >> 3)
48
#define PBA_ZONE(pba) (pba >> 11)
49
 
50
#define TIMEOUT HZ
51
 
52
static struct usb_device_id alauda_table [] = {
53
        { USB_DEVICE(0x0584, 0x0008) }, /* Fujifilm DPC-R1 */
54
        { USB_DEVICE(0x07b4, 0x010a) }, /* Olympus MAUSB-10 */
55
        { }
56
};
57
MODULE_DEVICE_TABLE(usb, alauda_table);
58
 
59
struct alauda_card {
60
        u8      id;             /* id byte */
61
        u8      chipshift;      /* 1<<chipshift total size */
62
        u8      pageshift;      /* 1<<pageshift page size */
63
        u8      blockshift;     /* 1<<blockshift block size */
64
};
65
 
66
struct alauda {
67
        struct usb_device       *dev;
68
        struct usb_interface    *interface;
69
        struct mtd_info         *mtd;
70
        struct alauda_card      *card;
71
        struct mutex            card_mutex;
72
        u32                     pagemask;
73
        u32                     bytemask;
74
        u32                     blockmask;
75
        unsigned int            write_out;
76
        unsigned int            bulk_in;
77
        unsigned int            bulk_out;
78
        u8                      port;
79
        struct kref             kref;
80
};
81
 
82
static struct alauda_card alauda_card_ids[] = {
83
        /* NAND flash */
84
        { 0x6e, 20, 8, 12},     /* 1 MB */
85
        { 0xe8, 20, 8, 12},     /* 1 MB */
86
        { 0xec, 20, 8, 12},     /* 1 MB */
87
        { 0x64, 21, 8, 12},     /* 2 MB */
88
        { 0xea, 21, 8, 12},     /* 2 MB */
89
        { 0x6b, 22, 9, 13},     /* 4 MB */
90
        { 0xe3, 22, 9, 13},     /* 4 MB */
91
        { 0xe5, 22, 9, 13},     /* 4 MB */
92
        { 0xe6, 23, 9, 13},     /* 8 MB */
93
        { 0x73, 24, 9, 14},     /* 16 MB */
94
        { 0x75, 25, 9, 14},     /* 32 MB */
95
        { 0x76, 26, 9, 14},     /* 64 MB */
96
        { 0x79, 27, 9, 14},     /* 128 MB */
97
        { 0x71, 28, 9, 14},     /* 256 MB */
98
 
99
        /* MASK ROM */
100
        { 0x5d, 21, 9, 13},     /* 2 MB */
101
        { 0xd5, 22, 9, 13},     /* 4 MB */
102
        { 0xd6, 23, 9, 13},     /* 8 MB */
103
        { 0x57, 24, 9, 13},     /* 16 MB */
104
        { 0x58, 25, 9, 13},     /* 32 MB */
105
        { }
106
};
107
 
108
static struct alauda_card *get_card(u8 id)
109
{
110
        struct alauda_card *card;
111
 
112
        for (card = alauda_card_ids; card->id; card++)
113
                if (card->id == id)
114
                        return card;
115
        return NULL;
116
}
117
 
118
static void alauda_delete(struct kref *kref)
119
{
120
        struct alauda *al = container_of(kref, struct alauda, kref);
121
 
122
        if (al->mtd) {
123
                del_mtd_device(al->mtd);
124
                kfree(al->mtd);
125
        }
126
        usb_put_dev(al->dev);
127
        kfree(al);
128
}
129
 
130
static int alauda_get_media_status(struct alauda *al, void *buf)
131
{
132
        int ret;
133
 
134
        mutex_lock(&al->card_mutex);
135
        ret = usb_control_msg(al->dev, usb_rcvctrlpipe(al->dev, 0),
136
                        ALAUDA_GET_XD_MEDIA_STATUS, 0xc0, 0, 1, buf, 2, HZ);
137
        mutex_unlock(&al->card_mutex);
138
        return ret;
139
}
140
 
141
static int alauda_ack_media(struct alauda *al)
142
{
143
        int ret;
144
 
145
        mutex_lock(&al->card_mutex);
146
        ret = usb_control_msg(al->dev, usb_sndctrlpipe(al->dev, 0),
147
                        ALAUDA_ACK_XD_MEDIA_CHANGE, 0x40, 0, 1, NULL, 0, HZ);
148
        mutex_unlock(&al->card_mutex);
149
        return ret;
150
}
151
 
152
static int alauda_get_media_signatures(struct alauda *al, void *buf)
153
{
154
        int ret;
155
 
156
        mutex_lock(&al->card_mutex);
157
        ret = usb_control_msg(al->dev, usb_rcvctrlpipe(al->dev, 0),
158
                        ALAUDA_GET_XD_MEDIA_SIG, 0xc0, 0, 0, buf, 4, HZ);
159
        mutex_unlock(&al->card_mutex);
160
        return ret;
161
}
162
 
163
static void alauda_reset(struct alauda *al)
164
{
165
        u8 command[] = {
166
                ALAUDA_BULK_CMD, ALAUDA_BULK_RESET_MEDIA, 0, 0,
167
                0, 0, 0, 0, al->port
168
        };
169
        mutex_lock(&al->card_mutex);
170
        usb_bulk_msg(al->dev, al->bulk_out, command, 9, NULL, HZ);
171
        mutex_unlock(&al->card_mutex);
172
}
173
 
174
static void correct_data(void *buf, void *read_ecc,
175
                int *corrected, int *uncorrected)
176
{
177
        u8 calc_ecc[3];
178
        int err;
179
 
180
        nand_calculate_ecc(NULL, buf, calc_ecc);
181
        err = nand_correct_data(NULL, buf, read_ecc, calc_ecc);
182
        if (err) {
183
                if (err > 0)
184
                        (*corrected)++;
185
                else
186
                        (*uncorrected)++;
187
        }
188
}
189
 
190
struct alauda_sg_request {
191
        struct urb *urb[3];
192
        struct completion comp;
193
};
194
 
195
static void alauda_complete(struct urb *urb)
196
{
197
        struct completion *comp = urb->context;
198
 
199
        if (comp)
200
                complete(comp);
201
}
202
 
203
static int __alauda_read_page(struct mtd_info *mtd, loff_t from, void *buf,
204
                void *oob)
205
{
206
        struct alauda_sg_request sg;
207
        struct alauda *al = mtd->priv;
208
        u32 pba = from >> al->card->blockshift;
209
        u32 page = (from >> al->card->pageshift) & al->pagemask;
210
        u8 command[] = {
211
                ALAUDA_BULK_CMD, ALAUDA_BULK_READ_PAGE, PBA_HI(pba),
212
                PBA_ZONE(pba), 0, PBA_LO(pba) + page, 1, 0, al->port
213
        };
214
        int i, err;
215
 
216
        for (i=0; i<3; i++)
217
                sg.urb[i] = NULL;
218
 
219
        err = -ENOMEM;
220
        for (i=0; i<3; i++) {
221
                sg.urb[i] = usb_alloc_urb(0, GFP_NOIO);
222
                if (!sg.urb[i])
223
                        goto out;
224
        }
225
        init_completion(&sg.comp);
226
        usb_fill_bulk_urb(sg.urb[0], al->dev, al->bulk_out, command, 9,
227
                        alauda_complete, NULL);
228
        usb_fill_bulk_urb(sg.urb[1], al->dev, al->bulk_in, buf, mtd->writesize,
229
                        alauda_complete, NULL);
230
        usb_fill_bulk_urb(sg.urb[2], al->dev, al->bulk_in, oob, 16,
231
                        alauda_complete, &sg.comp);
232
 
233
        mutex_lock(&al->card_mutex);
234
        for (i=0; i<3; i++) {
235
                err = usb_submit_urb(sg.urb[i], GFP_NOIO);
236
                if (err)
237
                        goto cancel;
238
        }
239
        if (!wait_for_completion_timeout(&sg.comp, TIMEOUT)) {
240
                err = -ETIMEDOUT;
241
cancel:
242
                for (i=0; i<3; i++) {
243
                        usb_kill_urb(sg.urb[i]);
244
                }
245
        }
246
        mutex_unlock(&al->card_mutex);
247
 
248
out:
249
        usb_free_urb(sg.urb[0]);
250
        usb_free_urb(sg.urb[1]);
251
        usb_free_urb(sg.urb[2]);
252
        return err;
253
}
254
 
255
static int alauda_read_page(struct mtd_info *mtd, loff_t from,
256
                void *buf, u8 *oob, int *corrected, int *uncorrected)
257
{
258
        int err;
259
 
260
        err = __alauda_read_page(mtd, from, buf, oob);
261
        if (err)
262
                return err;
263
        correct_data(buf, oob+13, corrected, uncorrected);
264
        correct_data(buf+256, oob+8, corrected, uncorrected);
265
        return 0;
266
}
267
 
268
static int alauda_write_page(struct mtd_info *mtd, loff_t to, void *buf,
269
                void *oob)
270
{
271
        struct alauda_sg_request sg;
272
        struct alauda *al = mtd->priv;
273
        u32 pba = to >> al->card->blockshift;
274
        u32 page = (to >> al->card->pageshift) & al->pagemask;
275
        u8 command[] = {
276
                ALAUDA_BULK_CMD, ALAUDA_BULK_WRITE_PAGE, PBA_HI(pba),
277
                PBA_ZONE(pba), 0, PBA_LO(pba) + page, 32, 0, al->port
278
        };
279
        int i, err;
280
 
281
        for (i=0; i<3; i++)
282
                sg.urb[i] = NULL;
283
 
284
        err = -ENOMEM;
285
        for (i=0; i<3; i++) {
286
                sg.urb[i] = usb_alloc_urb(0, GFP_NOIO);
287
                if (!sg.urb[i])
288
                        goto out;
289
        }
290
        init_completion(&sg.comp);
291
        usb_fill_bulk_urb(sg.urb[0], al->dev, al->bulk_out, command, 9,
292
                        alauda_complete, NULL);
293
        usb_fill_bulk_urb(sg.urb[1], al->dev, al->write_out, buf,mtd->writesize,
294
                        alauda_complete, NULL);
295
        usb_fill_bulk_urb(sg.urb[2], al->dev, al->write_out, oob, 16,
296
                        alauda_complete, &sg.comp);
297
 
298
        mutex_lock(&al->card_mutex);
299
        for (i=0; i<3; i++) {
300
                err = usb_submit_urb(sg.urb[i], GFP_NOIO);
301
                if (err)
302
                        goto cancel;
303
        }
304
        if (!wait_for_completion_timeout(&sg.comp, TIMEOUT)) {
305
                err = -ETIMEDOUT;
306
cancel:
307
                for (i=0; i<3; i++) {
308
                        usb_kill_urb(sg.urb[i]);
309
                }
310
        }
311
        mutex_unlock(&al->card_mutex);
312
 
313
out:
314
        usb_free_urb(sg.urb[0]);
315
        usb_free_urb(sg.urb[1]);
316
        usb_free_urb(sg.urb[2]);
317
        return err;
318
}
319
 
320
static int alauda_erase_block(struct mtd_info *mtd, loff_t ofs)
321
{
322
        struct alauda_sg_request sg;
323
        struct alauda *al = mtd->priv;
324
        u32 pba = ofs >> al->card->blockshift;
325
        u8 command[] = {
326
                ALAUDA_BULK_CMD, ALAUDA_BULK_ERASE_BLOCK, PBA_HI(pba),
327
                PBA_ZONE(pba), 0, PBA_LO(pba), 0x02, 0, al->port
328
        };
329
        u8 buf[2];
330
        int i, err;
331
 
332
        for (i=0; i<2; i++)
333
                sg.urb[i] = NULL;
334
 
335
        err = -ENOMEM;
336
        for (i=0; i<2; i++) {
337
                sg.urb[i] = usb_alloc_urb(0, GFP_NOIO);
338
                if (!sg.urb[i])
339
                        goto out;
340
        }
341
        init_completion(&sg.comp);
342
        usb_fill_bulk_urb(sg.urb[0], al->dev, al->bulk_out, command, 9,
343
                        alauda_complete, NULL);
344
        usb_fill_bulk_urb(sg.urb[1], al->dev, al->bulk_in, buf, 2,
345
                        alauda_complete, &sg.comp);
346
 
347
        mutex_lock(&al->card_mutex);
348
        for (i=0; i<2; i++) {
349
                err = usb_submit_urb(sg.urb[i], GFP_NOIO);
350
                if (err)
351
                        goto cancel;
352
        }
353
        if (!wait_for_completion_timeout(&sg.comp, TIMEOUT)) {
354
                err = -ETIMEDOUT;
355
cancel:
356
                for (i=0; i<2; i++) {
357
                        usb_kill_urb(sg.urb[i]);
358
                }
359
        }
360
        mutex_unlock(&al->card_mutex);
361
 
362
out:
363
        usb_free_urb(sg.urb[0]);
364
        usb_free_urb(sg.urb[1]);
365
        return err;
366
}
367
 
368
static int alauda_read_oob(struct mtd_info *mtd, loff_t from, void *oob)
369
{
370
        static u8 ignore_buf[512]; /* write only */
371
 
372
        return __alauda_read_page(mtd, from, ignore_buf, oob);
373
}
374
 
375
static int popcount8(u8 c)
376
{
377
        int ret = 0;
378
 
379
        for ( ; c; c>>=1)
380
                ret += c & 1;
381
        return ret;
382
}
383
 
384
static int alauda_isbad(struct mtd_info *mtd, loff_t ofs)
385
{
386
        u8 oob[16];
387
        int err;
388
 
389
        err = alauda_read_oob(mtd, ofs, oob);
390
        if (err)
391
                return err;
392
 
393
        /* A block is marked bad if two or more bits are zero */
394
        return popcount8(oob[5]) >= 7 ? 0 : 1;
395
}
396
 
397
static int alauda_bounce_read(struct mtd_info *mtd, loff_t from, size_t len,
398
                size_t *retlen, u_char *buf)
399
{
400
        struct alauda *al = mtd->priv;
401
        void *bounce_buf;
402
        int err, corrected=0, uncorrected=0;
403
 
404
        bounce_buf = kmalloc(mtd->writesize, GFP_KERNEL);
405
        if (!bounce_buf)
406
                return -ENOMEM;
407
 
408
        *retlen = len;
409
        while (len) {
410
                u8 oob[16];
411
                size_t byte = from & al->bytemask;
412
                size_t cplen = min(len, mtd->writesize - byte);
413
 
414
                err = alauda_read_page(mtd, from, bounce_buf, oob,
415
                                &corrected, &uncorrected);
416
                if (err)
417
                        goto out;
418
 
419
                memcpy(buf, bounce_buf + byte, cplen);
420
                buf += cplen;
421
                from += cplen;
422
                len -= cplen;
423
        }
424
        err = 0;
425
        if (corrected)
426
                err = -EUCLEAN;
427
        if (uncorrected)
428
                err = -EBADMSG;
429
out:
430
        kfree(bounce_buf);
431
        return err;
432
}
433
 
434
static int alauda_read(struct mtd_info *mtd, loff_t from, size_t len,
435
                size_t *retlen, u_char *buf)
436
{
437
        struct alauda *al = mtd->priv;
438
        int err, corrected=0, uncorrected=0;
439
 
440
        if ((from & al->bytemask) || (len & al->bytemask))
441
                return alauda_bounce_read(mtd, from, len, retlen, buf);
442
 
443
        *retlen = len;
444
        while (len) {
445
                u8 oob[16];
446
 
447
                err = alauda_read_page(mtd, from, buf, oob,
448
                                &corrected, &uncorrected);
449
                if (err)
450
                        return err;
451
 
452
                buf += mtd->writesize;
453
                from += mtd->writesize;
454
                len -= mtd->writesize;
455
        }
456
        err = 0;
457
        if (corrected)
458
                err = -EUCLEAN;
459
        if (uncorrected)
460
                err = -EBADMSG;
461
        return err;
462
}
463
 
464
static int alauda_write(struct mtd_info *mtd, loff_t to, size_t len,
465
                size_t *retlen, const u_char *buf)
466
{
467
        struct alauda *al = mtd->priv;
468
        int err;
469
 
470
        if ((to & al->bytemask) || (len & al->bytemask))
471
                return -EINVAL;
472
 
473
        *retlen = len;
474
        while (len) {
475
                u32 page = (to >> al->card->pageshift) & al->pagemask;
476
                u8 oob[16] = {  'h', 'e', 'l', 'l', 'o', 0xff, 0xff, 0xff,
477
                                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
478
 
479
                /* don't write to bad blocks */
480
                if (page == 0) {
481
                        err = alauda_isbad(mtd, to);
482
                        if (err) {
483
                                return -EIO;
484
                        }
485
                }
486
                nand_calculate_ecc(mtd, buf, &oob[13]);
487
                nand_calculate_ecc(mtd, buf+256, &oob[8]);
488
 
489
                err = alauda_write_page(mtd, to, (void*)buf, oob);
490
                if (err)
491
                        return err;
492
 
493
                buf += mtd->writesize;
494
                to += mtd->writesize;
495
                len -= mtd->writesize;
496
        }
497
        return 0;
498
}
499
 
500
static int __alauda_erase(struct mtd_info *mtd, struct erase_info *instr)
501
{
502
        struct alauda *al = mtd->priv;
503
        u32 ofs = instr->addr;
504
        u32 len = instr->len;
505
        int err;
506
 
507
        if ((ofs & al->blockmask) || (len & al->blockmask))
508
                return -EINVAL;
509
 
510
        while (len) {
511
                /* don't erase bad blocks */
512
                err = alauda_isbad(mtd, ofs);
513
                if (err > 0)
514
                        err = -EIO;
515
                if (err < 0)
516
                        return err;
517
 
518
                err = alauda_erase_block(mtd, ofs);
519
                if (err < 0)
520
                        return err;
521
 
522
                ofs += mtd->erasesize;
523
                len -= mtd->erasesize;
524
        }
525
        return 0;
526
}
527
 
528
static int alauda_erase(struct mtd_info *mtd, struct erase_info *instr)
529
{
530
        int err;
531
 
532
        err = __alauda_erase(mtd, instr);
533
        instr->state = err ? MTD_ERASE_FAILED : MTD_ERASE_DONE;
534
        mtd_erase_callback(instr);
535
        return err;
536
}
537
 
538
static int alauda_init_media(struct alauda *al)
539
{
540
        u8 buf[4], *b0=buf, *b1=buf+1;
541
        struct alauda_card *card;
542
        struct mtd_info *mtd;
543
        int err;
544
 
545
        mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);
546
        if (!mtd)
547
                return -ENOMEM;
548
 
549
        for (;;) {
550
                err = alauda_get_media_status(al, buf);
551
                if (err < 0)
552
                        goto error;
553
                if (*b0 & 0x10)
554
                        break;
555
                msleep(20);
556
        }
557
 
558
        err = alauda_ack_media(al);
559
        if (err)
560
                goto error;
561
 
562
        msleep(10);
563
 
564
        err = alauda_get_media_status(al, buf);
565
        if (err < 0)
566
                goto error;
567
 
568
        if (*b0 != 0x14) {
569
                /* media not ready */
570
                err = -EIO;
571
                goto error;
572
        }
573
        err = alauda_get_media_signatures(al, buf);
574
        if (err < 0)
575
                goto error;
576
 
577
        card = get_card(*b1);
578
        if (!card) {
579
                printk(KERN_ERR"Alauda: unknown card id %02x\n", *b1);
580
                err = -EIO;
581
                goto error;
582
        }
583
        printk(KERN_INFO"pagesize=%x\nerasesize=%x\nsize=%xMiB\n",
584
                        1<<card->pageshift, 1<<card->blockshift,
585
                        1<<(card->chipshift-20));
586
        al->card = card;
587
        al->pagemask = (1 << (card->blockshift - card->pageshift)) - 1;
588
        al->bytemask = (1 << card->pageshift) - 1;
589
        al->blockmask = (1 << card->blockshift) - 1;
590
 
591
        mtd->name = "alauda";
592
        mtd->size = 1<<card->chipshift;
593
        mtd->erasesize = 1<<card->blockshift;
594
        mtd->writesize = 1<<card->pageshift;
595
        mtd->type = MTD_NANDFLASH;
596
        mtd->flags = MTD_CAP_NANDFLASH;
597
        mtd->read = alauda_read;
598
        mtd->write = alauda_write;
599
        mtd->erase = alauda_erase;
600
        mtd->block_isbad = alauda_isbad;
601
        mtd->priv = al;
602
        mtd->owner = THIS_MODULE;
603
 
604
        err = add_mtd_device(mtd);
605
        if (err) {
606
                err = -ENFILE;
607
                goto error;
608
        }
609
 
610
        al->mtd = mtd;
611
        alauda_reset(al); /* no clue whether this is necessary */
612
        return 0;
613
error:
614
        kfree(mtd);
615
        return err;
616
}
617
 
618
static int alauda_check_media(struct alauda *al)
619
{
620
        u8 buf[2], *b0 = buf, *b1 = buf+1;
621
        int err;
622
 
623
        err = alauda_get_media_status(al, buf);
624
        if (err < 0)
625
                return err;
626
 
627
        if ((*b1 & 0x01) == 0) {
628
                /* door open */
629
                return -EIO;
630
        }
631
        if ((*b0 & 0x80) || ((*b0 & 0x1F) == 0x10)) {
632
                /* no media ? */
633
                return -EIO;
634
        }
635
        if (*b0 & 0x08) {
636
                /* media change ? */
637
                return alauda_init_media(al);
638
        }
639
        return 0;
640
}
641
 
642
static int alauda_probe(struct usb_interface *interface,
643
                const struct usb_device_id *id)
644
{
645
        struct alauda *al;
646
        struct usb_host_interface *iface;
647
        struct usb_endpoint_descriptor *ep,
648
                        *ep_in=NULL, *ep_out=NULL, *ep_wr=NULL;
649
        int i, err = -ENOMEM;
650
 
651
        al = kzalloc(2*sizeof(*al), GFP_KERNEL);
652
        if (!al)
653
                goto error;
654
 
655
        kref_init(&al->kref);
656
        usb_set_intfdata(interface, al);
657
 
658
        al->dev = usb_get_dev(interface_to_usbdev(interface));
659
        al->interface = interface;
660
 
661
        iface = interface->cur_altsetting;
662
        for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
663
                ep = &iface->endpoint[i].desc;
664
 
665
                if (usb_endpoint_is_bulk_in(ep)) {
666
                        ep_in = ep;
667
                } else if (usb_endpoint_is_bulk_out(ep)) {
668
                        if (i==0)
669
                                ep_wr = ep;
670
                        else
671
                                ep_out = ep;
672
                }
673
        }
674
        err = -EIO;
675
        if (!ep_wr || !ep_in || !ep_out)
676
                goto error;
677
 
678
        al->write_out = usb_sndbulkpipe(al->dev,
679
                        ep_wr->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
680
        al->bulk_in = usb_rcvbulkpipe(al->dev,
681
                        ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
682
        al->bulk_out = usb_sndbulkpipe(al->dev,
683
                        ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
684
 
685
        /* second device is identical up to now */
686
        memcpy(al+1, al, sizeof(*al));
687
 
688
        mutex_init(&al[0].card_mutex);
689
        mutex_init(&al[1].card_mutex);
690
 
691
        al[0].port = ALAUDA_PORT_XD;
692
        al[1].port = ALAUDA_PORT_SM;
693
 
694
        info("alauda probed");
695
        alauda_check_media(al);
696
        alauda_check_media(al+1);
697
 
698
        return 0;
699
 
700
error:
701
        if (al)
702
                kref_put(&al->kref, alauda_delete);
703
        return err;
704
}
705
 
706
static void alauda_disconnect(struct usb_interface *interface)
707
{
708
        struct alauda *al;
709
 
710
        al = usb_get_intfdata(interface);
711
        usb_set_intfdata(interface, NULL);
712
 
713
        /* FIXME: prevent more I/O from starting */
714
 
715
        /* decrement our usage count */
716
        if (al)
717
                kref_put(&al->kref, alauda_delete);
718
 
719
        info("alauda gone");
720
}
721
 
722
static struct usb_driver alauda_driver = {
723
        .name =         "alauda",
724
        .probe =        alauda_probe,
725
        .disconnect =   alauda_disconnect,
726
        .id_table =     alauda_table,
727
};
728
 
729
static int __init alauda_init(void)
730
{
731
        return usb_register(&alauda_driver);
732
}
733
 
734
static void __exit alauda_exit(void)
735
{
736
        usb_deregister(&alauda_driver);
737
}
738
 
739
module_init(alauda_init);
740
module_exit(alauda_exit);
741
 
742
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.