tangled
alpha
login
or
join now
tjh.dev
/
kernel
Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1
fork
atom
overview
issues
pulls
pipelines
Merge master.kernel.org:/home/rmk/linux-2.6-mmc
Linus Torvalds
20 years ago
bd6fe9e1
862aad56
+229
-235
2 changed files
expand all
collapse all
unified
split
drivers
mmc
wbsd.c
wbsd.h
+218
-223
drivers/mmc/wbsd.c
···
93
93
static inline void wbsd_unlock_config(struct wbsd_host* host)
94
94
{
95
95
BUG_ON(host->config == 0);
96
96
-
96
96
+
97
97
outb(host->unlock_code, host->config);
98
98
outb(host->unlock_code, host->config);
99
99
}
···
101
101
static inline void wbsd_lock_config(struct wbsd_host* host)
102
102
{
103
103
BUG_ON(host->config == 0);
104
104
-
104
104
+
105
105
outb(LOCK_CODE, host->config);
106
106
}
107
107
108
108
static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value)
109
109
{
110
110
BUG_ON(host->config == 0);
111
111
-
111
111
+
112
112
outb(reg, host->config);
113
113
outb(value, host->config + 1);
114
114
}
···
116
116
static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg)
117
117
{
118
118
BUG_ON(host->config == 0);
119
119
-
119
119
+
120
120
outb(reg, host->config);
121
121
return inb(host->config + 1);
122
122
}
···
140
140
static void wbsd_init_device(struct wbsd_host* host)
141
141
{
142
142
u8 setup, ier;
143
143
-
143
143
+
144
144
/*
145
145
* Reset chip (SD/MMC part) and fifo.
146
146
*/
147
147
setup = wbsd_read_index(host, WBSD_IDX_SETUP);
148
148
setup |= WBSD_FIFO_RESET | WBSD_SOFT_RESET;
149
149
wbsd_write_index(host, WBSD_IDX_SETUP, setup);
150
150
-
150
150
+
151
151
/*
152
152
* Set DAT3 to input
153
153
*/
154
154
setup &= ~WBSD_DAT3_H;
155
155
wbsd_write_index(host, WBSD_IDX_SETUP, setup);
156
156
host->flags &= ~WBSD_FIGNORE_DETECT;
157
157
-
157
157
+
158
158
/*
159
159
* Read back default clock.
160
160
*/
···
164
164
* Power down port.
165
165
*/
166
166
outb(WBSD_POWER_N, host->base + WBSD_CSR);
167
167
-
167
167
+
168
168
/*
169
169
* Set maximum timeout.
170
170
*/
171
171
wbsd_write_index(host, WBSD_IDX_TAAC, 0x7F);
172
172
-
172
172
+
173
173
/*
174
174
* Test for card presence
175
175
*/
···
177
177
host->flags |= WBSD_FCARD_PRESENT;
178
178
else
179
179
host->flags &= ~WBSD_FCARD_PRESENT;
180
180
-
180
180
+
181
181
/*
182
182
* Enable interesting interrupts.
183
183
*/
···
200
200
static void wbsd_reset(struct wbsd_host* host)
201
201
{
202
202
u8 setup;
203
203
-
203
203
+
204
204
printk(KERN_ERR DRIVER_NAME ": Resetting chip\n");
205
205
-
205
205
+
206
206
/*
207
207
* Soft reset of chip (SD/MMC part).
208
208
*/
···
214
214
static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq)
215
215
{
216
216
unsigned long dmaflags;
217
217
-
217
217
+
218
218
DBGF("Ending request, cmd (%x)\n", mrq->cmd->opcode);
219
219
-
219
219
+
220
220
if (host->dma >= 0)
221
221
{
222
222
/*
···
232
232
*/
233
233
wbsd_write_index(host, WBSD_IDX_DMA, 0);
234
234
}
235
235
-
235
235
+
236
236
host->mrq = NULL;
237
237
238
238
/*
···
275
275
host->offset = 0;
276
276
host->remain = host->cur_sg->length;
277
277
}
278
278
-
278
278
+
279
279
return host->num_sg;
280
280
}
281
281
···
297
297
struct scatterlist* sg;
298
298
char* dmabuf = host->dma_buffer;
299
299
char* sgbuf;
300
300
-
300
300
+
301
301
size = host->size;
302
302
-
302
302
+
303
303
sg = data->sg;
304
304
len = data->sg_len;
305
305
-
305
305
+
306
306
/*
307
307
* Just loop through all entries. Size might not
308
308
* be the entire list though so make sure that
···
317
317
memcpy(dmabuf, sgbuf, sg[i].length);
318
318
kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
319
319
dmabuf += sg[i].length;
320
320
-
320
320
+
321
321
if (size < sg[i].length)
322
322
size = 0;
323
323
else
324
324
size -= sg[i].length;
325
325
-
325
325
+
326
326
if (size == 0)
327
327
break;
328
328
}
329
329
-
329
329
+
330
330
/*
331
331
* Check that we didn't get a request to transfer
332
332
* more data than can fit into the SG list.
333
333
*/
334
334
-
334
334
+
335
335
BUG_ON(size != 0);
336
336
-
336
336
+
337
337
host->size -= size;
338
338
}
339
339
···
343
343
struct scatterlist* sg;
344
344
char* dmabuf = host->dma_buffer;
345
345
char* sgbuf;
346
346
-
346
346
+
347
347
size = host->size;
348
348
-
348
348
+
349
349
sg = data->sg;
350
350
len = data->sg_len;
351
351
-
351
351
+
352
352
/*
353
353
* Just loop through all entries. Size might not
354
354
* be the entire list though so make sure that
···
363
363
memcpy(sgbuf, dmabuf, sg[i].length);
364
364
kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
365
365
dmabuf += sg[i].length;
366
366
-
366
366
+
367
367
if (size < sg[i].length)
368
368
size = 0;
369
369
else
370
370
size -= sg[i].length;
371
371
-
371
371
+
372
372
if (size == 0)
373
373
break;
374
374
}
375
375
-
375
375
+
376
376
/*
377
377
* Check that we didn't get a request to transfer
378
378
* more data than can fit into the SG list.
379
379
*/
380
380
-
380
380
+
381
381
BUG_ON(size != 0);
382
382
-
382
382
+
383
383
host->size -= size;
384
384
}
385
385
386
386
/*
387
387
* Command handling
388
388
*/
389
389
-
389
389
+
390
390
static inline void wbsd_get_short_reply(struct wbsd_host* host,
391
391
struct mmc_command* cmd)
392
392
{
···
398
398
cmd->error = MMC_ERR_INVALID;
399
399
return;
400
400
}
401
401
-
401
401
+
402
402
cmd->resp[0] =
403
403
wbsd_read_index(host, WBSD_IDX_RESP12) << 24;
404
404
cmd->resp[0] |=
···
415
415
struct mmc_command* cmd)
416
416
{
417
417
int i;
418
418
-
418
418
+
419
419
/*
420
420
* Correct response type?
421
421
*/
···
424
424
cmd->error = MMC_ERR_INVALID;
425
425
return;
426
426
}
427
427
-
427
427
+
428
428
for (i = 0;i < 4;i++)
429
429
{
430
430
cmd->resp[i] =
···
442
442
{
443
443
int i;
444
444
u8 status, isr;
445
445
-
445
445
+
446
446
DBGF("Sending cmd (%x)\n", cmd->opcode);
447
447
448
448
/*
···
451
451
* transfer.
452
452
*/
453
453
host->isr = 0;
454
454
-
454
454
+
455
455
/*
456
456
* Send the command (CRC calculated by host).
457
457
*/
458
458
outb(cmd->opcode, host->base + WBSD_CMDR);
459
459
for (i = 3;i >= 0;i--)
460
460
outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR);
461
461
-
461
461
+
462
462
cmd->error = MMC_ERR_NONE;
463
463
-
463
463
+
464
464
/*
465
465
* Wait for the request to complete.
466
466
*/
···
477
477
* Read back status.
478
478
*/
479
479
isr = host->isr;
480
480
-
480
480
+
481
481
/* Card removed? */
482
482
if (isr & WBSD_INT_CARD)
483
483
cmd->error = MMC_ERR_TIMEOUT;
···
509
509
struct mmc_data* data = host->mrq->cmd->data;
510
510
char* buffer;
511
511
int i, fsr, fifo;
512
512
-
512
512
+
513
513
/*
514
514
* Handle excessive data.
515
515
*/
516
516
if (data->bytes_xfered == host->size)
517
517
return;
518
518
-
518
518
+
519
519
buffer = wbsd_kmap_sg(host) + host->offset;
520
520
521
521
/*
···
527
527
/*
528
528
* The size field in the FSR is broken so we have to
529
529
* do some guessing.
530
530
-
*/
530
530
+
*/
531
531
if (fsr & WBSD_FIFO_FULL)
532
532
fifo = 16;
533
533
else if (fsr & WBSD_FIFO_FUTHRE)
534
534
fifo = 8;
535
535
else
536
536
fifo = 1;
537
537
-
537
537
+
538
538
for (i = 0;i < fifo;i++)
539
539
{
540
540
*buffer = inb(host->base + WBSD_DFR);
···
543
543
host->remain--;
544
544
545
545
data->bytes_xfered++;
546
546
-
546
546
+
547
547
/*
548
548
* Transfer done?
549
549
*/
550
550
if (data->bytes_xfered == host->size)
551
551
{
552
552
-
wbsd_kunmap_sg(host);
552
552
+
wbsd_kunmap_sg(host);
553
553
return;
554
554
}
555
555
-
555
555
+
556
556
/*
557
557
* End of scatter list entry?
558
558
*/
559
559
if (host->remain == 0)
560
560
{
561
561
wbsd_kunmap_sg(host);
562
562
-
562
562
+
563
563
/*
564
564
* Get next entry. Check if last.
565
565
*/
···
572
572
* into the scatter list.
573
573
*/
574
574
BUG_ON(1);
575
575
-
575
575
+
576
576
host->size = data->bytes_xfered;
577
577
-
577
577
+
578
578
return;
579
579
}
580
580
-
580
580
+
581
581
buffer = wbsd_kmap_sg(host);
582
582
}
583
583
}
584
584
}
585
585
-
585
585
+
586
586
wbsd_kunmap_sg(host);
587
587
588
588
/*
···
599
599
struct mmc_data* data = host->mrq->cmd->data;
600
600
char* buffer;
601
601
int i, fsr, fifo;
602
602
-
602
602
+
603
603
/*
604
604
* Check that we aren't being called after the
605
605
* entire buffer has been transfered.
···
618
618
/*
619
619
* The size field in the FSR is broken so we have to
620
620
* do some guessing.
621
621
-
*/
621
621
+
*/
622
622
if (fsr & WBSD_FIFO_EMPTY)
623
623
fifo = 0;
624
624
else if (fsr & WBSD_FIFO_EMTHRE)
···
632
632
buffer++;
633
633
host->offset++;
634
634
host->remain--;
635
635
-
635
635
+
636
636
data->bytes_xfered++;
637
637
-
637
637
+
638
638
/*
639
639
* Transfer done?
640
640
*/
···
650
650
if (host->remain == 0)
651
651
{
652
652
wbsd_kunmap_sg(host);
653
653
-
653
653
+
654
654
/*
655
655
* Get next entry. Check if last.
656
656
*/
···
663
663
* into the scatter list.
664
664
*/
665
665
BUG_ON(1);
666
666
-
666
666
+
667
667
host->size = data->bytes_xfered;
668
668
-
668
668
+
669
669
return;
670
670
}
671
671
-
671
671
+
672
672
buffer = wbsd_kmap_sg(host);
673
673
}
674
674
}
675
675
}
676
676
-
676
676
+
677
677
wbsd_kunmap_sg(host);
678
678
-
678
678
+
679
679
/*
680
680
* The controller stops sending interrupts for
681
681
* 'FIFO empty' under certain conditions. So we
···
694
694
1 << data->blksz_bits, data->blocks, data->flags);
695
695
DBGF("tsac %d ms nsac %d clk\n",
696
696
data->timeout_ns / 1000000, data->timeout_clks);
697
697
-
697
697
+
698
698
/*
699
699
* Calculate size.
700
700
*/
···
708
708
wbsd_write_index(host, WBSD_IDX_TAAC, 127);
709
709
else
710
710
wbsd_write_index(host, WBSD_IDX_TAAC, data->timeout_ns/1000000);
711
711
-
711
711
+
712
712
if (data->timeout_clks > 255)
713
713
wbsd_write_index(host, WBSD_IDX_NSAC, 255);
714
714
else
715
715
wbsd_write_index(host, WBSD_IDX_NSAC, data->timeout_clks);
716
716
-
716
716
+
717
717
/*
718
718
* Inform the chip of how large blocks will be
719
719
* sent. It needs this to determine when to
···
732
732
else if (host->bus_width == MMC_BUS_WIDTH_4)
733
733
{
734
734
blksize = (1 << data->blksz_bits) + 2 * 4;
735
735
-
735
735
+
736
736
wbsd_write_index(host, WBSD_IDX_PBSMSB, ((blksize >> 4) & 0xF0)
737
737
| WBSD_DATA_WIDTH);
738
738
wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
···
751
751
setup = wbsd_read_index(host, WBSD_IDX_SETUP);
752
752
setup |= WBSD_FIFO_RESET;
753
753
wbsd_write_index(host, WBSD_IDX_SETUP, setup);
754
754
-
754
754
+
755
755
/*
756
756
* DMA transfer?
757
757
*/
758
758
if (host->dma >= 0)
759
759
-
{
759
759
+
{
760
760
/*
761
761
* The buffer for DMA is only 64 kB.
762
762
*/
···
766
766
data->error = MMC_ERR_INVALID;
767
767
return;
768
768
}
769
769
-
769
769
+
770
770
/*
771
771
* Transfer data from the SG list to
772
772
* the DMA buffer.
773
773
*/
774
774
if (data->flags & MMC_DATA_WRITE)
775
775
wbsd_sg_to_dma(host, data);
776
776
-
776
776
+
777
777
/*
778
778
* Initialise the ISA DMA controller.
779
779
-
*/
779
779
+
*/
780
780
dmaflags = claim_dma_lock();
781
781
disable_dma(host->dma);
782
782
clear_dma_ff(host->dma);
···
802
802
* output to a minimum.
803
803
*/
804
804
host->firsterr = 1;
805
805
-
805
805
+
806
806
/*
807
807
* Initialise the SG list.
808
808
*/
809
809
wbsd_init_sg(host, data);
810
810
-
810
810
+
811
811
/*
812
812
* Turn off DMA.
813
813
*/
814
814
wbsd_write_index(host, WBSD_IDX_DMA, 0);
815
815
-
815
815
+
816
816
/*
817
817
* Set up FIFO threshold levels (and fill
818
818
* buffer if doing a write).
···
828
828
WBSD_FIFOEN_EMPTY | 8);
829
829
wbsd_fill_fifo(host);
830
830
}
831
831
-
}
832
832
-
831
831
+
}
832
832
+
833
833
data->error = MMC_ERR_NONE;
834
834
}
835
835
···
838
838
unsigned long dmaflags;
839
839
int count;
840
840
u8 status;
841
841
-
841
841
+
842
842
WARN_ON(host->mrq == NULL);
843
843
844
844
/*
···
855
855
{
856
856
status = wbsd_read_index(host, WBSD_IDX_STATUS);
857
857
} while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE));
858
858
-
858
858
+
859
859
/*
860
860
* DMA transfer?
861
861
*/
···
865
865
* Disable DMA on the host.
866
866
*/
867
867
wbsd_write_index(host, WBSD_IDX_DMA, 0);
868
868
-
868
868
+
869
869
/*
870
870
* Turn of ISA DMA controller.
871
871
*/
···
874
874
clear_dma_ff(host->dma);
875
875
count = get_dma_residue(host->dma);
876
876
release_dma_lock(dmaflags);
877
877
-
877
877
+
878
878
/*
879
879
* Any leftover data?
880
880
*/
···
882
882
{
883
883
printk(KERN_ERR DRIVER_NAME ": Incomplete DMA "
884
884
"transfer. %d bytes left.\n", count);
885
885
-
885
885
+
886
886
data->error = MMC_ERR_FAILED;
887
887
}
888
888
else
···
893
893
*/
894
894
if (data->flags & MMC_DATA_READ)
895
895
wbsd_dma_to_sg(host, data);
896
896
-
896
896
+
897
897
data->bytes_xfered = host->size;
898
898
}
899
899
}
900
900
-
900
900
+
901
901
DBGF("Ending data transfer (%d bytes)\n", data->bytes_xfered);
902
902
-
902
902
+
903
903
wbsd_request_end(host, host->mrq);
904
904
}
905
905
···
924
924
cmd = mrq->cmd;
925
925
926
926
host->mrq = mrq;
927
927
-
927
927
+
928
928
/*
929
929
* If there is no card in the slot then
930
930
* timeout immediatly.
···
941
941
if (cmd->data)
942
942
{
943
943
wbsd_prepare_data(host, cmd->data);
944
944
-
944
944
+
945
945
if (cmd->data->error != MMC_ERR_NONE)
946
946
goto done;
947
947
}
948
948
-
948
948
+
949
949
wbsd_send_command(host, cmd);
950
950
951
951
/*
952
952
* If this is a data transfer the request
953
953
* will be finished after the data has
954
954
* transfered.
955
955
-
*/
955
955
+
*/
956
956
if (cmd->data && (cmd->error == MMC_ERR_NONE))
957
957
{
958
958
/*
···
965
965
966
966
return;
967
967
}
968
968
-
968
968
+
969
969
done:
970
970
wbsd_request_end(host, mrq);
971
971
···
976
976
{
977
977
struct wbsd_host* host = mmc_priv(mmc);
978
978
u8 clk, setup, pwr;
979
979
-
979
979
+
980
980
DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n",
981
981
ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select,
982
982
ios->vdd, ios->bus_width);
···
989
989
*/
990
990
if (ios->power_mode == MMC_POWER_OFF)
991
991
wbsd_init_device(host);
992
992
-
992
992
+
993
993
if (ios->clock >= 24000000)
994
994
clk = WBSD_CLK_24M;
995
995
else if (ios->clock >= 16000000)
···
1042
1042
mod_timer(&host->ignore_timer, jiffies + HZ/100);
1043
1043
}
1044
1044
wbsd_write_index(host, WBSD_IDX_SETUP, setup);
1045
1045
-
1045
1045
+
1046
1046
/*
1047
1047
* Store bus width for later. Will be used when
1048
1048
* setting up the data transfer.
···
1128
1128
WARN_ON(!host->mrq->cmd->data);
1129
1129
if (!host->mrq->cmd->data)
1130
1130
return NULL;
1131
1131
-
1131
1131
+
1132
1132
return host->mrq->cmd->data;
1133
1133
}
1134
1134
···
1136
1136
{
1137
1137
struct wbsd_host* host = (struct wbsd_host*)param;
1138
1138
u8 csr;
1139
1139
-
1139
1139
+
int delay = -1;
1140
1140
+
1140
1141
spin_lock(&host->lock);
1141
1141
-
1142
1142
+
1142
1143
if (host->flags & WBSD_FIGNORE_DETECT)
1143
1144
{
1144
1145
spin_unlock(&host->lock);
1145
1146
return;
1146
1147
}
1147
1147
-
1148
1148
+
1148
1149
csr = inb(host->base + WBSD_CSR);
1149
1150
WARN_ON(csr == 0xff);
1150
1150
-
1151
1151
+
1151
1152
if (csr & WBSD_CARDPRESENT)
1152
1153
{
1153
1154
if (!(host->flags & WBSD_FCARD_PRESENT))
1154
1155
{
1155
1156
DBG("Card inserted\n");
1156
1157
host->flags |= WBSD_FCARD_PRESENT;
1157
1157
-
1158
1158
-
spin_unlock(&host->lock);
1159
1158
1160
1160
-
/*
1161
1161
-
* Delay card detection to allow electrical connections
1162
1162
-
* to stabilise.
1163
1163
-
*/
1164
1164
-
mmc_detect_change(host->mmc, msecs_to_jiffies(500));
1159
1159
+
delay = 500;
1165
1160
}
1166
1166
-
else
1167
1167
-
spin_unlock(&host->lock);
1168
1161
}
1169
1162
else if (host->flags & WBSD_FCARD_PRESENT)
1170
1163
{
1171
1164
DBG("Card removed\n");
1172
1165
host->flags &= ~WBSD_FCARD_PRESENT;
1173
1173
-
1166
1166
+
1174
1167
if (host->mrq)
1175
1168
{
1176
1169
printk(KERN_ERR DRIVER_NAME
1177
1170
": Card removed during transfer!\n");
1178
1171
wbsd_reset(host);
1179
1179
-
1172
1172
+
1180
1173
host->mrq->cmd->error = MMC_ERR_FAILED;
1181
1174
tasklet_schedule(&host->finish_tasklet);
1182
1175
}
1183
1183
-
1184
1184
-
/*
1185
1185
-
* Unlock first since we might get a call back.
1186
1186
-
*/
1187
1187
-
spin_unlock(&host->lock);
1188
1176
1189
1189
-
mmc_detect_change(host->mmc, 0);
1177
1177
+
delay = 0;
1190
1178
}
1191
1191
-
else
1192
1192
-
spin_unlock(&host->lock);
1179
1179
+
1180
1180
+
/*
1181
1181
+
* Unlock first since we might get a call back.
1182
1182
+
*/
1183
1183
+
1184
1184
+
spin_unlock(&host->lock);
1185
1185
+
1186
1186
+
if (delay != -1)
1187
1187
+
mmc_detect_change(host->mmc, msecs_to_jiffies(delay));
1193
1188
}
1194
1189
1195
1190
static void wbsd_tasklet_fifo(unsigned long param)
1196
1191
{
1197
1192
struct wbsd_host* host = (struct wbsd_host*)param;
1198
1193
struct mmc_data* data;
1199
1199
-
1194
1194
+
1200
1195
spin_lock(&host->lock);
1201
1201
-
1196
1196
+
1202
1197
if (!host->mrq)
1203
1198
goto end;
1204
1204
-
1199
1199
+
1205
1200
data = wbsd_get_data(host);
1206
1201
if (!data)
1207
1202
goto end;
···
1215
1220
tasklet_schedule(&host->finish_tasklet);
1216
1221
}
1217
1222
1218
1218
-
end:
1223
1223
+
end:
1219
1224
spin_unlock(&host->lock);
1220
1225
}
1221
1226
···
1223
1228
{
1224
1229
struct wbsd_host* host = (struct wbsd_host*)param;
1225
1230
struct mmc_data* data;
1226
1226
-
1231
1231
+
1227
1232
spin_lock(&host->lock);
1228
1228
-
1233
1233
+
1229
1234
if (!host->mrq)
1230
1235
goto end;
1231
1231
-
1236
1236
+
1232
1237
data = wbsd_get_data(host);
1233
1238
if (!data)
1234
1239
goto end;
1235
1235
-
1240
1240
+
1236
1241
DBGF("CRC error\n");
1237
1242
1238
1243
data->error = MMC_ERR_BADCRC;
1239
1239
-
1244
1244
+
1240
1245
tasklet_schedule(&host->finish_tasklet);
1241
1246
1242
1242
-
end:
1247
1247
+
end:
1243
1248
spin_unlock(&host->lock);
1244
1249
}
1245
1250
···
1247
1252
{
1248
1253
struct wbsd_host* host = (struct wbsd_host*)param;
1249
1254
struct mmc_data* data;
1250
1250
-
1255
1255
+
1251
1256
spin_lock(&host->lock);
1252
1252
-
1257
1257
+
1253
1258
if (!host->mrq)
1254
1259
goto end;
1255
1255
-
1260
1260
+
1256
1261
data = wbsd_get_data(host);
1257
1262
if (!data)
1258
1263
goto end;
1259
1259
-
1264
1264
+
1260
1265
DBGF("Timeout\n");
1261
1266
1262
1267
data->error = MMC_ERR_TIMEOUT;
1263
1263
-
1268
1268
+
1264
1269
tasklet_schedule(&host->finish_tasklet);
1265
1270
1266
1266
-
end:
1271
1271
+
end:
1267
1272
spin_unlock(&host->lock);
1268
1273
}
1269
1274
···
1271
1276
{
1272
1277
struct wbsd_host* host = (struct wbsd_host*)param;
1273
1278
struct mmc_data* data;
1274
1274
-
1279
1279
+
1275
1280
spin_lock(&host->lock);
1276
1276
-
1281
1281
+
1277
1282
WARN_ON(!host->mrq);
1278
1283
if (!host->mrq)
1279
1284
goto end;
1280
1280
-
1285
1285
+
1281
1286
data = wbsd_get_data(host);
1282
1287
if (!data)
1283
1288
goto end;
1284
1289
1285
1290
wbsd_finish_data(host, data);
1286
1286
-
1287
1287
-
end:
1291
1291
+
1292
1292
+
end:
1288
1293
spin_unlock(&host->lock);
1289
1294
}
1290
1295
···
1292
1297
{
1293
1298
struct wbsd_host* host = (struct wbsd_host*)param;
1294
1299
struct mmc_data* data;
1295
1295
-
1300
1300
+
1296
1301
spin_lock(&host->lock);
1297
1302
1298
1303
if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) !=
···
1301
1306
data = wbsd_get_data(host);
1302
1307
if (!data)
1303
1308
goto end;
1304
1304
-
1309
1309
+
1305
1310
DBGF("CRC error\n");
1306
1311
1307
1312
data->error = MMC_ERR_BADCRC;
1308
1308
-
1313
1313
+
1309
1314
tasklet_schedule(&host->finish_tasklet);
1310
1315
}
1311
1316
1312
1312
-
end:
1317
1317
+
end:
1313
1318
spin_unlock(&host->lock);
1314
1319
}
1315
1320
···
1321
1326
{
1322
1327
struct wbsd_host* host = dev_id;
1323
1328
int isr;
1324
1324
-
1329
1329
+
1325
1330
isr = inb(host->base + WBSD_ISR);
1326
1331
1327
1332
/*
···
1329
1334
*/
1330
1335
if (isr == 0xff || isr == 0x00)
1331
1336
return IRQ_NONE;
1332
1332
-
1337
1337
+
1333
1338
host->isr |= isr;
1334
1339
1335
1340
/*
···
1347
1352
tasklet_hi_schedule(&host->block_tasklet);
1348
1353
if (isr & WBSD_INT_TC)
1349
1354
tasklet_schedule(&host->finish_tasklet);
1350
1350
-
1355
1355
+
1351
1356
return IRQ_HANDLED;
1352
1357
}
1353
1358
···
1365
1370
{
1366
1371
struct mmc_host* mmc;
1367
1372
struct wbsd_host* host;
1368
1368
-
1373
1373
+
1369
1374
/*
1370
1375
* Allocate MMC structure.
1371
1376
*/
1372
1377
mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev);
1373
1378
if (!mmc)
1374
1379
return -ENOMEM;
1375
1375
-
1380
1380
+
1376
1381
host = mmc_priv(mmc);
1377
1382
host->mmc = mmc;
1378
1383
···
1386
1391
mmc->f_max = 24000000;
1387
1392
mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
1388
1393
mmc->caps = MMC_CAP_4_BIT_DATA;
1389
1389
-
1394
1394
+
1390
1395
spin_lock_init(&host->lock);
1391
1391
-
1396
1396
+
1392
1397
/*
1393
1398
* Set up timers
1394
1399
*/
1395
1400
init_timer(&host->ignore_timer);
1396
1401
host->ignore_timer.data = (unsigned long)host;
1397
1402
host->ignore_timer.function = wbsd_reset_ignore;
1398
1398
-
1403
1403
+
1399
1404
/*
1400
1405
* Maximum number of segments. Worst case is one sector per segment
1401
1406
* so this will be 64kB/512.
1402
1407
*/
1403
1408
mmc->max_hw_segs = 128;
1404
1409
mmc->max_phys_segs = 128;
1405
1405
-
1410
1410
+
1406
1411
/*
1407
1412
* Maximum number of sectors in one transfer. Also limited by 64kB
1408
1413
* buffer.
1409
1414
*/
1410
1415
mmc->max_sectors = 128;
1411
1411
-
1416
1416
+
1412
1417
/*
1413
1418
* Maximum segment size. Could be one segment with the maximum number
1414
1419
* of segments.
1415
1420
*/
1416
1421
mmc->max_seg_size = mmc->max_sectors * 512;
1417
1417
-
1422
1422
+
1418
1423
dev_set_drvdata(dev, mmc);
1419
1419
-
1424
1424
+
1420
1425
return 0;
1421
1426
}
1422
1427
···
1424
1429
{
1425
1430
struct mmc_host* mmc;
1426
1431
struct wbsd_host* host;
1427
1427
-
1432
1432
+
1428
1433
mmc = dev_get_drvdata(dev);
1429
1434
if (!mmc)
1430
1435
return;
1431
1431
-
1436
1436
+
1432
1437
host = mmc_priv(mmc);
1433
1438
BUG_ON(host == NULL);
1434
1434
-
1439
1439
+
1435
1440
del_timer_sync(&host->ignore_timer);
1436
1436
-
1441
1441
+
1437
1442
mmc_free_host(mmc);
1438
1438
-
1443
1443
+
1439
1444
dev_set_drvdata(dev, NULL);
1440
1445
}
1441
1446
···
1447
1452
{
1448
1453
int i, j, k;
1449
1454
int id;
1450
1450
-
1455
1455
+
1451
1456
/*
1452
1457
* Iterate through all ports, all codes to
1453
1458
* find hardware that is in our known list.
···
1456
1461
{
1457
1462
if (!request_region(config_ports[i], 2, DRIVER_NAME))
1458
1463
continue;
1459
1459
-
1464
1464
+
1460
1465
for (j = 0;j < sizeof(unlock_codes)/sizeof(int);j++)
1461
1466
{
1462
1467
id = 0xFFFF;
1463
1463
-
1468
1468
+
1464
1469
outb(unlock_codes[j], config_ports[i]);
1465
1470
outb(unlock_codes[j], config_ports[i]);
1466
1466
-
1471
1471
+
1467
1472
outb(WBSD_CONF_ID_HI, config_ports[i]);
1468
1473
id = inb(config_ports[i] + 1) << 8;
1469
1474
1470
1475
outb(WBSD_CONF_ID_LO, config_ports[i]);
1471
1476
id |= inb(config_ports[i] + 1);
1472
1472
-
1477
1477
+
1473
1478
for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++)
1474
1479
{
1475
1480
if (id == valid_ids[k])
1476
1476
-
{
1481
1481
+
{
1477
1482
host->chip_id = id;
1478
1483
host->config = config_ports[i];
1479
1484
host->unlock_code = unlock_codes[i];
1480
1480
-
1485
1485
+
1481
1486
return 0;
1482
1487
}
1483
1488
}
1484
1484
-
1489
1489
+
1485
1490
if (id != 0xFFFF)
1486
1491
{
1487
1492
DBG("Unknown hardware (id %x) found at %x\n",
···
1490
1495
1491
1496
outb(LOCK_CODE, config_ports[i]);
1492
1497
}
1493
1493
-
1498
1498
+
1494
1499
release_region(config_ports[i], 2);
1495
1500
}
1496
1496
-
1501
1501
+
1497
1502
return -ENODEV;
1498
1503
}
1499
1504
···
1505
1510
{
1506
1511
if (io & 0x7)
1507
1512
return -EINVAL;
1508
1508
-
1513
1513
+
1509
1514
if (!request_region(base, 8, DRIVER_NAME))
1510
1515
return -EIO;
1511
1511
-
1516
1516
+
1512
1517
host->base = io;
1513
1513
-
1518
1518
+
1514
1519
return 0;
1515
1520
}
1516
1521
···
1518
1523
{
1519
1524
if (host->base)
1520
1525
release_region(host->base, 8);
1521
1521
-
1526
1526
+
1522
1527
host->base = 0;
1523
1528
1524
1529
if (host->config)
1525
1530
release_region(host->config, 2);
1526
1526
-
1531
1531
+
1527
1532
host->config = 0;
1528
1533
}
1529
1534
···
1535
1540
{
1536
1541
if (dma < 0)
1537
1542
return;
1538
1538
-
1543
1543
+
1539
1544
if (request_dma(dma, DRIVER_NAME))
1540
1545
goto err;
1541
1541
-
1546
1546
+
1542
1547
/*
1543
1548
* We need to allocate a special buffer in
1544
1549
* order for ISA to be able to DMA to it.
···
1553
1558
*/
1554
1559
host->dma_addr = dma_map_single(host->mmc->dev, host->dma_buffer,
1555
1560
WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
1556
1556
-
1561
1561
+
1557
1562
/*
1558
1563
* ISA DMA must be aligned on a 64k basis.
1559
1564
*/
···
1566
1571
goto kfree;
1567
1572
1568
1573
host->dma = dma;
1569
1569
-
1574
1574
+
1570
1575
return;
1571
1571
-
1576
1576
+
1572
1577
kfree:
1573
1578
/*
1574
1579
* If we've gotten here then there is some kind of alignment bug
1575
1580
*/
1576
1581
BUG_ON(1);
1577
1577
-
1582
1582
+
1578
1583
dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
1579
1584
DMA_BIDIRECTIONAL);
1580
1585
host->dma_addr = (dma_addr_t)NULL;
1581
1581
-
1586
1586
+
1582
1587
kfree(host->dma_buffer);
1583
1588
host->dma_buffer = NULL;
1584
1589
···
1599
1604
kfree(host->dma_buffer);
1600
1605
if (host->dma >= 0)
1601
1606
free_dma(host->dma);
1602
1602
-
1607
1607
+
1603
1608
host->dma = -1;
1604
1609
host->dma_buffer = NULL;
1605
1610
host->dma_addr = (dma_addr_t)NULL;
···
1612
1617
static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
1613
1618
{
1614
1619
int ret;
1615
1615
-
1620
1620
+
1616
1621
/*
1617
1622
* Allocate interrupt.
1618
1623
*/
···
1620
1625
ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host);
1621
1626
if (ret)
1622
1627
return ret;
1623
1623
-
1628
1628
+
1624
1629
host->irq = irq;
1625
1630
1626
1631
/*
···
1632
1637
tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host);
1633
1638
tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host);
1634
1639
tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host);
1635
1635
-
1640
1640
+
1636
1641
return 0;
1637
1642
}
1638
1643
···
1642
1647
return;
1643
1648
1644
1649
free_irq(host->irq, host);
1645
1645
-
1650
1650
+
1646
1651
host->irq = 0;
1647
1647
-
1652
1652
+
1648
1653
tasklet_kill(&host->card_tasklet);
1649
1654
tasklet_kill(&host->fifo_tasklet);
1650
1655
tasklet_kill(&host->crc_tasklet);
···
1661
1666
int base, int irq, int dma)
1662
1667
{
1663
1668
int ret;
1664
1664
-
1669
1669
+
1665
1670
/*
1666
1671
* Allocate I/O ports.
1667
1672
*/
···
1680
1685
* Allocate DMA.
1681
1686
*/
1682
1687
wbsd_request_dma(host, dma);
1683
1683
-
1688
1688
+
1684
1689
return 0;
1685
1690
}
1686
1691
···
1703
1708
{
1704
1709
/*
1705
1710
* Reset the chip.
1706
1706
-
*/
1711
1711
+
*/
1707
1712
wbsd_write_config(host, WBSD_CONF_SWRST, 1);
1708
1713
wbsd_write_config(host, WBSD_CONF_SWRST, 0);
1709
1714
···
1711
1716
* Select SD/MMC function.
1712
1717
*/
1713
1718
wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
1714
1714
-
1719
1719
+
1715
1720
/*
1716
1721
* Set up card detection.
1717
1722
*/
1718
1723
wbsd_write_config(host, WBSD_CONF_PINS, WBSD_PINS_DETECT_GP11);
1719
1719
-
1724
1724
+
1720
1725
/*
1721
1726
* Configure chip
1722
1727
*/
1723
1728
wbsd_write_config(host, WBSD_CONF_PORT_HI, host->base >> 8);
1724
1729
wbsd_write_config(host, WBSD_CONF_PORT_LO, host->base & 0xff);
1725
1725
-
1730
1730
+
1726
1731
wbsd_write_config(host, WBSD_CONF_IRQ, host->irq);
1727
1727
-
1732
1732
+
1728
1733
if (host->dma >= 0)
1729
1734
wbsd_write_config(host, WBSD_CONF_DRQ, host->dma);
1730
1730
-
1735
1735
+
1731
1736
/*
1732
1737
* Enable and power up chip.
1733
1738
*/
···
1738
1743
/*
1739
1744
* Check that configured resources are correct.
1740
1745
*/
1741
1741
-
1746
1746
+
1742
1747
static int __devinit wbsd_chip_validate(struct wbsd_host* host)
1743
1748
{
1744
1749
int base, irq, dma;
1745
1745
-
1750
1750
+
1746
1751
/*
1747
1752
* Select SD/MMC function.
1748
1753
*/
1749
1754
wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
1750
1750
-
1755
1755
+
1751
1756
/*
1752
1757
* Read configuration.
1753
1758
*/
1754
1759
base = wbsd_read_config(host, WBSD_CONF_PORT_HI) << 8;
1755
1760
base |= wbsd_read_config(host, WBSD_CONF_PORT_LO);
1756
1756
-
1761
1761
+
1757
1762
irq = wbsd_read_config(host, WBSD_CONF_IRQ);
1758
1758
-
1763
1763
+
1759
1764
dma = wbsd_read_config(host, WBSD_CONF_DRQ);
1760
1760
-
1765
1765
+
1761
1766
/*
1762
1767
* Validate against given configuration.
1763
1768
*/
···
1767
1772
return 0;
1768
1773
if ((dma != host->dma) && (host->dma != -1))
1769
1774
return 0;
1770
1770
-
1775
1775
+
1771
1776
return 1;
1772
1777
}
1773
1778
···
1783
1788
struct wbsd_host* host = NULL;
1784
1789
struct mmc_host* mmc = NULL;
1785
1790
int ret;
1786
1786
-
1791
1791
+
1787
1792
ret = wbsd_alloc_mmc(dev);
1788
1793
if (ret)
1789
1794
return ret;
1790
1790
-
1795
1795
+
1791
1796
mmc = dev_get_drvdata(dev);
1792
1797
host = mmc_priv(mmc);
1793
1793
-
1798
1798
+
1794
1799
/*
1795
1800
* Scan for hardware.
1796
1801
*/
···
1809
1814
return ret;
1810
1815
}
1811
1816
}
1812
1812
-
1817
1817
+
1813
1818
/*
1814
1819
* Request resources.
1815
1820
*/
···
1820
1825
wbsd_free_mmc(dev);
1821
1826
return ret;
1822
1827
}
1823
1823
-
1828
1828
+
1824
1829
/*
1825
1830
* See if chip needs to be configured.
1826
1831
*/
···
1837
1842
}
1838
1843
else
1839
1844
wbsd_chip_config(host);
1840
1840
-
1845
1845
+
1841
1846
/*
1842
1847
* Power Management stuff. No idea how this works.
1843
1848
* Not tested.
···
1855
1860
* Reset the chip into a known state.
1856
1861
*/
1857
1862
wbsd_init_device(host);
1858
1858
-
1863
1863
+
1859
1864
mmc_add_host(mmc);
1860
1865
1861
1866
printk(KERN_INFO "%s: W83L51xD", mmc_hostname(mmc));
···
1877
1882
{
1878
1883
struct mmc_host* mmc = dev_get_drvdata(dev);
1879
1884
struct wbsd_host* host;
1880
1880
-
1885
1885
+
1881
1886
if (!mmc)
1882
1887
return;
1883
1888
1884
1889
host = mmc_priv(mmc);
1885
1885
-
1890
1890
+
1886
1891
mmc_remove_host(mmc);
1887
1892
1888
1893
if (!pnp)
···
1895
1900
wbsd_write_config(host, WBSD_CONF_ENABLE, 0);
1896
1901
wbsd_lock_config(host);
1897
1902
}
1898
1898
-
1903
1903
+
1899
1904
wbsd_release_resources(host);
1900
1900
-
1905
1905
+
1901
1906
wbsd_free_mmc(dev);
1902
1907
}
1903
1908
···
1927
1932
wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id)
1928
1933
{
1929
1934
int io, irq, dma;
1930
1930
-
1935
1935
+
1931
1936
/*
1932
1937
* Get resources from PnP layer.
1933
1938
*/
···
1937
1942
dma = pnp_dma(pnpdev, 0);
1938
1943
else
1939
1944
dma = -1;
1940
1940
-
1945
1945
+
1941
1946
DBGF("PnP resources: port %3x irq %d dma %d\n", io, irq, dma);
1942
1942
-
1947
1947
+
1943
1948
return wbsd_init(&pnpdev->dev, io, irq, dma, 1);
1944
1949
}
1945
1950
···
1980
1985
.bus = &platform_bus_type,
1981
1986
.probe = wbsd_probe,
1982
1987
.remove = wbsd_remove,
1983
1983
-
1988
1988
+
1984
1989
.suspend = wbsd_suspend,
1985
1990
.resume = wbsd_resume,
1986
1991
};
···
2003
2008
static int __init wbsd_drv_init(void)
2004
2009
{
2005
2010
int result;
2006
2006
-
2011
2011
+
2007
2012
printk(KERN_INFO DRIVER_NAME
2008
2013
": Winbond W83L51xD SD/MMC card interface driver, "
2009
2014
DRIVER_VERSION "\n");
···
2018
2023
return result;
2019
2024
}
2020
2025
2021
2021
-
#endif /* CONFIG_PNP */
2022
2022
-
2026
2026
+
#endif /* CONFIG_PNP */
2027
2027
+
2023
2028
if (nopnp)
2024
2029
{
2025
2030
result = driver_register(&wbsd_driver);
···
2041
2046
2042
2047
if (!nopnp)
2043
2048
pnp_unregister_driver(&wbsd_pnp_driver);
2044
2044
-
2045
2045
-
#endif /* CONFIG_PNP */
2049
2049
+
2050
2050
+
#endif /* CONFIG_PNP */
2046
2051
2047
2052
if (nopnp)
2048
2053
{
2049
2054
platform_device_unregister(wbsd_device);
2050
2050
-
2055
2055
+
2051
2056
driver_unregister(&wbsd_driver);
2052
2057
}
2053
2058
+11
-12
drivers/mmc/wbsd.h
···
139
139
struct wbsd_host
140
140
{
141
141
struct mmc_host* mmc; /* MMC structure */
142
142
-
142
142
+
143
143
spinlock_t lock; /* Mutex */
144
144
145
145
int flags; /* Driver states */
146
146
147
147
#define WBSD_FCARD_PRESENT (1<<0) /* Card is present */
148
148
#define WBSD_FIGNORE_DETECT (1<<1) /* Ignore card detection */
149
149
-
149
149
+
150
150
struct mmc_request* mrq; /* Current request */
151
151
-
151
151
+
152
152
u8 isr; /* Accumulated ISR */
153
153
-
153
153
+
154
154
struct scatterlist* cur_sg; /* Current SG entry */
155
155
unsigned int num_sg; /* Number of entries left */
156
156
void* mapped_sg; /* vaddr of mapped sg */
157
157
-
157
157
+
158
158
unsigned int offset; /* Offset into current entry */
159
159
unsigned int remain; /* Data left in curren entry */
160
160
161
161
int size; /* Total size of transfer */
162
162
-
162
162
+
163
163
char* dma_buffer; /* ISA DMA buffer */
164
164
dma_addr_t dma_addr; /* Physical address for same */
165
165
166
166
int firsterr; /* See fifo functions */
167
167
-
167
167
+
168
168
u8 clk; /* Current clock speed */
169
169
unsigned char bus_width; /* Current bus width */
170
170
-
170
170
+
171
171
int config; /* Config port */
172
172
u8 unlock_code; /* Code to unlock config */
173
173
174
174
int chip_id; /* ID of controller */
175
175
-
175
175
+
176
176
int base; /* I/O port base */
177
177
int irq; /* Interrupt */
178
178
int dma; /* DMA channel */
179
179
-
179
179
+
180
180
struct tasklet_struct card_tasklet; /* Tasklet structures */
181
181
struct tasklet_struct fifo_tasklet;
182
182
struct tasklet_struct crc_tasklet;
183
183
struct tasklet_struct timeout_tasklet;
184
184
struct tasklet_struct finish_tasklet;
185
185
struct tasklet_struct block_tasklet;
186
186
-
187
187
-
struct timer_list detect_timer; /* Card detection timer */
186
186
+
188
187
struct timer_list ignore_timer; /* Ignore detection timer */
189
188
};