aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-atapi.c52
-rw-r--r--drivers/ide/ide-cd.c28
-rw-r--r--drivers/ide/ide-io.c3
-rw-r--r--drivers/ide/ide-tape.c3
-rw-r--r--include/linux/ide.h2
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);
107put_req:
105 blk_put_request(rq); 108 blk_put_request(rq);
106
107 return error; 109 return error;
108} 110}
109EXPORT_SYMBOL_GPL(ide_queue_pc_tail); 111EXPORT_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}
211EXPORT_SYMBOL_GPL(ide_prep_sense); 220EXPORT_SYMBOL_GPL(ide_prep_sense);
212 221
213void ide_queue_sense_rq(ide_drive_t *drive, void *special) 222int 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}
225EXPORT_SYMBOL_GPL(ide_queue_sense_rq); 240EXPORT_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}
250EXPORT_SYMBOL_GPL(ide_retry_pc); 266EXPORT_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
404end_request: 406end_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 *);
1183void ide_retry_pc(ide_drive_t *drive); 1183void ide_retry_pc(ide_drive_t *drive);
1184 1184
1185void ide_prep_sense(ide_drive_t *drive, struct request *rq); 1185void ide_prep_sense(ide_drive_t *drive, struct request *rq);
1186void ide_queue_sense_rq(ide_drive_t *drive, void *special); 1186int ide_queue_sense_rq(ide_drive_t *drive, void *special);
1187 1187
1188int ide_cd_expiry(ide_drive_t *); 1188int ide_cd_expiry(ide_drive_t *);
1189 1189