Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/ide/ide-atapi.c
15109 views
1
/*
2
* ATAPI support.
3
*/
4
5
#include <linux/kernel.h>
6
#include <linux/cdrom.h>
7
#include <linux/delay.h>
8
#include <linux/ide.h>
9
#include <linux/scatterlist.h>
10
#include <linux/gfp.h>
11
12
#include <scsi/scsi.h>
13
14
#define DRV_NAME "ide-atapi"
15
#define PFX DRV_NAME ": "
16
17
#ifdef DEBUG
18
#define debug_log(fmt, args...) \
19
printk(KERN_INFO "ide: " fmt, ## args)
20
#else
21
#define debug_log(fmt, args...) do {} while (0)
22
#endif
23
24
#define ATAPI_MIN_CDB_BYTES 12
25
26
static inline int dev_is_idecd(ide_drive_t *drive)
27
{
28
return drive->media == ide_cdrom || drive->media == ide_optical;
29
}
30
31
/*
32
* Check whether we can support a device,
33
* based on the ATAPI IDENTIFY command results.
34
*/
35
int ide_check_atapi_device(ide_drive_t *drive, const char *s)
36
{
37
u16 *id = drive->id;
38
u8 gcw[2], protocol, device_type, removable, drq_type, packet_size;
39
40
*((u16 *)&gcw) = id[ATA_ID_CONFIG];
41
42
protocol = (gcw[1] & 0xC0) >> 6;
43
device_type = gcw[1] & 0x1F;
44
removable = (gcw[0] & 0x80) >> 7;
45
drq_type = (gcw[0] & 0x60) >> 5;
46
packet_size = gcw[0] & 0x03;
47
48
#ifdef CONFIG_PPC
49
/* kludge for Apple PowerBook internal zip */
50
if (drive->media == ide_floppy && device_type == 5 &&
51
!strstr((char *)&id[ATA_ID_PROD], "CD-ROM") &&
52
strstr((char *)&id[ATA_ID_PROD], "ZIP"))
53
device_type = 0;
54
#endif
55
56
if (protocol != 2)
57
printk(KERN_ERR "%s: %s: protocol (0x%02x) is not ATAPI\n",
58
s, drive->name, protocol);
59
else if ((drive->media == ide_floppy && device_type != 0) ||
60
(drive->media == ide_tape && device_type != 1))
61
printk(KERN_ERR "%s: %s: invalid device type (0x%02x)\n",
62
s, drive->name, device_type);
63
else if (removable == 0)
64
printk(KERN_ERR "%s: %s: the removable flag is not set\n",
65
s, drive->name);
66
else if (drive->media == ide_floppy && drq_type == 3)
67
printk(KERN_ERR "%s: %s: sorry, DRQ type (0x%02x) not "
68
"supported\n", s, drive->name, drq_type);
69
else if (packet_size != 0)
70
printk(KERN_ERR "%s: %s: packet size (0x%02x) is not 12 "
71
"bytes\n", s, drive->name, packet_size);
72
else
73
return 1;
74
return 0;
75
}
76
EXPORT_SYMBOL_GPL(ide_check_atapi_device);
77
78
void ide_init_pc(struct ide_atapi_pc *pc)
79
{
80
memset(pc, 0, sizeof(*pc));
81
}
82
EXPORT_SYMBOL_GPL(ide_init_pc);
83
84
/*
85
* Add a special packet command request to the tail of the request queue,
86
* and wait for it to be serviced.
87
*/
88
int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
89
struct ide_atapi_pc *pc, void *buf, unsigned int bufflen)
90
{
91
struct request *rq;
92
int error;
93
94
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
95
rq->cmd_type = REQ_TYPE_SPECIAL;
96
rq->special = (char *)pc;
97
98
if (buf && bufflen) {
99
error = blk_rq_map_kern(drive->queue, rq, buf, bufflen,
100
GFP_NOIO);
101
if (error)
102
goto put_req;
103
}
104
105
memcpy(rq->cmd, pc->c, 12);
106
if (drive->media == ide_tape)
107
rq->cmd[13] = REQ_IDETAPE_PC1;
108
error = blk_execute_rq(drive->queue, disk, rq, 0);
109
put_req:
110
blk_put_request(rq);
111
return error;
112
}
113
EXPORT_SYMBOL_GPL(ide_queue_pc_tail);
114
115
int ide_do_test_unit_ready(ide_drive_t *drive, struct gendisk *disk)
116
{
117
struct ide_atapi_pc pc;
118
119
ide_init_pc(&pc);
120
pc.c[0] = TEST_UNIT_READY;
121
122
return ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
123
}
124
EXPORT_SYMBOL_GPL(ide_do_test_unit_ready);
125
126
int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start)
127
{
128
struct ide_atapi_pc pc;
129
130
ide_init_pc(&pc);
131
pc.c[0] = START_STOP;
132
pc.c[4] = start;
133
134
if (drive->media == ide_tape)
135
pc.flags |= PC_FLAG_WAIT_FOR_DSC;
136
137
return ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
138
}
139
EXPORT_SYMBOL_GPL(ide_do_start_stop);
140
141
int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
142
{
143
struct ide_atapi_pc pc;
144
145
if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0)
146
return 0;
147
148
ide_init_pc(&pc);
149
pc.c[0] = ALLOW_MEDIUM_REMOVAL;
150
pc.c[4] = on;
151
152
return ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
153
}
154
EXPORT_SYMBOL_GPL(ide_set_media_lock);
155
156
void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc)
157
{
158
ide_init_pc(pc);
159
pc->c[0] = REQUEST_SENSE;
160
if (drive->media == ide_floppy) {
161
pc->c[4] = 255;
162
pc->req_xfer = 18;
163
} else {
164
pc->c[4] = 20;
165
pc->req_xfer = 20;
166
}
167
}
168
EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd);
169
170
void ide_prep_sense(ide_drive_t *drive, struct request *rq)
171
{
172
struct request_sense *sense = &drive->sense_data;
173
struct request *sense_rq = &drive->sense_rq;
174
unsigned int cmd_len, sense_len;
175
int err;
176
177
switch (drive->media) {
178
case ide_floppy:
179
cmd_len = 255;
180
sense_len = 18;
181
break;
182
case ide_tape:
183
cmd_len = 20;
184
sense_len = 20;
185
break;
186
default:
187
cmd_len = 18;
188
sense_len = 18;
189
}
190
191
BUG_ON(sense_len > sizeof(*sense));
192
193
if (rq->cmd_type == REQ_TYPE_SENSE || drive->sense_rq_armed)
194
return;
195
196
memset(sense, 0, sizeof(*sense));
197
198
blk_rq_init(rq->q, sense_rq);
199
200
err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len,
201
GFP_NOIO);
202
if (unlikely(err)) {
203
if (printk_ratelimit())
204
printk(KERN_WARNING PFX "%s: failed to map sense "
205
"buffer\n", drive->name);
206
return;
207
}
208
209
sense_rq->rq_disk = rq->rq_disk;
210
sense_rq->cmd[0] = GPCMD_REQUEST_SENSE;
211
sense_rq->cmd[4] = cmd_len;
212
sense_rq->cmd_type = REQ_TYPE_SENSE;
213
sense_rq->cmd_flags |= REQ_PREEMPT;
214
215
if (drive->media == ide_tape)
216
sense_rq->cmd[13] = REQ_IDETAPE_PC1;
217
218
drive->sense_rq_armed = true;
219
}
220
EXPORT_SYMBOL_GPL(ide_prep_sense);
221
222
int ide_queue_sense_rq(ide_drive_t *drive, void *special)
223
{
224
/* deferred failure from ide_prep_sense() */
225
if (!drive->sense_rq_armed) {
226
printk(KERN_WARNING PFX "%s: error queuing a sense request\n",
227
drive->name);
228
return -ENOMEM;
229
}
230
231
drive->sense_rq.special = special;
232
drive->sense_rq_armed = false;
233
234
drive->hwif->rq = NULL;
235
236
elv_add_request(drive->queue, &drive->sense_rq, ELEVATOR_INSERT_FRONT);
237
return 0;
238
}
239
EXPORT_SYMBOL_GPL(ide_queue_sense_rq);
240
241
/*
242
* Called when an error was detected during the last packet command.
243
* We queue a request sense packet command at the head of the request
244
* queue.
245
*/
246
void ide_retry_pc(ide_drive_t *drive)
247
{
248
struct request *failed_rq = drive->hwif->rq;
249
struct request *sense_rq = &drive->sense_rq;
250
struct ide_atapi_pc *pc = &drive->request_sense_pc;
251
252
(void)ide_read_error(drive);
253
254
/* init pc from sense_rq */
255
ide_init_pc(pc);
256
memcpy(pc->c, sense_rq->cmd, 12);
257
258
if (drive->media == ide_tape)
259
drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC;
260
261
/*
262
* Push back the failed request and put request sense on top
263
* of it. The failed command will be retried after sense data
264
* is acquired.
265
*/
266
drive->hwif->rq = NULL;
267
ide_requeue_and_plug(drive, failed_rq);
268
if (ide_queue_sense_rq(drive, pc)) {
269
blk_start_request(failed_rq);
270
ide_complete_rq(drive, -EIO, blk_rq_bytes(failed_rq));
271
}
272
}
273
EXPORT_SYMBOL_GPL(ide_retry_pc);
274
275
int ide_cd_expiry(ide_drive_t *drive)
276
{
277
struct request *rq = drive->hwif->rq;
278
unsigned long wait = 0;
279
280
debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]);
281
282
/*
283
* Some commands are *slow* and normally take a long time to complete.
284
* Usually we can use the ATAPI "disconnect" to bypass this, but not all
285
* commands/drives support that. Let ide_timer_expiry keep polling us
286
* for these.
287
*/
288
switch (rq->cmd[0]) {
289
case GPCMD_BLANK:
290
case GPCMD_FORMAT_UNIT:
291
case GPCMD_RESERVE_RZONE_TRACK:
292
case GPCMD_CLOSE_TRACK:
293
case GPCMD_FLUSH_CACHE:
294
wait = ATAPI_WAIT_PC;
295
break;
296
default:
297
if (!(rq->cmd_flags & REQ_QUIET))
298
printk(KERN_INFO PFX "cmd 0x%x timed out\n",
299
rq->cmd[0]);
300
wait = 0;
301
break;
302
}
303
return wait;
304
}
305
EXPORT_SYMBOL_GPL(ide_cd_expiry);
306
307
int ide_cd_get_xferlen(struct request *rq)
308
{
309
switch (rq->cmd_type) {
310
case REQ_TYPE_FS:
311
return 32768;
312
case REQ_TYPE_SENSE:
313
case REQ_TYPE_BLOCK_PC:
314
case REQ_TYPE_ATA_PC:
315
return blk_rq_bytes(rq);
316
default:
317
return 0;
318
}
319
}
320
EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);
321
322
void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
323
{
324
struct ide_taskfile tf;
325
326
drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT |
327
IDE_VALID_LBAM | IDE_VALID_LBAH);
328
329
*bcount = (tf.lbah << 8) | tf.lbam;
330
*ireason = tf.nsect & 3;
331
}
332
EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
333
334
/*
335
* Check the contents of the interrupt reason register and attempt to recover if
336
* there are problems.
337
*
338
* Returns:
339
* - 0 if everything's ok
340
* - 1 if the request has to be terminated.
341
*/
342
int ide_check_ireason(ide_drive_t *drive, struct request *rq, int len,
343
int ireason, int rw)
344
{
345
ide_hwif_t *hwif = drive->hwif;
346
347
debug_log("ireason: 0x%x, rw: 0x%x\n", ireason, rw);
348
349
if (ireason == (!rw << 1))
350
return 0;
351
else if (ireason == (rw << 1)) {
352
printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n",
353
drive->name, __func__);
354
355
if (dev_is_idecd(drive))
356
ide_pad_transfer(drive, rw, len);
357
} else if (!rw && ireason == ATAPI_COD) {
358
if (dev_is_idecd(drive)) {
359
/*
360
* Some drives (ASUS) seem to tell us that status info
361
* is available. Just get it and ignore.
362
*/
363
(void)hwif->tp_ops->read_status(hwif);
364
return 0;
365
}
366
} else {
367
if (ireason & ATAPI_COD)
368
printk(KERN_ERR PFX "%s: CoD != 0 in %s\n", drive->name,
369
__func__);
370
371
/* drive wants a command packet, or invalid ireason... */
372
printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n",
373
drive->name, __func__, ireason);
374
}
375
376
if (dev_is_idecd(drive) && rq->cmd_type == REQ_TYPE_ATA_PC)
377
rq->cmd_flags |= REQ_FAILED;
378
379
return 1;
380
}
381
EXPORT_SYMBOL_GPL(ide_check_ireason);
382
383
/*
384
* This is the usual interrupt handler which will be called during a packet
385
* command. We will transfer some of the data (as requested by the drive)
386
* and will re-point interrupt handler to us.
387
*/
388
static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
389
{
390
struct ide_atapi_pc *pc = drive->pc;
391
ide_hwif_t *hwif = drive->hwif;
392
struct ide_cmd *cmd = &hwif->cmd;
393
struct request *rq = hwif->rq;
394
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
395
unsigned int timeout, done;
396
u16 bcount;
397
u8 stat, ireason, dsc = 0;
398
u8 write = !!(pc->flags & PC_FLAG_WRITING);
399
400
debug_log("Enter %s - interrupt handler\n", __func__);
401
402
timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
403
: WAIT_TAPE_CMD;
404
405
/* Clear the interrupt */
406
stat = tp_ops->read_status(hwif);
407
408
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
409
int rc;
410
411
drive->waiting_for_dma = 0;
412
rc = hwif->dma_ops->dma_end(drive);
413
ide_dma_unmap_sg(drive, cmd);
414
415
if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) {
416
if (drive->media == ide_floppy)
417
printk(KERN_ERR PFX "%s: DMA %s error\n",
418
drive->name, rq_data_dir(pc->rq)
419
? "write" : "read");
420
pc->flags |= PC_FLAG_DMA_ERROR;
421
} else
422
rq->resid_len = 0;
423
debug_log("%s: DMA finished\n", drive->name);
424
}
425
426
/* No more interrupts */
427
if ((stat & ATA_DRQ) == 0) {
428
int uptodate, error;
429
430
debug_log("Packet command completed, %d bytes transferred\n",
431
blk_rq_bytes(rq));
432
433
pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
434
435
local_irq_enable_in_hardirq();
436
437
if (drive->media == ide_tape &&
438
(stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE)
439
stat &= ~ATA_ERR;
440
441
if ((stat & ATA_ERR) || (pc->flags & PC_FLAG_DMA_ERROR)) {
442
/* Error detected */
443
debug_log("%s: I/O error\n", drive->name);
444
445
if (drive->media != ide_tape)
446
pc->rq->errors++;
447
448
if (rq->cmd[0] == REQUEST_SENSE) {
449
printk(KERN_ERR PFX "%s: I/O error in request "
450
"sense command\n", drive->name);
451
return ide_do_reset(drive);
452
}
453
454
debug_log("[cmd %x]: check condition\n", rq->cmd[0]);
455
456
/* Retry operation */
457
ide_retry_pc(drive);
458
459
/* queued, but not started */
460
return ide_stopped;
461
}
462
pc->error = 0;
463
464
if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)
465
dsc = 1;
466
467
/*
468
* ->pc_callback() might change rq->data_len for
469
* residual count, cache total length.
470
*/
471
done = blk_rq_bytes(rq);
472
473
/* Command finished - Call the callback function */
474
uptodate = drive->pc_callback(drive, dsc);
475
476
if (uptodate == 0)
477
drive->failed_pc = NULL;
478
479
if (rq->cmd_type == REQ_TYPE_SPECIAL) {
480
rq->errors = 0;
481
error = 0;
482
} else {
483
484
if (rq->cmd_type != REQ_TYPE_FS && uptodate <= 0) {
485
if (rq->errors == 0)
486
rq->errors = -EIO;
487
}
488
489
error = uptodate ? 0 : -EIO;
490
}
491
492
ide_complete_rq(drive, error, blk_rq_bytes(rq));
493
return ide_stopped;
494
}
495
496
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
497
pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
498
printk(KERN_ERR PFX "%s: The device wants to issue more "
499
"interrupts in DMA mode\n", drive->name);
500
ide_dma_off(drive);
501
return ide_do_reset(drive);
502
}
503
504
/* Get the number of bytes to transfer on this interrupt. */
505
ide_read_bcount_and_ireason(drive, &bcount, &ireason);
506
507
if (ide_check_ireason(drive, rq, bcount, ireason, write))
508
return ide_do_reset(drive);
509
510
done = min_t(unsigned int, bcount, cmd->nleft);
511
ide_pio_bytes(drive, cmd, write, done);
512
513
/* Update transferred byte count */
514
rq->resid_len -= done;
515
516
bcount -= done;
517
518
if (bcount)
519
ide_pad_transfer(drive, write, bcount);
520
521
debug_log("[cmd %x] transferred %d bytes, padded %d bytes, resid: %u\n",
522
rq->cmd[0], done, bcount, rq->resid_len);
523
524
/* And set the interrupt handler again */
525
ide_set_handler(drive, ide_pc_intr, timeout);
526
return ide_started;
527
}
528
529
static void ide_init_packet_cmd(struct ide_cmd *cmd, u8 valid_tf,
530
u16 bcount, u8 dma)
531
{
532
cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO;
533
cmd->valid.out.tf = IDE_VALID_LBAH | IDE_VALID_LBAM |
534
IDE_VALID_FEATURE | valid_tf;
535
cmd->tf.command = ATA_CMD_PACKET;
536
cmd->tf.feature = dma; /* Use PIO/DMA */
537
cmd->tf.lbam = bcount & 0xff;
538
cmd->tf.lbah = (bcount >> 8) & 0xff;
539
}
540
541
static u8 ide_read_ireason(ide_drive_t *drive)
542
{
543
struct ide_taskfile tf;
544
545
drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT);
546
547
return tf.nsect & 3;
548
}
549
550
static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
551
{
552
int retries = 100;
553
554
while (retries-- && ((ireason & ATAPI_COD) == 0 ||
555
(ireason & ATAPI_IO))) {
556
printk(KERN_ERR PFX "%s: (IO,CoD != (0,1) while issuing "
557
"a packet command, retrying\n", drive->name);
558
udelay(100);
559
ireason = ide_read_ireason(drive);
560
if (retries == 0) {
561
printk(KERN_ERR PFX "%s: (IO,CoD != (0,1) while issuing"
562
" a packet command, ignoring\n",
563
drive->name);
564
ireason |= ATAPI_COD;
565
ireason &= ~ATAPI_IO;
566
}
567
}
568
569
return ireason;
570
}
571
572
static int ide_delayed_transfer_pc(ide_drive_t *drive)
573
{
574
/* Send the actual packet */
575
drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12);
576
577
/* Timeout for the packet command */
578
return WAIT_FLOPPY_CMD;
579
}
580
581
static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
582
{
583
struct ide_atapi_pc *uninitialized_var(pc);
584
ide_hwif_t *hwif = drive->hwif;
585
struct request *rq = hwif->rq;
586
ide_expiry_t *expiry;
587
unsigned int timeout;
588
int cmd_len;
589
ide_startstop_t startstop;
590
u8 ireason;
591
592
if (ide_wait_stat(&startstop, drive, ATA_DRQ, ATA_BUSY, WAIT_READY)) {
593
printk(KERN_ERR PFX "%s: Strange, packet command initiated yet "
594
"DRQ isn't asserted\n", drive->name);
595
return startstop;
596
}
597
598
if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
599
if (drive->dma)
600
drive->waiting_for_dma = 1;
601
}
602
603
if (dev_is_idecd(drive)) {
604
/* ATAPI commands get padded out to 12 bytes minimum */
605
cmd_len = COMMAND_SIZE(rq->cmd[0]);
606
if (cmd_len < ATAPI_MIN_CDB_BYTES)
607
cmd_len = ATAPI_MIN_CDB_BYTES;
608
609
timeout = rq->timeout;
610
expiry = ide_cd_expiry;
611
} else {
612
pc = drive->pc;
613
614
cmd_len = ATAPI_MIN_CDB_BYTES;
615
616
/*
617
* If necessary schedule the packet transfer to occur 'timeout'
618
* milliseconds later in ide_delayed_transfer_pc() after the
619
* device says it's ready for a packet.
620
*/
621
if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
622
timeout = drive->pc_delay;
623
expiry = &ide_delayed_transfer_pc;
624
} else {
625
timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
626
: WAIT_TAPE_CMD;
627
expiry = NULL;
628
}
629
630
ireason = ide_read_ireason(drive);
631
if (drive->media == ide_tape)
632
ireason = ide_wait_ireason(drive, ireason);
633
634
if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {
635
printk(KERN_ERR PFX "%s: (IO,CoD) != (0,1) while "
636
"issuing a packet command\n", drive->name);
637
638
return ide_do_reset(drive);
639
}
640
}
641
642
hwif->expiry = expiry;
643
644
/* Set the interrupt routine */
645
ide_set_handler(drive,
646
(dev_is_idecd(drive) ? drive->irq_handler
647
: ide_pc_intr),
648
timeout);
649
650
/* Send the actual packet */
651
if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
652
hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
653
654
/* Begin DMA, if necessary */
655
if (dev_is_idecd(drive)) {
656
if (drive->dma)
657
hwif->dma_ops->dma_start(drive);
658
} else {
659
if (pc->flags & PC_FLAG_DMA_OK) {
660
pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
661
hwif->dma_ops->dma_start(drive);
662
}
663
}
664
665
return ide_started;
666
}
667
668
ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
669
{
670
struct ide_atapi_pc *pc;
671
ide_hwif_t *hwif = drive->hwif;
672
ide_expiry_t *expiry = NULL;
673
struct request *rq = hwif->rq;
674
unsigned int timeout, bytes;
675
u16 bcount;
676
u8 valid_tf;
677
u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT);
678
679
if (dev_is_idecd(drive)) {
680
valid_tf = IDE_VALID_NSECT | IDE_VALID_LBAL;
681
bcount = ide_cd_get_xferlen(rq);
682
expiry = ide_cd_expiry;
683
timeout = ATAPI_WAIT_PC;
684
685
if (drive->dma)
686
drive->dma = !ide_dma_prepare(drive, cmd);
687
} else {
688
pc = drive->pc;
689
690
valid_tf = IDE_VALID_DEVICE;
691
bytes = blk_rq_bytes(rq);
692
bcount = ((drive->media == ide_tape) ? bytes
693
: min_t(unsigned int,
694
bytes, 63 * 1024));
695
696
/* We haven't transferred any data yet */
697
rq->resid_len = bcount;
698
699
if (pc->flags & PC_FLAG_DMA_ERROR) {
700
pc->flags &= ~PC_FLAG_DMA_ERROR;
701
ide_dma_off(drive);
702
}
703
704
if (pc->flags & PC_FLAG_DMA_OK)
705
drive->dma = !ide_dma_prepare(drive, cmd);
706
707
if (!drive->dma)
708
pc->flags &= ~PC_FLAG_DMA_OK;
709
710
timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
711
: WAIT_TAPE_CMD;
712
}
713
714
ide_init_packet_cmd(cmd, valid_tf, bcount, drive->dma);
715
716
(void)do_rw_taskfile(drive, cmd);
717
718
if (drq_int) {
719
if (drive->dma)
720
drive->waiting_for_dma = 0;
721
hwif->expiry = expiry;
722
}
723
724
ide_execute_command(drive, cmd, ide_transfer_pc, timeout);
725
726
return drq_int ? ide_started : ide_transfer_pc(drive);
727
}
728
EXPORT_SYMBOL_GPL(ide_issue_pc);
729
730