diff options
author | Borislav Petkov <petkovbb@googlemail.com> | 2008-04-27 09:38:25 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-04-27 09:38:25 -0400 |
commit | 5e69bd959d1086f87a603b4ddc6bdb0a130ec7db (patch) | |
tree | 557a1e62e25da255ed7ce61cbe6118ed653e9df0 /drivers | |
parent | ddfe7a776360f7067e06eee9d8b1ae4d957e6ddf (diff) |
ide-tape: remove pipeline-specific code from idetape_add_chrdev_read_request()
In order to do away with queueing read requests on the pipeline, several things
have to be done:
1. Do not allocate additional pipeline stages in idetape_init_read() until
(tape->nr_stages < max_stages) and do only read operation preparations. As a
collateral result, idetape_add_stage_tail() becomes unused so remove it.
2. Queue the read request's buffer directly thru idetape_queue_rw_tail().
3. Remove now unused idetape_kmalloc_stage() and idetape_switch_buffers().
[bart: simplify the original patch]
Signed-off-by: Borislav Petkov <petkovbb@gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ide/ide-tape.c | 96 |
1 files changed, 5 insertions, 91 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index e785145abb47..e176b5c1b208 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -1586,15 +1586,6 @@ abort: | |||
1586 | return NULL; | 1586 | return NULL; |
1587 | } | 1587 | } |
1588 | 1588 | ||
1589 | static idetape_stage_t *idetape_kmalloc_stage(idetape_tape_t *tape) | ||
1590 | { | ||
1591 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | ||
1592 | |||
1593 | if (tape->nr_stages >= tape->max_stages) | ||
1594 | return NULL; | ||
1595 | return __idetape_kmalloc_stage(tape, 0, 0); | ||
1596 | } | ||
1597 | |||
1598 | static int idetape_copy_stage_from_user(idetape_tape_t *tape, | 1589 | static int idetape_copy_stage_from_user(idetape_tape_t *tape, |
1599 | idetape_stage_t *stage, const char __user *buf, int n) | 1590 | idetape_stage_t *stage, const char __user *buf, int n) |
1600 | { | 1591 | { |
@@ -1672,39 +1663,6 @@ static void idetape_init_merge_stage(idetape_tape_t *tape) | |||
1672 | } | 1663 | } |
1673 | } | 1664 | } |
1674 | 1665 | ||
1675 | static void idetape_switch_buffers(idetape_tape_t *tape, idetape_stage_t *stage) | ||
1676 | { | ||
1677 | struct idetape_bh *tmp; | ||
1678 | |||
1679 | tmp = stage->bh; | ||
1680 | stage->bh = tape->merge_stage->bh; | ||
1681 | tape->merge_stage->bh = tmp; | ||
1682 | idetape_init_merge_stage(tape); | ||
1683 | } | ||
1684 | |||
1685 | /* Add a new stage at the end of the pipeline. */ | ||
1686 | static void idetape_add_stage_tail(ide_drive_t *drive, idetape_stage_t *stage) | ||
1687 | { | ||
1688 | idetape_tape_t *tape = drive->driver_data; | ||
1689 | unsigned long flags; | ||
1690 | |||
1691 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | ||
1692 | |||
1693 | spin_lock_irqsave(&tape->lock, flags); | ||
1694 | stage->next = NULL; | ||
1695 | if (tape->last_stage != NULL) | ||
1696 | tape->last_stage->next = stage; | ||
1697 | else | ||
1698 | tape->first_stage = stage; | ||
1699 | tape->next_stage = stage; | ||
1700 | tape->last_stage = stage; | ||
1701 | if (tape->next_stage == NULL) | ||
1702 | tape->next_stage = tape->last_stage; | ||
1703 | tape->nr_stages++; | ||
1704 | tape->nr_pending_stages++; | ||
1705 | spin_unlock_irqrestore(&tape->lock, flags); | ||
1706 | } | ||
1707 | |||
1708 | /* Install a completion in a pending request and sleep until it is serviced. The | 1666 | /* Install a completion in a pending request and sleep until it is serviced. The |
1709 | * caller should ensure that the request will not be serviced before we install | 1667 | * caller should ensure that the request will not be serviced before we install |
1710 | * the completion (usually by disabling interrupts). | 1668 | * the completion (usually by disabling interrupts). |
@@ -2228,10 +2186,7 @@ static void idetape_empty_write_pipeline(ide_drive_t *drive) | |||
2228 | static int idetape_init_read(ide_drive_t *drive, int max_stages) | 2186 | static int idetape_init_read(ide_drive_t *drive, int max_stages) |
2229 | { | 2187 | { |
2230 | idetape_tape_t *tape = drive->driver_data; | 2188 | idetape_tape_t *tape = drive->driver_data; |
2231 | idetape_stage_t *new_stage; | ||
2232 | struct request rq; | ||
2233 | int bytes_read; | 2189 | int bytes_read; |
2234 | u16 blocks = *(u16 *)&tape->caps[12]; | ||
2235 | 2190 | ||
2236 | /* Initialize read operation */ | 2191 | /* Initialize read operation */ |
2237 | if (tape->chrdev_dir != IDETAPE_DIR_READ) { | 2192 | if (tape->chrdev_dir != IDETAPE_DIR_READ) { |
@@ -2267,21 +2222,7 @@ static int idetape_init_read(ide_drive_t *drive, int max_stages) | |||
2267 | } | 2222 | } |
2268 | } | 2223 | } |
2269 | } | 2224 | } |
2270 | idetape_init_rq(&rq, REQ_IDETAPE_READ); | 2225 | |
2271 | rq.sector = tape->first_frame; | ||
2272 | rq.nr_sectors = blocks; | ||
2273 | rq.current_nr_sectors = blocks; | ||
2274 | if (!test_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags) && | ||
2275 | tape->nr_stages < max_stages) { | ||
2276 | new_stage = idetape_kmalloc_stage(tape); | ||
2277 | while (new_stage != NULL) { | ||
2278 | new_stage->rq = rq; | ||
2279 | idetape_add_stage_tail(drive, new_stage); | ||
2280 | if (tape->nr_stages >= max_stages) | ||
2281 | break; | ||
2282 | new_stage = idetape_kmalloc_stage(tape); | ||
2283 | } | ||
2284 | } | ||
2285 | if (!test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags)) { | 2226 | if (!test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags)) { |
2286 | if (tape->nr_pending_stages >= 3 * max_stages / 4) { | 2227 | if (tape->nr_pending_stages >= 3 * max_stages / 4) { |
2287 | tape->measure_insert_time = 1; | 2228 | tape->measure_insert_time = 1; |
@@ -2301,9 +2242,6 @@ static int idetape_init_read(ide_drive_t *drive, int max_stages) | |||
2301 | static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) | 2242 | static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) |
2302 | { | 2243 | { |
2303 | idetape_tape_t *tape = drive->driver_data; | 2244 | idetape_tape_t *tape = drive->driver_data; |
2304 | unsigned long flags; | ||
2305 | struct request *rq_ptr; | ||
2306 | int bytes_read; | ||
2307 | 2245 | ||
2308 | debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks); | 2246 | debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks); |
2309 | 2247 | ||
@@ -2311,37 +2249,13 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) | |||
2311 | if (test_bit(IDETAPE_FLAG_FILEMARK, &tape->flags)) | 2249 | if (test_bit(IDETAPE_FLAG_FILEMARK, &tape->flags)) |
2312 | return 0; | 2250 | return 0; |
2313 | 2251 | ||
2314 | /* Wait for the next block to reach the head of the pipeline. */ | ||
2315 | idetape_init_read(drive, tape->max_stages); | 2252 | idetape_init_read(drive, tape->max_stages); |
2316 | if (tape->first_stage == NULL) { | ||
2317 | if (test_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags)) | ||
2318 | return 0; | ||
2319 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks, | ||
2320 | tape->merge_stage->bh); | ||
2321 | } | ||
2322 | idetape_wait_first_stage(drive); | ||
2323 | rq_ptr = &tape->first_stage->rq; | ||
2324 | bytes_read = tape->blk_size * (rq_ptr->nr_sectors - | ||
2325 | rq_ptr->current_nr_sectors); | ||
2326 | rq_ptr->nr_sectors = 0; | ||
2327 | rq_ptr->current_nr_sectors = 0; | ||
2328 | 2253 | ||
2329 | if (rq_ptr->errors == IDETAPE_ERROR_EOD) | 2254 | if (test_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags)) |
2330 | return 0; | 2255 | return 0; |
2331 | else { | 2256 | |
2332 | idetape_switch_buffers(tape, tape->first_stage); | 2257 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks, |
2333 | if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK) | 2258 | tape->merge_stage->bh); |
2334 | set_bit(IDETAPE_FLAG_FILEMARK, &tape->flags); | ||
2335 | spin_lock_irqsave(&tape->lock, flags); | ||
2336 | idetape_remove_stage_head(drive); | ||
2337 | spin_unlock_irqrestore(&tape->lock, flags); | ||
2338 | } | ||
2339 | if (bytes_read > blocks * tape->blk_size) { | ||
2340 | printk(KERN_ERR "ide-tape: bug: trying to return more bytes" | ||
2341 | " than requested\n"); | ||
2342 | bytes_read = blocks * tape->blk_size; | ||
2343 | } | ||
2344 | return (bytes_read); | ||
2345 | } | 2259 | } |
2346 | 2260 | ||
2347 | static void idetape_pad_zeros(ide_drive_t *drive, int bcount) | 2261 | static void idetape_pad_zeros(ide_drive_t *drive, int bcount) |