diff options
Diffstat (limited to 'drivers/ide/ide-tape.c')
-rw-r--r-- | drivers/ide/ide-tape.c | 55 |
1 files changed, 2 insertions, 53 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 8883eea4658f..71ebee001882 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -2202,28 +2202,16 @@ static void idetape_wait_first_stage(ide_drive_t *drive) | |||
2202 | spin_unlock_irqrestore(&tape->lock, flags); | 2202 | spin_unlock_irqrestore(&tape->lock, flags); |
2203 | } | 2203 | } |
2204 | 2204 | ||
2205 | /* | 2205 | /* Queue up a character device originated write request. */ |
2206 | * Try to add a character device originated write request to our pipeline. In | ||
2207 | * case we don't succeed, we revert to non-pipelined operation mode for this | ||
2208 | * request. In order to accomplish that, we | ||
2209 | * | ||
2210 | * 1. Try to allocate a new pipeline stage. | ||
2211 | * 2. If we can't, wait for more and more requests to be serviced and try again | ||
2212 | * each time. | ||
2213 | * 3. If we still can't allocate a stage, fallback to non-pipelined operation | ||
2214 | * mode for this request. | ||
2215 | */ | ||
2216 | static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) | 2206 | static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) |
2217 | { | 2207 | { |
2218 | idetape_tape_t *tape = drive->driver_data; | 2208 | idetape_tape_t *tape = drive->driver_data; |
2219 | idetape_stage_t *new_stage; | ||
2220 | unsigned long flags; | 2209 | unsigned long flags; |
2221 | struct request *rq; | ||
2222 | 2210 | ||
2223 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); | 2211 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); |
2224 | 2212 | ||
2225 | /* Attempt to allocate a new stage. Beware possible race conditions. */ | 2213 | /* Attempt to allocate a new stage. Beware possible race conditions. */ |
2226 | while ((new_stage = idetape_kmalloc_stage(tape)) == NULL) { | 2214 | while (1) { |
2227 | spin_lock_irqsave(&tape->lock, flags); | 2215 | spin_lock_irqsave(&tape->lock, flags); |
2228 | if (test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags)) { | 2216 | if (test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags)) { |
2229 | idetape_wait_for_request(drive, tape->active_data_rq); | 2217 | idetape_wait_for_request(drive, tape->active_data_rq); |
@@ -2234,49 +2222,10 @@ static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) | |||
2234 | if (test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, | 2222 | if (test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, |
2235 | &tape->flags)) | 2223 | &tape->flags)) |
2236 | continue; | 2224 | continue; |
2237 | /* | ||
2238 | * The machine is short on memory. Fallback to non- | ||
2239 | * pipelined operation mode for this request. | ||
2240 | */ | ||
2241 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, | 2225 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, |
2242 | blocks, tape->merge_stage->bh); | 2226 | blocks, tape->merge_stage->bh); |
2243 | } | 2227 | } |
2244 | } | 2228 | } |
2245 | rq = &new_stage->rq; | ||
2246 | idetape_init_rq(rq, REQ_IDETAPE_WRITE); | ||
2247 | /* Doesn't actually matter - We always assume sequential access */ | ||
2248 | rq->sector = tape->first_frame; | ||
2249 | rq->current_nr_sectors = blocks; | ||
2250 | rq->nr_sectors = blocks; | ||
2251 | |||
2252 | idetape_switch_buffers(tape, new_stage); | ||
2253 | idetape_add_stage_tail(drive, new_stage); | ||
2254 | tape->pipeline_head++; | ||
2255 | idetape_calculate_speeds(drive); | ||
2256 | |||
2257 | /* | ||
2258 | * Estimate whether the tape has stopped writing by checking if our | ||
2259 | * write pipeline is currently empty. If we are not writing anymore, | ||
2260 | * wait for the pipeline to be almost completely full (90%) before | ||
2261 | * starting to service requests, so that we will be able to keep up with | ||
2262 | * the higher speeds of the tape. | ||
2263 | */ | ||
2264 | if (!test_bit(IDETAPE_FLAG_PIPELINE_ACTIVE, &tape->flags)) { | ||
2265 | if (tape->nr_stages >= tape->max_stages * 9 / 10 || | ||
2266 | tape->nr_stages >= tape->max_stages - | ||
2267 | tape->uncontrolled_pipeline_head_speed * 3 * 1024 / | ||
2268 | tape->blk_size) { | ||
2269 | tape->measure_insert_time = 1; | ||
2270 | tape->insert_time = jiffies; | ||
2271 | tape->insert_size = 0; | ||
2272 | tape->insert_speed = 0; | ||
2273 | idetape_plug_pipeline(drive); | ||
2274 | } | ||
2275 | } | ||
2276 | if (test_and_clear_bit(IDETAPE_FLAG_PIPELINE_ERR, &tape->flags)) | ||
2277 | /* Return a deferred error */ | ||
2278 | return -EIO; | ||
2279 | return blocks; | ||
2280 | } | 2229 | } |
2281 | 2230 | ||
2282 | /* | 2231 | /* |