diff options
-rw-r--r-- | drivers/ide/ide-atapi.c | 52 | ||||
-rw-r--r-- | drivers/ide/ide-cd.c | 28 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 3 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 3 | ||||
-rw-r--r-- | include/linux/ide.h | 2 |
5 files changed, 52 insertions, 36 deletions
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 972c522516f8..5cefe12f5622 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
@@ -94,16 +94,18 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, | |||
94 | rq->special = (char *)pc; | 94 | rq->special = (char *)pc; |
95 | 95 | ||
96 | if (pc->req_xfer) { | 96 | if (pc->req_xfer) { |
97 | rq->data = pc->buf; | 97 | error = blk_rq_map_kern(drive->queue, rq, pc->buf, pc->req_xfer, |
98 | rq->data_len = pc->req_xfer; | 98 | GFP_NOIO); |
99 | if (error) | ||
100 | goto put_req; | ||
99 | } | 101 | } |
100 | 102 | ||
101 | memcpy(rq->cmd, pc->c, 12); | 103 | memcpy(rq->cmd, pc->c, 12); |
102 | if (drive->media == ide_tape) | 104 | if (drive->media == ide_tape) |
103 | rq->cmd[13] = REQ_IDETAPE_PC1; | 105 | rq->cmd[13] = REQ_IDETAPE_PC1; |
104 | error = blk_execute_rq(drive->queue, disk, rq, 0); | 106 | error = blk_execute_rq(drive->queue, disk, rq, 0); |
107 | put_req: | ||
105 | blk_put_request(rq); | 108 | blk_put_request(rq); |
106 | |||
107 | return error; | 109 | return error; |
108 | } | 110 | } |
109 | EXPORT_SYMBOL_GPL(ide_queue_pc_tail); | 111 | EXPORT_SYMBOL_GPL(ide_queue_pc_tail); |
@@ -168,6 +170,7 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) | |||
168 | struct request_sense *sense = &drive->sense_data; | 170 | struct request_sense *sense = &drive->sense_data; |
169 | struct request *sense_rq = &drive->sense_rq; | 171 | struct request *sense_rq = &drive->sense_rq; |
170 | unsigned int cmd_len, sense_len; | 172 | unsigned int cmd_len, sense_len; |
173 | int err; | ||
171 | 174 | ||
172 | debug_log("%s: enter\n", __func__); | 175 | debug_log("%s: enter\n", __func__); |
173 | 176 | ||
@@ -193,13 +196,19 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) | |||
193 | memset(sense, 0, sizeof(*sense)); | 196 | memset(sense, 0, sizeof(*sense)); |
194 | 197 | ||
195 | blk_rq_init(rq->q, sense_rq); | 198 | blk_rq_init(rq->q, sense_rq); |
196 | sense_rq->rq_disk = rq->rq_disk; | ||
197 | 199 | ||
198 | sense_rq->data = sense; | 200 | err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len, |
201 | GFP_NOIO); | ||
202 | if (unlikely(err)) { | ||
203 | if (printk_ratelimit()) | ||
204 | printk(KERN_WARNING "%s: failed to map sense buffer\n", | ||
205 | drive->name); | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | sense_rq->rq_disk = rq->rq_disk; | ||
199 | sense_rq->cmd[0] = GPCMD_REQUEST_SENSE; | 210 | sense_rq->cmd[0] = GPCMD_REQUEST_SENSE; |
200 | sense_rq->cmd[4] = cmd_len; | 211 | sense_rq->cmd[4] = cmd_len; |
201 | sense_rq->data_len = sense_len; | ||
202 | |||
203 | sense_rq->cmd_type = REQ_TYPE_SENSE; | 212 | sense_rq->cmd_type = REQ_TYPE_SENSE; |
204 | sense_rq->cmd_flags |= REQ_PREEMPT; | 213 | sense_rq->cmd_flags |= REQ_PREEMPT; |
205 | 214 | ||
@@ -210,9 +219,14 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) | |||
210 | } | 219 | } |
211 | EXPORT_SYMBOL_GPL(ide_prep_sense); | 220 | EXPORT_SYMBOL_GPL(ide_prep_sense); |
212 | 221 | ||
213 | void ide_queue_sense_rq(ide_drive_t *drive, void *special) | 222 | int ide_queue_sense_rq(ide_drive_t *drive, void *special) |
214 | { | 223 | { |
215 | BUG_ON(!drive->sense_rq_armed); | 224 | /* deferred failure from ide_prep_sense() */ |
225 | if (!drive->sense_rq_armed) { | ||
226 | printk(KERN_WARNING "%s: failed queue sense request\n", | ||
227 | drive->name); | ||
228 | return -ENOMEM; | ||
229 | } | ||
216 | 230 | ||
217 | drive->sense_rq.special = special; | 231 | drive->sense_rq.special = special; |
218 | drive->sense_rq_armed = false; | 232 | drive->sense_rq_armed = false; |
@@ -221,6 +235,7 @@ void ide_queue_sense_rq(ide_drive_t *drive, void *special) | |||
221 | 235 | ||
222 | elv_add_request(drive->queue, &drive->sense_rq, | 236 | elv_add_request(drive->queue, &drive->sense_rq, |
223 | ELEVATOR_INSERT_FRONT, 0); | 237 | ELEVATOR_INSERT_FRONT, 0); |
238 | return 0; | ||
224 | } | 239 | } |
225 | EXPORT_SYMBOL_GPL(ide_queue_sense_rq); | 240 | EXPORT_SYMBOL_GPL(ide_queue_sense_rq); |
226 | 241 | ||
@@ -239,13 +254,14 @@ void ide_retry_pc(ide_drive_t *drive) | |||
239 | /* init pc from sense_rq */ | 254 | /* init pc from sense_rq */ |
240 | ide_init_pc(pc); | 255 | ide_init_pc(pc); |
241 | memcpy(pc->c, sense_rq->cmd, 12); | 256 | memcpy(pc->c, sense_rq->cmd, 12); |
242 | pc->buf = sense_rq->data; | 257 | pc->buf = bio_data(sense_rq->bio); /* pointer to mapped address */ |
243 | pc->req_xfer = sense_rq->data_len; | 258 | pc->req_xfer = sense_rq->data_len; |
244 | 259 | ||
245 | if (drive->media == ide_tape) | 260 | if (drive->media == ide_tape) |
246 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); | 261 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); |
247 | 262 | ||
248 | ide_queue_sense_rq(drive, pc); | 263 | if (ide_queue_sense_rq(drive, pc)) |
264 | ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); | ||
249 | } | 265 | } |
250 | EXPORT_SYMBOL_GPL(ide_retry_pc); | 266 | EXPORT_SYMBOL_GPL(ide_retry_pc); |
251 | 267 | ||
@@ -317,7 +333,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
317 | struct ide_cmd *cmd = &hwif->cmd; | 333 | struct ide_cmd *cmd = &hwif->cmd; |
318 | struct request *rq = hwif->rq; | 334 | struct request *rq = hwif->rq; |
319 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 335 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
320 | xfer_func_t *xferfunc; | ||
321 | unsigned int timeout, done; | 336 | unsigned int timeout, done; |
322 | u16 bcount; | 337 | u16 bcount; |
323 | u8 stat, ireason, dsc = 0; | 338 | u8 stat, ireason, dsc = 0; |
@@ -411,7 +426,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
411 | rq->errors = -EIO; | 426 | rq->errors = -EIO; |
412 | } | 427 | } |
413 | 428 | ||
414 | if (drive->media == ide_tape) | 429 | if (drive->media == ide_tape && !rq->bio) |
415 | done = ide_rq_bytes(rq); /* FIXME */ | 430 | done = ide_rq_bytes(rq); /* FIXME */ |
416 | else | 431 | else |
417 | done = blk_rq_bytes(rq); | 432 | done = blk_rq_bytes(rq); |
@@ -448,16 +463,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
448 | return ide_do_reset(drive); | 463 | return ide_do_reset(drive); |
449 | } | 464 | } |
450 | 465 | ||
451 | xferfunc = write ? tp_ops->output_data : tp_ops->input_data; | 466 | if (drive->media == ide_tape && pc->bh) |
452 | 467 | done = drive->pc_io_buffers(drive, pc, bcount, write); | |
453 | if (drive->media == ide_floppy && pc->buf == NULL) { | 468 | else { |
454 | done = min_t(unsigned int, bcount, cmd->nleft); | 469 | done = min_t(unsigned int, bcount, cmd->nleft); |
455 | ide_pio_bytes(drive, cmd, write, done); | 470 | ide_pio_bytes(drive, cmd, write, done); |
456 | } else if (drive->media == ide_tape && pc->bh) { | ||
457 | done = drive->pc_io_buffers(drive, pc, bcount, write); | ||
458 | } else { | ||
459 | done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred); | ||
460 | xferfunc(drive, NULL, pc->cur_pos, done); | ||
461 | } | 471 | } |
462 | 472 | ||
463 | /* Update the current position */ | 473 | /* Update the current position */ |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 061d7bbcd34a..673628790f10 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -210,10 +210,12 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) | |||
210 | { | 210 | { |
211 | /* | 211 | /* |
212 | * For REQ_TYPE_SENSE, "rq->special" points to the original | 212 | * For REQ_TYPE_SENSE, "rq->special" points to the original |
213 | * failed request | 213 | * failed request. Also, the sense data should be read |
214 | * directly from rq which might be different from the original | ||
215 | * sense buffer if it got copied during mapping. | ||
214 | */ | 216 | */ |
215 | struct request *failed = (struct request *)rq->special; | 217 | struct request *failed = (struct request *)rq->special; |
216 | struct request_sense *sense = &drive->sense_data; | 218 | void *sense = bio_data(rq->bio); |
217 | 219 | ||
218 | if (failed) { | 220 | if (failed) { |
219 | if (failed->sense) { | 221 | if (failed->sense) { |
@@ -398,7 +400,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) | |||
398 | 400 | ||
399 | /* if we got a CHECK_CONDITION status, queue a request sense command */ | 401 | /* if we got a CHECK_CONDITION status, queue a request sense command */ |
400 | if (stat & ATA_ERR) | 402 | if (stat & ATA_ERR) |
401 | ide_queue_sense_rq(drive, NULL); | 403 | return ide_queue_sense_rq(drive, NULL) ? 2 : 1; |
402 | return 1; | 404 | return 1; |
403 | 405 | ||
404 | end_request: | 406 | end_request: |
@@ -412,8 +414,7 @@ end_request: | |||
412 | 414 | ||
413 | hwif->rq = NULL; | 415 | hwif->rq = NULL; |
414 | 416 | ||
415 | ide_queue_sense_rq(drive, rq); | 417 | return ide_queue_sense_rq(drive, rq) ? 2 : 1; |
416 | return 1; | ||
417 | } else | 418 | } else |
418 | return 2; | 419 | return 2; |
419 | } | 420 | } |
@@ -507,8 +508,12 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, | |||
507 | rq->cmd_flags |= cmd_flags; | 508 | rq->cmd_flags |= cmd_flags; |
508 | rq->timeout = timeout; | 509 | rq->timeout = timeout; |
509 | if (buffer) { | 510 | if (buffer) { |
510 | rq->data = buffer; | 511 | error = blk_rq_map_kern(drive->queue, rq, buffer, |
511 | rq->data_len = *bufflen; | 512 | *bufflen, GFP_NOIO); |
513 | if (error) { | ||
514 | blk_put_request(rq); | ||
515 | return error; | ||
516 | } | ||
512 | } | 517 | } |
513 | 518 | ||
514 | error = blk_execute_rq(drive->queue, info->disk, rq, 0); | 519 | error = blk_execute_rq(drive->queue, info->disk, rq, 0); |
@@ -802,15 +807,10 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | |||
802 | drive->dma = 0; | 807 | drive->dma = 0; |
803 | 808 | ||
804 | /* sg request */ | 809 | /* sg request */ |
805 | if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) { | 810 | if (rq->bio) { |
806 | struct request_queue *q = drive->queue; | 811 | struct request_queue *q = drive->queue; |
812 | char *buf = bio_data(rq->bio); | ||
807 | unsigned int alignment; | 813 | unsigned int alignment; |
808 | char *buf; | ||
809 | |||
810 | if (rq->bio) | ||
811 | buf = bio_data(rq->bio); | ||
812 | else | ||
813 | buf = rq->data; | ||
814 | 814 | ||
815 | drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | 815 | drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); |
816 | 816 | ||
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 9b9e8b1aae5e..3245c2dbda33 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -481,6 +481,9 @@ void do_ide_request(struct request_queue *q) | |||
481 | 481 | ||
482 | spin_unlock_irq(q->queue_lock); | 482 | spin_unlock_irq(q->queue_lock); |
483 | 483 | ||
484 | /* HLD do_request() callback might sleep, make sure it's okay */ | ||
485 | might_sleep(); | ||
486 | |||
484 | if (ide_lock_host(host, hwif)) | 487 | if (ide_lock_host(host, hwif)) |
485 | goto plug_device_2; | 488 | goto plug_device_2; |
486 | 489 | ||
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 8324dfa78a3f..9b762a2d5d95 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -850,6 +850,9 @@ out: | |||
850 | 850 | ||
851 | cmd.rq = rq; | 851 | cmd.rq = rq; |
852 | 852 | ||
853 | ide_init_sg_cmd(&cmd, pc->req_xfer); | ||
854 | ide_map_sg(drive, &cmd); | ||
855 | |||
853 | return ide_tape_issue_pc(drive, &cmd, pc); | 856 | return ide_tape_issue_pc(drive, &cmd, pc); |
854 | } | 857 | } |
855 | 858 | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index 9e67ccac3c1f..1957461ac762 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -1183,7 +1183,7 @@ void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); | |||
1183 | void ide_retry_pc(ide_drive_t *drive); | 1183 | void ide_retry_pc(ide_drive_t *drive); |
1184 | 1184 | ||
1185 | void ide_prep_sense(ide_drive_t *drive, struct request *rq); | 1185 | void ide_prep_sense(ide_drive_t *drive, struct request *rq); |
1186 | void ide_queue_sense_rq(ide_drive_t *drive, void *special); | 1186 | int ide_queue_sense_rq(ide_drive_t *drive, void *special); |
1187 | 1187 | ||
1188 | int ide_cd_expiry(ide_drive_t *); | 1188 | int ide_cd_expiry(ide_drive_t *); |
1189 | 1189 | ||