diff options
author | Borislav Petkov <petkovbb@googlemail.com> | 2009-04-18 18:00:42 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2009-04-18 18:00:42 -0400 |
commit | 746d5e43274e9ea6cbd58818afc9239d41fb4e1e (patch) | |
tree | ccd01a9ff82888f274a301b41bd7565eec2909c4 | |
parent | a1df5169f9bf08f6067029bfb840a05e282b1b97 (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.c | 54 | ||||
-rw-r--r-- | drivers/ide/ide-cd.h | 4 |
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 | ||
209 | static 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 | |||
247 | static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) | 209 | static 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 | ||
437 | end_request: | 404 | end_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 | ||