X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fide%2Fide-taskfile.c;h=cc8633cbe133db4d9b7f81330ef66a547a6176ac;hb=a9d244a2ff163247b607c4bb64803230ca8f8acb;hp=f400eb4d4aff73414a2e7b2d0e9739ce0969de46;hpb=d868ca24302e99a0e8a86071ca2c66273edf97d9;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index f400eb4..cc8633c 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -19,8 +19,8 @@ #include #include #include +#include -#include #include void 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) #endif } -int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) +int taskfile_lib_get_identify(ide_drive_t *drive, u8 *buf) { struct ide_cmd cmd; @@ -86,7 +86,7 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) if (orig_cmd->protocol == ATA_PROT_PIO && (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) && drive->mult_count == 0) { - printk(KERN_ERR "%s: multimode not set!\n", drive->name); + pr_err("%s: multimode not set!\n", drive->name); return ide_stopped; } @@ -98,7 +98,6 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { ide_tf_dump(drive->name, cmd); tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); - SELECT_MASK(drive, 0); if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) { u8 data[2] = { cmd->tf.data, cmd->hob.data }; @@ -166,7 +165,7 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive) if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) { if (custom && tf->command == ATA_CMD_SET_MULTI) { drive->mult_req = drive->mult_count = 0; - drive->special.b.recalibrate = 1; + drive->special_flags |= IDE_SFLAG_RECALIBRATE; (void)ide_dump_status(drive, __func__, stat); return ide_stopped; } else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) { @@ -215,7 +214,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) } if (stat & ATA_BUSY) - printk(KERN_ERR "%s: drive still BUSY!\n", drive->name); + pr_err("%s: drive still BUSY!\n", drive->name); return stat; } @@ -226,8 +225,8 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, ide_hwif_t *hwif = drive->hwif; struct scatterlist *sg = hwif->sg_table; struct scatterlist *cursg = cmd->cursg; + unsigned long uninitialized_var(flags); struct page *page; - unsigned long flags; unsigned int offset; u8 *buf; @@ -237,6 +236,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, while (len) { unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs); + int page_is_high; if (nr_bytes > PAGE_SIZE) nr_bytes = PAGE_SIZE; @@ -248,7 +248,8 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, page = nth_page(page, (offset >> PAGE_SHIFT)); offset %= PAGE_SIZE; - if (PageHighMem(page)) + page_is_high = PageHighMem(page); + if (page_is_high) local_irq_save(flags); buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; @@ -269,7 +270,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, kunmap_atomic(buf, KM_BIO_SRC_IRQ); - if (PageHighMem(page)) + if (page_is_high) local_irq_restore(flags); len -= nr_bytes; @@ -323,10 +324,17 @@ static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat) { struct request *rq = drive->hwif->rq; - u8 err = ide_read_error(drive); + u8 err = ide_read_error(drive), nsect = cmd->tf.nsect; + u8 set_xfer = !!(cmd->tf_flags & IDE_TFLAG_SET_XFER); ide_complete_cmd(drive, cmd, stat, err); rq->errors = err; + + if (err == 0 && set_xfer) { + ide_set_xfer_rate(drive, nsect); + ide_driveid_update(drive); + } + ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq)); } @@ -385,7 +393,7 @@ out_end: if ((cmd->tf_flags & IDE_TFLAG_FS) == 0) ide_finish_cmd(drive, cmd, stat); else - ide_complete_rq(drive, 0, cmd->rq->nr_sectors << 9); + ide_complete_rq(drive, 0, blk_rq_sectors(cmd->rq) << 9); return ide_stopped; out_err: ide_error_cmd(drive, cmd); @@ -399,8 +407,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, if (ide_wait_stat(&startstop, drive, ATA_DRQ, drive->bad_wstat, WAIT_DRQ)) { - printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", - drive->name, + pr_err("%s: no DRQ after issuing %sWRITE%s\n", drive->name, (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "", (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : ""); return startstop; @@ -450,7 +457,6 @@ put_req: blk_put_request(rq); return error; } - EXPORT_SYMBOL(ide_raw_taskfile); int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) @@ -476,10 +482,9 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) u16 nsect = 0; char __user *buf = (char __user *)arg; -// printk("IDE Taskfile ...\n"); - req_task = kzalloc(tasksize, GFP_KERNEL); - if (req_task == NULL) return -ENOMEM; + if (req_task == NULL) + return -ENOMEM; if (copy_from_user(req_task, buf, tasksize)) { kfree(req_task); return -EFAULT; @@ -487,7 +492,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) taskout = req_task->out_size; taskin = req_task->in_size; - + if (taskin > 65536 || taskout > 65536) { err = -EINVAL; goto abort; @@ -577,51 +582,49 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) cmd.protocol = ATA_PROT_DMA; switch (req_task->data_phase) { - case TASKFILE_MULTI_OUT: - if (!drive->mult_count) { - /* (hs): give up if multcount is not set */ - printk(KERN_ERR "%s: %s Multimode Write " \ - "multcount is not set\n", - drive->name, __func__); - err = -EPERM; - goto abort; - } - cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; - /* fall through */ - case TASKFILE_OUT: - cmd.protocol = ATA_PROT_PIO; - /* fall through */ - case TASKFILE_OUT_DMAQ: - case TASKFILE_OUT_DMA: - cmd.tf_flags |= IDE_TFLAG_WRITE; - nsect = taskout / SECTOR_SIZE; - data_buf = outbuf; - break; - case TASKFILE_MULTI_IN: - if (!drive->mult_count) { - /* (hs): give up if multcount is not set */ - printk(KERN_ERR "%s: %s Multimode Read failure " \ - "multcount is not set\n", - drive->name, __func__); - err = -EPERM; - goto abort; - } - cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; - /* fall through */ - case TASKFILE_IN: - cmd.protocol = ATA_PROT_PIO; - /* fall through */ - case TASKFILE_IN_DMAQ: - case TASKFILE_IN_DMA: - nsect = taskin / SECTOR_SIZE; - data_buf = inbuf; - break; - case TASKFILE_NO_DATA: - cmd.protocol = ATA_PROT_NODATA; - break; - default: - err = -EFAULT; + case TASKFILE_MULTI_OUT: + if (!drive->mult_count) { + /* (hs): give up if multcount is not set */ + pr_err("%s: %s Multimode Write multcount is not set\n", + drive->name, __func__); + err = -EPERM; + goto abort; + } + cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; + /* fall through */ + case TASKFILE_OUT: + cmd.protocol = ATA_PROT_PIO; + /* fall through */ + case TASKFILE_OUT_DMAQ: + case TASKFILE_OUT_DMA: + cmd.tf_flags |= IDE_TFLAG_WRITE; + nsect = taskout / SECTOR_SIZE; + data_buf = outbuf; + break; + case TASKFILE_MULTI_IN: + if (!drive->mult_count) { + /* (hs): give up if multcount is not set */ + pr_err("%s: %s Multimode Read multcount is not set\n", + drive->name, __func__); + err = -EPERM; goto abort; + } + cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; + /* fall through */ + case TASKFILE_IN: + cmd.protocol = ATA_PROT_PIO; + /* fall through */ + case TASKFILE_IN_DMAQ: + case TASKFILE_IN_DMA: + nsect = taskin / SECTOR_SIZE; + data_buf = inbuf; + break; + case TASKFILE_NO_DATA: + cmd.protocol = ATA_PROT_NODATA; + break; + default: + err = -EFAULT; + goto abort; } if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA) @@ -630,7 +633,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect; if (!nsect) { - printk(KERN_ERR "%s: in/out command without data\n", + pr_err("%s: in/out command without data\n", drive->name); err = -EFAULT; goto abort; @@ -672,8 +675,6 @@ abort: kfree(outbuf); kfree(inbuf); -// printk("IDE Taskfile ioctl ended. rc = %i\n", err); - return err; } #endif