aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-taskfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-taskfile.c')
-rw-r--r--drivers/ide/ide-taskfile.c126
1 files changed, 64 insertions, 62 deletions
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 75b85a8cd2d4..cc8633cbe133 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -19,8 +19,8 @@
19#include <linux/hdreg.h> 19#include <linux/hdreg.h>
20#include <linux/ide.h> 20#include <linux/ide.h>
21#include <linux/scatterlist.h> 21#include <linux/scatterlist.h>
22#include <linux/uaccess.h>
22 23
23#include <asm/uaccess.h>
24#include <asm/io.h> 24#include <asm/io.h>
25 25
26void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd) 26void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd)
@@ -53,7 +53,7 @@ void ide_tf_dump(const char *s, struct ide_cmd *cmd)
53#endif 53#endif
54} 54}
55 55
56int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) 56int taskfile_lib_get_identify(ide_drive_t *drive, u8 *buf)
57{ 57{
58 struct ide_cmd cmd; 58 struct ide_cmd cmd;
59 59
@@ -86,7 +86,7 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
86 if (orig_cmd->protocol == ATA_PROT_PIO && 86 if (orig_cmd->protocol == ATA_PROT_PIO &&
87 (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) && 87 (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
88 drive->mult_count == 0) { 88 drive->mult_count == 0) {
89 printk(KERN_ERR "%s: multimode not set!\n", drive->name); 89 pr_err("%s: multimode not set!\n", drive->name);
90 return ide_stopped; 90 return ide_stopped;
91 } 91 }
92 92
@@ -214,7 +214,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
214 } 214 }
215 215
216 if (stat & ATA_BUSY) 216 if (stat & ATA_BUSY)
217 printk(KERN_ERR "%s: drive still BUSY!\n", drive->name); 217 pr_err("%s: drive still BUSY!\n", drive->name);
218 218
219 return stat; 219 return stat;
220} 220}
@@ -225,8 +225,8 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
225 ide_hwif_t *hwif = drive->hwif; 225 ide_hwif_t *hwif = drive->hwif;
226 struct scatterlist *sg = hwif->sg_table; 226 struct scatterlist *sg = hwif->sg_table;
227 struct scatterlist *cursg = cmd->cursg; 227 struct scatterlist *cursg = cmd->cursg;
228 unsigned long uninitialized_var(flags);
228 struct page *page; 229 struct page *page;
229 unsigned long flags;
230 unsigned int offset; 230 unsigned int offset;
231 u8 *buf; 231 u8 *buf;
232 232
@@ -236,6 +236,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
236 236
237 while (len) { 237 while (len) {
238 unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs); 238 unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
239 int page_is_high;
239 240
240 if (nr_bytes > PAGE_SIZE) 241 if (nr_bytes > PAGE_SIZE)
241 nr_bytes = PAGE_SIZE; 242 nr_bytes = PAGE_SIZE;
@@ -247,7 +248,8 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
247 page = nth_page(page, (offset >> PAGE_SHIFT)); 248 page = nth_page(page, (offset >> PAGE_SHIFT));
248 offset %= PAGE_SIZE; 249 offset %= PAGE_SIZE;
249 250
250 if (PageHighMem(page)) 251 page_is_high = PageHighMem(page);
252 if (page_is_high)
251 local_irq_save(flags); 253 local_irq_save(flags);
252 254
253 buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; 255 buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
@@ -268,7 +270,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
268 270
269 kunmap_atomic(buf, KM_BIO_SRC_IRQ); 271 kunmap_atomic(buf, KM_BIO_SRC_IRQ);
270 272
271 if (PageHighMem(page)) 273 if (page_is_high)
272 local_irq_restore(flags); 274 local_irq_restore(flags);
273 275
274 len -= nr_bytes; 276 len -= nr_bytes;
@@ -322,10 +324,17 @@ static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
322void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat) 324void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
323{ 325{
324 struct request *rq = drive->hwif->rq; 326 struct request *rq = drive->hwif->rq;
325 u8 err = ide_read_error(drive); 327 u8 err = ide_read_error(drive), nsect = cmd->tf.nsect;
328 u8 set_xfer = !!(cmd->tf_flags & IDE_TFLAG_SET_XFER);
326 329
327 ide_complete_cmd(drive, cmd, stat, err); 330 ide_complete_cmd(drive, cmd, stat, err);
328 rq->errors = err; 331 rq->errors = err;
332
333 if (err == 0 && set_xfer) {
334 ide_set_xfer_rate(drive, nsect);
335 ide_driveid_update(drive);
336 }
337
329 ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq)); 338 ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
330} 339}
331 340
@@ -398,8 +407,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
398 407
399 if (ide_wait_stat(&startstop, drive, ATA_DRQ, 408 if (ide_wait_stat(&startstop, drive, ATA_DRQ,
400 drive->bad_wstat, WAIT_DRQ)) { 409 drive->bad_wstat, WAIT_DRQ)) {
401 printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", 410 pr_err("%s: no DRQ after issuing %sWRITE%s\n", drive->name,
402 drive->name,
403 (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "", 411 (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
404 (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : ""); 412 (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
405 return startstop; 413 return startstop;
@@ -449,7 +457,6 @@ put_req:
449 blk_put_request(rq); 457 blk_put_request(rq);
450 return error; 458 return error;
451} 459}
452
453EXPORT_SYMBOL(ide_raw_taskfile); 460EXPORT_SYMBOL(ide_raw_taskfile);
454 461
455int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) 462int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
@@ -475,10 +482,9 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
475 u16 nsect = 0; 482 u16 nsect = 0;
476 char __user *buf = (char __user *)arg; 483 char __user *buf = (char __user *)arg;
477 484
478// printk("IDE Taskfile ...\n");
479
480 req_task = kzalloc(tasksize, GFP_KERNEL); 485 req_task = kzalloc(tasksize, GFP_KERNEL);
481 if (req_task == NULL) return -ENOMEM; 486 if (req_task == NULL)
487 return -ENOMEM;
482 if (copy_from_user(req_task, buf, tasksize)) { 488 if (copy_from_user(req_task, buf, tasksize)) {
483 kfree(req_task); 489 kfree(req_task);
484 return -EFAULT; 490 return -EFAULT;
@@ -486,7 +492,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
486 492
487 taskout = req_task->out_size; 493 taskout = req_task->out_size;
488 taskin = req_task->in_size; 494 taskin = req_task->in_size;
489 495
490 if (taskin > 65536 || taskout > 65536) { 496 if (taskin > 65536 || taskout > 65536) {
491 err = -EINVAL; 497 err = -EINVAL;
492 goto abort; 498 goto abort;
@@ -576,51 +582,49 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
576 cmd.protocol = ATA_PROT_DMA; 582 cmd.protocol = ATA_PROT_DMA;
577 583
578 switch (req_task->data_phase) { 584 switch (req_task->data_phase) {
579 case TASKFILE_MULTI_OUT: 585 case TASKFILE_MULTI_OUT:
580 if (!drive->mult_count) { 586 if (!drive->mult_count) {
581 /* (hs): give up if multcount is not set */ 587 /* (hs): give up if multcount is not set */
582 printk(KERN_ERR "%s: %s Multimode Write " \ 588 pr_err("%s: %s Multimode Write multcount is not set\n",
583 "multcount is not set\n", 589 drive->name, __func__);
584 drive->name, __func__); 590 err = -EPERM;
585 err = -EPERM; 591 goto abort;
586 goto abort; 592 }
587 } 593 cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
588 cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; 594 /* fall through */
589 /* fall through */ 595 case TASKFILE_OUT:
590 case TASKFILE_OUT: 596 cmd.protocol = ATA_PROT_PIO;
591 cmd.protocol = ATA_PROT_PIO; 597 /* fall through */
592 /* fall through */ 598 case TASKFILE_OUT_DMAQ:
593 case TASKFILE_OUT_DMAQ: 599 case TASKFILE_OUT_DMA:
594 case TASKFILE_OUT_DMA: 600 cmd.tf_flags |= IDE_TFLAG_WRITE;
595 cmd.tf_flags |= IDE_TFLAG_WRITE; 601 nsect = taskout / SECTOR_SIZE;
596 nsect = taskout / SECTOR_SIZE; 602 data_buf = outbuf;
597 data_buf = outbuf; 603 break;
598 break; 604 case TASKFILE_MULTI_IN:
599 case TASKFILE_MULTI_IN: 605 if (!drive->mult_count) {
600 if (!drive->mult_count) { 606 /* (hs): give up if multcount is not set */
601 /* (hs): give up if multcount is not set */ 607 pr_err("%s: %s Multimode Read multcount is not set\n",
602 printk(KERN_ERR "%s: %s Multimode Read failure " \ 608 drive->name, __func__);
603 "multcount is not set\n", 609 err = -EPERM;
604 drive->name, __func__);
605 err = -EPERM;
606 goto abort;
607 }
608 cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
609 /* fall through */
610 case TASKFILE_IN:
611 cmd.protocol = ATA_PROT_PIO;
612 /* fall through */
613 case TASKFILE_IN_DMAQ:
614 case TASKFILE_IN_DMA:
615 nsect = taskin / SECTOR_SIZE;
616 data_buf = inbuf;
617 break;
618 case TASKFILE_NO_DATA:
619 cmd.protocol = ATA_PROT_NODATA;
620 break;
621 default:
622 err = -EFAULT;
623 goto abort; 610 goto abort;
611 }
612 cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
613 /* fall through */
614 case TASKFILE_IN:
615 cmd.protocol = ATA_PROT_PIO;
616 /* fall through */
617 case TASKFILE_IN_DMAQ:
618 case TASKFILE_IN_DMA:
619 nsect = taskin / SECTOR_SIZE;
620 data_buf = inbuf;
621 break;
622 case TASKFILE_NO_DATA:
623 cmd.protocol = ATA_PROT_NODATA;
624 break;
625 default:
626 err = -EFAULT;
627 goto abort;
624 } 628 }
625 629
626 if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA) 630 if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
@@ -629,7 +633,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
629 nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect; 633 nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect;
630 634
631 if (!nsect) { 635 if (!nsect) {
632 printk(KERN_ERR "%s: in/out command without data\n", 636 pr_err("%s: in/out command without data\n",
633 drive->name); 637 drive->name);
634 err = -EFAULT; 638 err = -EFAULT;
635 goto abort; 639 goto abort;
@@ -671,8 +675,6 @@ abort:
671 kfree(outbuf); 675 kfree(outbuf);
672 kfree(inbuf); 676 kfree(inbuf);
673 677
674// printk("IDE Taskfile ioctl ended. rc = %i\n", err);
675
676 return err; 678 return err;
677} 679}
678#endif 680#endif