aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <petkovbb@googlemail.com>2009-04-18 18:00:42 -0400
committerTejun Heo <tj@kernel.org>2009-04-18 18:00:42 -0400
commit746d5e43274e9ea6cbd58818afc9239d41fb4e1e (patch)
treeccd01a9ff82888f274a301b41bd7565eec2909c4
parenta1df5169f9bf08f6067029bfb840a05e282b1b97 (diff)
ide-cd: convert to using generic sense request
Preallocate a sense request in the ->do_request method and reinitialize it only on demand, in case it's been consumed in the IRQ handler path. The reason for this is that we don't want to be mapping rq to bio in the IRQ path and introduce all kinds of unnecessary hacks to the block layer. tj: * Both user and kernel PC requests expect sense data to be stored in separate storage other than drive->sense_data. Copy sense data to rq->sense on completion if rq->sense is not NULL. This fixes bogus sense data on PC requests. As a result, remove cdrom_queue_request_sense. CC: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> CC: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Borislav Petkov <petkovbb@gmail.com> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--drivers/ide/ide-cd.c54
-rw-r--r--drivers/ide/ide-cd.h4
2 files changed, 12 insertions, 46 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index eb3c299d95de..7b21c7eac5b0 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -206,44 +206,6 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
206 ide_cd_log_error(drive->name, failed_command, sense); 206 ide_cd_log_error(drive->name, failed_command, sense);
207} 207}
208 208
209static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
210 struct request *failed_command)
211{
212 struct cdrom_info *info = drive->driver_data;
213 struct request *rq = &drive->request_sense_rq;
214
215 ide_debug_log(IDE_DBG_SENSE, "enter");
216
217 if (sense == NULL)
218 sense = &info->sense_data;
219
220 memset(sense, 0, 18);
221
222 /* stuff the sense request in front of our current request */
223 blk_rq_init(NULL, rq);
224 rq->cmd_type = REQ_TYPE_ATA_PC;
225 rq->rq_disk = info->disk;
226
227 rq->data = sense;
228 rq->cmd[0] = GPCMD_REQUEST_SENSE;
229 rq->cmd[4] = 18;
230 rq->data_len = 18;
231
232 rq->cmd_type = REQ_TYPE_SENSE;
233 rq->cmd_flags |= REQ_PREEMPT;
234
235 /* NOTE! Save the failed command in "rq->special" */
236 rq->special = (void *)failed_command;
237
238 if (failed_command)
239 ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x",
240 failed_command->cmd[0]);
241
242 drive->hwif->rq = NULL;
243
244 elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
245}
246
247static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) 209static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
248{ 210{
249 /* 211 /*
@@ -251,11 +213,16 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
251 * failed request 213 * failed request
252 */ 214 */
253 struct request *failed = (struct request *)rq->special; 215 struct request *failed = (struct request *)rq->special;
254 struct cdrom_info *info = drive->driver_data; 216 struct request_sense *sense = &drive->sense_data;
255 void *sense = &info->sense_data;
256 217
257 if (failed) { 218 if (failed) {
258 if (failed->sense) { 219 if (failed->sense) {
220 /*
221 * Sense is always read into drive->sense_data.
222 * Copy back if the failed request has its
223 * sense pointer set.
224 */
225 memcpy(failed->sense, sense, 18);
259 sense = failed->sense; 226 sense = failed->sense;
260 failed->sense_len = rq->sense_len; 227 failed->sense_len = rq->sense_len;
261 } 228 }
@@ -431,7 +398,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
431 398
432 /* if we got a CHECK_CONDITION status, queue a request sense command */ 399 /* if we got a CHECK_CONDITION status, queue a request sense command */
433 if (stat & ATA_ERR) 400 if (stat & ATA_ERR)
434 cdrom_queue_request_sense(drive, NULL, NULL); 401 ide_queue_sense_rq(drive, NULL);
435 return 1; 402 return 1;
436 403
437end_request: 404end_request:
@@ -445,7 +412,7 @@ end_request:
445 412
446 hwif->rq = NULL; 413 hwif->rq = NULL;
447 414
448 cdrom_queue_request_sense(drive, rq->sense, rq); 415 ide_queue_sense_rq(drive, rq);
449 return 1; 416 return 1;
450 } else 417 } else
451 return 2; 418 return 2;
@@ -893,6 +860,9 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
893 goto out_end; 860 goto out_end;
894 } 861 }
895 862
863 /* prepare sense request for this command */
864 ide_prep_sense(drive, rq);
865
896 memset(&cmd, 0, sizeof(cmd)); 866 memset(&cmd, 0, sizeof(cmd));
897 867
898 if (rq_data_dir(rq)) 868 if (rq_data_dir(rq))
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 1d97101099ce..93a3cf1b0f3f 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -87,10 +87,6 @@ struct cdrom_info {
87 87
88 struct atapi_toc *toc; 88 struct atapi_toc *toc;
89 89
90 /* The result of the last successful request sense command
91 on this device. */
92 struct request_sense sense_data;
93
94 u8 max_speed; /* Max speed of the drive. */ 90 u8 max_speed; /* Max speed of the drive. */
95 u8 current_speed; /* Current speed of the drive. */ 91 u8 current_speed; /* Current speed of the drive. */
96 92