From a907905219dc83f501274d5d8c6d2aa2161ff8c3 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 23 Jun 2009 04:12:24 -0700 Subject: IDE: Save a call to PageHighMem() PageHighMem() isn't cheap so avoid calling it twice on the same page. Signed-off-by: Jean Delvare Acked-by: Bartlomiej Zolnierkiewicz Signed-off-by: David S. Miller --- drivers/ide/ide-taskfile.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 75b85a8cd2d4..90e5c0deb0e0 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -236,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; @@ -247,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; @@ -268,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; -- cgit v1.2.3 From 7fa350b4754cd69c8352ef3f5d23082fbdcab0bd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 23 Jun 2009 04:16:04 -0700 Subject: ide: Fix annoying warning in ide_pio_bytes(). GCC can't see that flags is only set and used when PageHighmem() is true. Inspired by a patch from Jean Delvare. Signed-off-by: David S. Miller --- drivers/ide/ide-taskfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 90e5c0deb0e0..3a5224cbd0f2 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -225,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; -- cgit v1.2.3 From 37bbe084d1152cb580d2cc88b4eda2004506a141 Mon Sep 17 00:00:00 2001 From: Mark de Wever Date: Fri, 17 Jul 2009 23:55:15 +0000 Subject: ide-tape: fix debug call This error only occurs when IDETAPE_DEBUG_LOG is enabled. Signed-off-by: Mark de Wever Signed-off-by: David S. Miller --- drivers/ide/ide-tape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index bc5fb12b913c..1d74f159bcc4 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -583,7 +583,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, struct ide_cmd cmd; u8 stat; - debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n" + debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n", (unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq)); BUG_ON(!(blk_special_request(rq) || blk_sense_request(rq))); -- cgit v1.2.3 From e972d7027c0fb7055f5f2fe02d662c9528063bef Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 17 Jul 2009 23:55:16 +0000 Subject: ide-tape: convert to ide_debug_log macro Remove tape->debug_mask and use drive->debug_mask instead. There should be no functional change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: David S. Miller --- drivers/ide/ide-tape.c | 102 ++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 53 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1d74f159bcc4..3468ece98496 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -47,28 +47,13 @@ #include #include -enum { - /* output errors only */ - DBG_ERR = (1 << 0), - /* output all sense key/asc */ - DBG_SENSE = (1 << 1), - /* info regarding all chrdev-related procedures */ - DBG_CHRDEV = (1 << 2), - /* all remaining procedures */ - DBG_PROCS = (1 << 3), -}; - /* define to see debug info */ -#define IDETAPE_DEBUG_LOG 0 +#undef IDETAPE_DEBUG_LOG -#if IDETAPE_DEBUG_LOG -#define debug_log(lvl, fmt, args...) \ -{ \ - if (tape->debug_mask & lvl) \ - printk(KERN_INFO "ide-tape: " fmt, ## args); \ -} +#ifdef IDETAPE_DEBUG_LOG +#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args) #else -#define debug_log(lvl, fmt, args...) do {} while (0) +#define ide_debug_log(lvl, fmt, args...) do {} while (0) #endif /**************************** Tunable parameters *****************************/ @@ -230,8 +215,6 @@ typedef struct ide_tape_obj { char drv_write_prot; /* the tape is write protected (hardware or opened as read-only) */ char write_prot; - - u32 debug_mask; } idetape_tape_t; static DEFINE_MUTEX(idetape_ref_mutex); @@ -290,8 +273,9 @@ static void idetape_analyze_error(ide_drive_t *drive) tape->asc = sense[12]; tape->ascq = sense[13]; - debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n", - pc->c[0], tape->sense_key, tape->asc, tape->ascq); + ide_debug_log(IDE_DBG_FUNC, + "cmd: 0x%x, sense key = %x, asc = %x, ascq = %x", + rq->cmd[0], tape->sense_key, tape->asc, tape->ascq); /* correct remaining bytes to transfer */ if (pc->flags & PC_FLAG_DMA_ERROR) @@ -344,7 +328,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) int uptodate = pc->error ? 0 : 1; int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; - debug_log(DBG_PROCS, "Enter %s\n", __func__); + ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, dsc: %d, err: %d", rq->cmd[0], + dsc, err); if (dsc) ide_tape_handle_dsc(drive); @@ -390,10 +375,12 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) static void idetape_postpone_request(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; + struct request *rq = drive->hwif->rq; - debug_log(DBG_PROCS, "Enter %s\n", __func__); + ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, dsc_poll_freq: %lu", + rq->cmd[0], tape->dsc_poll_freq); - tape->postponed_rq = drive->hwif->rq; + tape->postponed_rq = rq; ide_stall_queue(drive, tape->dsc_poll_freq); } @@ -488,7 +475,8 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); return ide_stopped; } - debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); + ide_debug_log(IDE_DBG_SENSE, "retry #%d, cmd: 0x%02x", pc->retries, + pc->c[0]); pc->retries++; @@ -583,8 +571,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, struct ide_cmd cmd; u8 stat; - debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n", - (unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq)); + ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, sector: %llu, nr_sectors: %u", + rq->cmd[0], (unsigned long long)blk_rq_pos(rq), + blk_rq_sectors(rq)); BUG_ON(!(blk_special_request(rq) || blk_sense_request(rq))); @@ -745,7 +734,7 @@ static int ide_tape_read_position(ide_drive_t *drive) struct ide_atapi_pc pc; u8 buf[20]; - debug_log(DBG_PROCS, "Enter %s\n", __func__); + ide_debug_log(IDE_DBG_FUNC, "enter"); /* prep cmd */ ide_init_pc(&pc); @@ -756,9 +745,9 @@ static int ide_tape_read_position(ide_drive_t *drive) return -1; if (!pc.error) { - debug_log(DBG_SENSE, "BOP - %s\n", + ide_debug_log(IDE_DBG_FUNC, "BOP - %s", (buf[0] & 0x80) ? "Yes" : "No"); - debug_log(DBG_SENSE, "EOP - %s\n", + ide_debug_log(IDE_DBG_FUNC, "EOP - %s", (buf[0] & 0x40) ? "Yes" : "No"); if (buf[0] & 0x4) { @@ -768,8 +757,8 @@ static int ide_tape_read_position(ide_drive_t *drive) &drive->atapi_flags); return -1; } else { - debug_log(DBG_SENSE, "Block Location - %u\n", - be32_to_cpup((__be32 *)&buf[4])); + ide_debug_log(IDE_DBG_FUNC, "Block Location: %u", + be32_to_cpup((__be32 *)&buf[4])); tape->partition = buf[1]; tape->first_frame = be32_to_cpup((__be32 *)&buf[4]); @@ -866,7 +855,8 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size) struct request *rq; int ret; - debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); + ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, size: %d", cmd, size); + BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE); BUG_ON(size < 0 || size % tape->blk_size); @@ -1029,7 +1019,7 @@ static int idetape_rewind_tape(ide_drive_t *drive) struct ide_atapi_pc pc; int ret; - debug_log(DBG_SENSE, "Enter %s\n", __func__); + ide_debug_log(IDE_DBG_FUNC, "enter"); idetape_create_rewind_cmd(drive, &pc); ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); @@ -1055,7 +1045,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, int nr_stages; } config; - debug_log(DBG_PROCS, "Enter %s\n", __func__); + ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%04x", cmd); switch (cmd) { case 0x0340: @@ -1085,6 +1075,9 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, int retval, count = 0; int sprev = !!(tape->caps[4] & 0x20); + + ide_debug_log(IDE_DBG_FUNC, "mt_op: %d, mt_count: %d", mt_op, mt_count); + if (mt_count == 0) return 0; if (MTBSF == mt_op || MTBSFM == mt_op) { @@ -1148,7 +1141,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, ssize_t ret = 0; int rc; - debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); + ide_debug_log(IDE_DBG_FUNC, "count %Zd", count); if (tape->chrdev_dir != IDETAPE_DIR_READ) { if (test_bit(ilog2(IDE_AFLAG_DETECT_BS), &drive->atapi_flags)) @@ -1187,8 +1180,6 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, } if (!done && test_bit(ilog2(IDE_AFLAG_FILEMARK), &drive->atapi_flags)) { - debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name); - idetape_space_over_filemarks(drive, MTFSF, 1); return 0; } @@ -1209,7 +1200,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, if (tape->write_prot) return -EACCES; - debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); + ide_debug_log(IDE_DBG_FUNC, "count %Zd", count); /* Initialize write operation */ rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE); @@ -1273,8 +1264,8 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) struct ide_atapi_pc pc; int i, retval; - debug_log(DBG_ERR, "Handling MTIOCTOP ioctl: mt_op=%d, mt_count=%d\n", - mt_op, mt_count); + ide_debug_log(IDE_DBG_FUNC, "MTIOCTOP ioctl: mt_op: %d, mt_count: %d", + mt_op, mt_count); switch (mt_op) { case MTFSF: @@ -1393,7 +1384,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, int block_offset = 0, position = tape->first_frame; void __user *argp = (void __user *)arg; - debug_log(DBG_CHRDEV, "Enter %s, cmd=%u\n", __func__, cmd); + ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x", cmd); if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { ide_tape_flush_merge_buffer(drive); @@ -1461,6 +1452,9 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive) (buf[4 + 6] << 8) + buf[4 + 7]; tape->drv_write_prot = (buf[2] & 0x80) >> 7; + + ide_debug_log(IDE_DBG_FUNC, "blk_size: %d, write_prot: %d", + tape->blk_size, tape->drv_write_prot); } static int idetape_chrdev_open(struct inode *inode, struct file *filp) @@ -1480,7 +1474,10 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) return -ENXIO; } - debug_log(DBG_CHRDEV, "Enter %s\n", __func__); + drive = tape->drive; + filp->private_data = tape; + + ide_debug_log(IDE_DBG_FUNC, "enter"); /* * We really want to do nonseekable_open(inode, filp); here, but some @@ -1489,9 +1486,6 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) */ filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); - drive = tape->drive; - - filp->private_data = tape; if (test_and_set_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags)) { retval = -EBUSY; @@ -1570,7 +1564,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp) lock_kernel(); tape = drive->driver_data; - debug_log(DBG_CHRDEV, "Enter %s\n", __func__); + ide_debug_log(IDE_DBG_FUNC, "enter"); if (tape->chrdev_dir == IDETAPE_DIR_WRITE) idetape_write_release(drive, minor); @@ -1707,7 +1701,6 @@ static int divf_buffer_size(ide_drive_t *drive) { return 1024; } ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP); -ide_tape_devset_rw_field(debug_mask, debug_mask); ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq); ide_tape_devset_r_field(avg_speed, avg_speed); @@ -1719,7 +1712,6 @@ static const struct ide_proc_devset idetape_settings[] = { __IDE_PROC_DEVSET(avg_speed, 0, 0xffff, NULL, NULL), __IDE_PROC_DEVSET(buffer, 0, 0xffff, NULL, divf_buffer), __IDE_PROC_DEVSET(buffer_size, 0, 0xffff, NULL, divf_buffer_size), - __IDE_PROC_DEVSET(debug_mask, 0, 0xffff, NULL, NULL), __IDE_PROC_DEVSET(dsc_overlap, 0, 1, NULL, NULL), __IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL), __IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX, @@ -1746,7 +1738,9 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) int buffer_size; u16 *ctl = (u16 *)&tape->caps[12]; - drive->pc_callback = ide_tape_callback; + ide_debug_log(IDE_DBG_FUNC, "minor: %d", minor); + + drive->pc_callback = ide_tape_callback; drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; @@ -1932,7 +1926,9 @@ static int ide_tape_probe(ide_drive_t *drive) struct gendisk *g; int minor; - if (!strstr("ide-tape", drive->driver_req)) + ide_debug_log(IDE_DBG_FUNC, "enter"); + + if (!strstr(DRV_NAME, drive->driver_req)) goto failed; if (drive->media != ide_tape) -- cgit v1.2.3 From 6f3848ac2399faac0be3f26648bf1d7a644a8242 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 21 Jul 2009 23:08:23 -0700 Subject: ide-tape: fix handling of postponed rqs ide-tape used to hit [ 58.614854] ide-tape: ht0: BUG: Two DSC requests queued! due to the fact that another rq was being issued while the driver was waiting for DSC to get set for the device executing ATAPI commands which set the DSC to 1 to indicate completion. Here's a sample output of that case: issue REZERO_UNIT [ 143.088505] ide-tape: ide_tape_issue_pc: retry #0, cmd: 0x01 [ 143.095122] ide: Enter ide_pc_intr - interrupt handler [ 143.096118] ide: Packet command completed, 0 bytes transferred [ 143.106319] ide-tape: ide_tape_callback: cmd: 0x1, dsc: 1, err: 0 [ 143.112601] ide-tape: idetape_postpone_request: cmd: 0x1, dsc_poll_freq: 2000 we stall the ide-tape queue here waiting for DSC [ 143.119936] ide-tape: ide_tape_read_position: enter [ 145.119019] ide-tape: idetape_do_request: sector: 4294967295, nr_sectors: 0 and issue the new READ_POSITION rq and hit the check. [ 145.126247] ide-tape: ht0: BUG: Two DSC requests queued! [ 145.131748] ide-tape: ide_tape_read_position: BOP - No [ 145.137059] ide-tape: ide_tape_read_position: EOP - No Also, ->postponed_rq used to point to that postponed request. To make things worse, in certain circumstances the rq it was pointing to got replaced unterneath it by swiftly reusing the same rq from the mempool of the block layer practically confusing stuff even more. However, we don't need to keep a pointer to that rq but simply wait for DSC to be set first before issuing the follow-up request in the drive's queue. In order to do that, we make idetape_do_request() first check the DSC and if not set, we stall the drive queue giving the other device on that IDE channel a chance. Signed-off-by: Borislav Petkov Signed-off-by: David S. Miller --- drivers/ide/ide-tape.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 3468ece98496..7b2032bc357b 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -155,7 +155,8 @@ typedef struct ide_tape_obj { * other device. Note that at most we will have only one DSC (usually * data transfer) request in the device request queue. */ - struct request *postponed_rq; + bool postponed_rq; + /* The time in which we started polling for DSC */ unsigned long dsc_polling_start; /* Timer used to poll for dsc */ @@ -372,15 +373,14 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) * Postpone the current request so that ide.c will be able to service requests * from another device on the same port while we are polling for DSC. */ -static void idetape_postpone_request(ide_drive_t *drive) +static void ide_tape_stall_queue(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; - struct request *rq = drive->hwif->rq; ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, dsc_poll_freq: %lu", - rq->cmd[0], tape->dsc_poll_freq); + drive->hwif->rq->cmd[0], tape->dsc_poll_freq); - tape->postponed_rq = rq; + tape->postponed_rq = true; ide_stall_queue(drive, tape->dsc_poll_freq); } @@ -394,7 +394,7 @@ static void ide_tape_handle_dsc(ide_drive_t *drive) tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST; tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; /* Allow ide.c to handle other requests */ - idetape_postpone_request(drive); + ide_tape_stall_queue(drive); } /* @@ -567,7 +567,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, ide_hwif_t *hwif = drive->hwif; idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc *pc = NULL; - struct request *postponed_rq = tape->postponed_rq; struct ide_cmd cmd; u8 stat; @@ -583,18 +582,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, goto out; } - if (postponed_rq != NULL) - if (rq != postponed_rq) { - printk(KERN_ERR "ide-tape: ide-tape.c bug - " - "Two DSC requests were queued\n"); - drive->failed_pc = NULL; - rq->errors = 0; - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); - return ide_stopped; - } - - tape->postponed_rq = NULL; - /* * If the tape is still busy, postpone our request and service * the other device meanwhile. @@ -612,7 +599,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, if (!(drive->atapi_flags & IDE_AFLAG_IGNORE_DSC) && !(stat & ATA_DSC)) { - if (postponed_rq == NULL) { + if (!tape->postponed_rq) { tape->dsc_polling_start = jiffies; tape->dsc_poll_freq = tape->best_dsc_rw_freq; tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT; @@ -629,10 +616,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, tape->dsc_polling_start + IDETAPE_DSC_MA_THRESHOLD)) tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW; - idetape_postpone_request(drive); + ide_tape_stall_queue(drive); return ide_stopped; - } else + } else { drive->atapi_flags &= ~IDE_AFLAG_IGNORE_DSC; + tape->postponed_rq = false; + } if (rq->cmd[13] & REQ_IDETAPE_READ) { pc = &tape->queued_pc; -- cgit v1.2.3 From 72db37b2c9c5b71e49068f5fac6433a6c36498a5 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 2 Aug 2009 13:19:05 -0700 Subject: drivers/ide/ide-cd.c: Use DIV_ROUND_CLOSEST The kernel.h macro DIV_ROUND_CLOSEST performs the computation (x + d/2)/d but is perhaps more readable. The semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @haskernel@ @@ #include @depends on haskernel@ expression x,__divisor; @@ - (((x) + ((__divisor) / 2)) / (__divisor)) + DIV_ROUND_CLOSEST(x,__divisor) // Signed-off-by: Julia Lawall Acked-by: Borislav Petkov Signed-off-by: David S. Miller --- drivers/ide/ide-cd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 6a9a769bffc1..ad0ab0c0a493 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1146,8 +1146,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u", curspeed, maxspeed); - cd->current_speed = (curspeed + (176/2)) / 176; - cd->max_speed = (maxspeed + (176/2)) / 176; + cd->current_speed = DIV_ROUND_CLOSEST(curspeed, 176); + cd->max_speed = DIV_ROUND_CLOSEST(maxspeed, 176); } #define IDE_CD_CAPABILITIES \ -- cgit v1.2.3 From 2d5abcedeb41f4af9582c60cef70749c3ab90a3b Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sun, 2 Aug 2009 20:17:34 -0700 Subject: ide: ide-taskfile.c fix style problems Fix trivial style problems: WARNING: Use #include instead of WARNING: space prohibited between function name and open parenthesis '(' WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable ERROR: do not use C99 // comments X 2 ERROR: trailing statements should be on next line ERROR: trailing whitespace ERROR: switch and case should be at the same indent WARNING: line over 80 characters total: 5 errors, 4 warnings Also removed dead code Also used pr_err() to avoid line breaks Signed-off-by: Jaswinder Singh Rajput Acked-by: Bartlomiej Zolnierkiewicz Signed-off-by: David S. Miller --- drivers/ide/ide-taskfile.c | 109 +++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 58 deletions(-) diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 3a5224cbd0f2..50336d51eebc 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; } @@ -214,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; } @@ -400,8 +400,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; @@ -451,7 +450,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) @@ -477,10 +475,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; @@ -488,7 +485,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; @@ -578,51 +575,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) @@ -631,7 +626,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; @@ -673,8 +668,6 @@ abort: kfree(outbuf); kfree(inbuf); -// printk("IDE Taskfile ioctl ended. rc = %i\n", err); - return err; } #endif -- cgit v1.2.3 From fa56d4cb4022c8b313c3b99236e1b87effc3655b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 23 Jun 2009 11:29:11 +0000 Subject: ide: allow ide_dev_read_id() to be called from the IRQ context * Un-static __ide_wait_stat(). * Allow ide_dev_read_id() helper to be called from the IRQ context by adding irq_ctx flag and using mdelay()/__ide_wait_stat() when needed. * Switch ide_driveid_update() to set irq_ctx flag. This change is needed for the consecutive patch which fixes races in handling of user-space SET XFER commands but for improved bisectability and clarity it is better to do it in a separate patch. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: David S. Miller --- drivers/ide/ide-iops.c | 6 +++--- drivers/ide/ide-probe.c | 31 +++++++++++++++++++++---------- include/linux/ide.h | 3 ++- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 2892b242bbe1..b99873845d21 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -102,8 +102,8 @@ EXPORT_SYMBOL(ide_fixstring); * setting a timer to wake up at half second intervals thereafter, * until timeout is achieved, before timing out. */ -static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, - unsigned long timeout, u8 *rstat) +int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, + unsigned long timeout, u8 *rstat) { ide_hwif_t *hwif = drive->hwif; const struct ide_tp_ops *tp_ops = hwif->tp_ops; @@ -316,7 +316,7 @@ int ide_driveid_update(ide_drive_t *drive) return 0; SELECT_MASK(drive, 1); - rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id); + rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id, 1); SELECT_MASK(drive, 0); if (rc) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 1bb106f6221a..8de442cbee94 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -238,6 +238,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id) * @drive: drive to identify * @cmd: command to use * @id: buffer for IDENTIFY data + * @irq_ctx: flag set when called from the IRQ context * * Sends an ATA(PI) IDENTIFY request to a drive and waits for a response. * @@ -246,7 +247,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id) * 2 device aborted the command (refused to identify itself) */ -int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) +int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id, int irq_ctx) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; @@ -263,7 +264,10 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS); /* take a deep breath */ - msleep(50); + if (irq_ctx) + mdelay(50); + else + msleep(50); if (io_ports->ctl_addr && (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) { @@ -295,12 +299,19 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; - if (ide_busy_sleep(drive, timeout, use_altstatus)) - return 1; - /* wait for IRQ and ATA_DRQ */ - msleep(50); - s = tp_ops->read_status(hwif); + if (irq_ctx) { + rc = __ide_wait_stat(drive, ATA_DRQ, BAD_R_STAT, timeout, &s); + if (rc) + return 1; + } else { + rc = ide_busy_sleep(drive, timeout, use_altstatus); + if (rc) + return 1; + + msleep(50); + s = tp_ops->read_status(hwif); + } if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) { /* drive returned ID */ @@ -406,10 +417,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd) if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) || present || cmd == ATA_CMD_ID_ATAPI) { - rc = ide_dev_read_id(drive, cmd, id); + rc = ide_dev_read_id(drive, cmd, id, 0); if (rc) /* failed: try again */ - rc = ide_dev_read_id(drive, cmd, id); + rc = ide_dev_read_id(drive, cmd, id, 0); stat = tp_ops->read_status(hwif); @@ -424,7 +435,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) msleep(50); tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); (void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0); - rc = ide_dev_read_id(drive, cmd, id); + rc = ide_dev_read_id(drive, cmd, id, 0); } /* ensure drive IRQ is clear */ diff --git a/include/linux/ide.h b/include/linux/ide.h index edc93a6d931d..cb6cd0459a5e 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1081,6 +1081,7 @@ extern void ide_fixstring(u8 *, const int, const int); int ide_busy_sleep(ide_drive_t *, unsigned long, int); +int __ide_wait_stat(ide_drive_t *, u8, u8, unsigned long, u8 *); int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); ide_startstop_t ide_do_park_unpark(ide_drive_t *, struct request *); @@ -1169,7 +1170,7 @@ int ide_no_data_taskfile(ide_drive_t *, struct ide_cmd *); int ide_taskfile_ioctl(ide_drive_t *, unsigned long); -int ide_dev_read_id(ide_drive_t *, u8, u16 *); +int ide_dev_read_id(ide_drive_t *, u8, u16 *, int); extern int ide_driveid_update(ide_drive_t *); extern int ide_config_drive_speed(ide_drive_t *, u8); -- cgit v1.2.3 From 665d66e8fad60a5a162c4615f27f916ad1a6d567 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 23 Jun 2009 11:35:51 +0000 Subject: ide: fix races in handling of user-space SET XFER commands * Make cmd->tf_flags field 'u16' and add IDE_TFLAG_SET_XFER taskfile flag. * Update ide_finish_cmd() to set xfer / re-read id if the new flag is set. * Convert set_xfer_rate() (write handler for /proc/ide/hd?/current_speed) and ide_cmd_ioctl() (HDIO_DRIVE_CMD ioctl handler) to use the new flag. * Remove no longer needed disable_irq_nosync() + enable_irq() from ide_config_drive_speed(). Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: David S. Miller --- drivers/ide/ide-ioctls.c | 8 ++------ drivers/ide/ide-iops.c | 10 ---------- drivers/ide/ide-proc.c | 10 ++-------- drivers/ide/ide-taskfile.c | 9 ++++++++- include/linux/ide.h | 3 ++- 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index e246d3d3fbcc..d3440b5010a5 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -167,6 +167,8 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) err = -EINVAL; goto abort; } + + cmd.tf_flags |= IDE_TFLAG_SET_XFER; } err = ide_raw_taskfile(drive, &cmd, buf, args[3]); @@ -174,12 +176,6 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) args[0] = tf->status; args[1] = tf->error; args[2] = tf->nsect; - - if (!err && xfer_rate) { - /* active-retuning-calls future */ - ide_set_xfer_rate(drive, xfer_rate); - ide_driveid_update(drive); - } abort: if (copy_to_user((void __user *)arg, &args, 4)) err = -EFAULT; diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index b99873845d21..b14fa9a87c49 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -363,14 +363,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) * this point (lost interrupt). */ - /* - * FIXME: we race against the running IRQ here if - * this is called from non IRQ context. If we use - * disable_irq() we hang on the error path. Work - * is needed. - */ - disable_irq_nosync(hwif->irq); - udelay(1); tp_ops->dev_select(drive); SELECT_MASK(drive, 1); @@ -394,8 +386,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) SELECT_MASK(drive, 0); - enable_irq(hwif->irq); - if (error) { (void) ide_dump_status(drive, "set_drive_speed_status", stat); return error; diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 3242698832a4..021de41655e6 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -195,7 +195,6 @@ ide_devset_get(xfer_rate, current_speed); static int set_xfer_rate (ide_drive_t *drive, int arg) { struct ide_cmd cmd; - int err; if (arg < XFER_PIO_0 || arg > XFER_UDMA_6) return -EINVAL; @@ -206,14 +205,9 @@ static int set_xfer_rate (ide_drive_t *drive, int arg) cmd.tf.nsect = (u8)arg; cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT; cmd.valid.in.tf = IDE_VALID_NSECT; + cmd.tf_flags = IDE_TFLAG_SET_XFER; - err = ide_no_data_taskfile(drive, &cmd); - - if (!err) { - ide_set_xfer_rate(drive, (u8) arg); - ide_driveid_update(drive); - } - return err; + return ide_no_data_taskfile(drive, &cmd); } ide_devset_rw(current_speed, xfer_rate); diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 50336d51eebc..cc8633cbe133 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -324,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)); } diff --git a/include/linux/ide.h b/include/linux/ide.h index cb6cd0459a5e..803c1ae31237 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -258,6 +258,7 @@ enum { IDE_TFLAG_DYN = (1 << 5), IDE_TFLAG_FS = (1 << 6), IDE_TFLAG_MULTI_PIO = (1 << 7), + IDE_TFLAG_SET_XFER = (1 << 8), }; enum { @@ -294,7 +295,7 @@ struct ide_cmd { } out, in; } valid; - u8 tf_flags; + u16 tf_flags; u8 ftf_flags; /* for TASKFILE ioctl */ int protocol; -- cgit v1.2.3