diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-03-27 07:46:38 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-03-27 07:46:38 -0400 |
commit | adb1af9803d167091c2cb4de14014185054bfe2c (patch) | |
tree | aeac3bd825abfb344b1b1b43e282756fb8069f49 /drivers/ide/ide-taskfile.c | |
parent | 22aa4b32a19b1f231d4ce7e9af6354b577a22a35 (diff) |
ide: pass command instead of request to ide_pio_datablock()
* Add IDE_TFLAG_FS taskfile flag and set it for REQ_TYPE_FS requests.
* Convert ->{in,out}put_data methods to take command instead of request
as an argument. Then convert pre_task_out_intr(), task_end_request(),
task_error(), task_in_unexpected(), ide_pio_sector(), ide_pio_multi()
and ide_pio_datablock() in similar way.
* Rename task_end_request() to ide_finish_cmd().
There should be no functional changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-taskfile.c')
-rw-r--r-- | drivers/ide/ide-taskfile.c | 88 |
1 files changed, 43 insertions, 45 deletions
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 2b85c137764a..d3bd93afbf2b 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -54,19 +54,20 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) | |||
54 | } | 54 | } |
55 | 55 | ||
56 | static ide_startstop_t task_no_data_intr(ide_drive_t *); | 56 | static ide_startstop_t task_no_data_intr(ide_drive_t *); |
57 | static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); | 57 | static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct ide_cmd *); |
58 | static ide_startstop_t task_in_intr(ide_drive_t *); | 58 | static ide_startstop_t task_in_intr(ide_drive_t *); |
59 | 59 | ||
60 | ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) | 60 | ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) |
61 | { | 61 | { |
62 | ide_hwif_t *hwif = drive->hwif; | 62 | ide_hwif_t *hwif = drive->hwif; |
63 | struct ide_cmd *cmd = &hwif->cmd; | ||
63 | struct ide_taskfile *tf = &cmd->tf; | 64 | struct ide_taskfile *tf = &cmd->tf; |
64 | ide_handler_t *handler = NULL; | 65 | ide_handler_t *handler = NULL; |
65 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 66 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
66 | const struct ide_dma_ops *dma_ops = hwif->dma_ops; | 67 | const struct ide_dma_ops *dma_ops = hwif->dma_ops; |
67 | 68 | ||
68 | if (cmd->data_phase == TASKFILE_MULTI_IN || | 69 | if (orig_cmd->data_phase == TASKFILE_MULTI_IN || |
69 | cmd->data_phase == TASKFILE_MULTI_OUT) { | 70 | orig_cmd->data_phase == TASKFILE_MULTI_OUT) { |
70 | if (!drive->mult_count) { | 71 | if (!drive->mult_count) { |
71 | printk(KERN_ERR "%s: multimode not set!\n", | 72 | printk(KERN_ERR "%s: multimode not set!\n", |
72 | drive->name); | 73 | drive->name); |
@@ -74,10 +75,10 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) | |||
74 | } | 75 | } |
75 | } | 76 | } |
76 | 77 | ||
77 | if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) | 78 | if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED) |
78 | cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS; | 79 | orig_cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS; |
79 | 80 | ||
80 | memcpy(&hwif->cmd, cmd, sizeof(*cmd)); | 81 | memcpy(cmd, orig_cmd, sizeof(*cmd)); |
81 | 82 | ||
82 | if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { | 83 | if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { |
83 | ide_tf_dump(drive->name, tf); | 84 | ide_tf_dump(drive->name, tf); |
@@ -91,7 +92,7 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) | |||
91 | case TASKFILE_OUT: | 92 | case TASKFILE_OUT: |
92 | tp_ops->exec_command(hwif, tf->command); | 93 | tp_ops->exec_command(hwif, tf->command); |
93 | ndelay(400); /* FIXME */ | 94 | ndelay(400); /* FIXME */ |
94 | return pre_task_out_intr(drive, cmd->rq); | 95 | return pre_task_out_intr(drive, cmd); |
95 | case TASKFILE_MULTI_IN: | 96 | case TASKFILE_MULTI_IN: |
96 | case TASKFILE_IN: | 97 | case TASKFILE_IN: |
97 | handler = task_in_intr; | 98 | handler = task_in_intr; |
@@ -203,7 +204,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) | |||
203 | return stat; | 204 | return stat; |
204 | } | 205 | } |
205 | 206 | ||
206 | static void ide_pio_sector(ide_drive_t *drive, struct request *rq, | 207 | static void ide_pio_sector(ide_drive_t *drive, struct ide_cmd *cmd, |
207 | unsigned int write) | 208 | unsigned int write) |
208 | { | 209 | { |
209 | ide_hwif_t *hwif = drive->hwif; | 210 | ide_hwif_t *hwif = drive->hwif; |
@@ -244,9 +245,9 @@ static void ide_pio_sector(ide_drive_t *drive, struct request *rq, | |||
244 | 245 | ||
245 | /* do the actual data transfer */ | 246 | /* do the actual data transfer */ |
246 | if (write) | 247 | if (write) |
247 | hwif->tp_ops->output_data(drive, rq, buf, SECTOR_SIZE); | 248 | hwif->tp_ops->output_data(drive, cmd, buf, SECTOR_SIZE); |
248 | else | 249 | else |
249 | hwif->tp_ops->input_data(drive, rq, buf, SECTOR_SIZE); | 250 | hwif->tp_ops->input_data(drive, cmd, buf, SECTOR_SIZE); |
250 | 251 | ||
251 | kunmap_atomic(buf, KM_BIO_SRC_IRQ); | 252 | kunmap_atomic(buf, KM_BIO_SRC_IRQ); |
252 | #ifdef CONFIG_HIGHMEM | 253 | #ifdef CONFIG_HIGHMEM |
@@ -254,24 +255,23 @@ static void ide_pio_sector(ide_drive_t *drive, struct request *rq, | |||
254 | #endif | 255 | #endif |
255 | } | 256 | } |
256 | 257 | ||
257 | static void ide_pio_multi(ide_drive_t *drive, struct request *rq, | 258 | static void ide_pio_multi(ide_drive_t *drive, struct ide_cmd *cmd, |
258 | unsigned int write) | 259 | unsigned int write) |
259 | { | 260 | { |
260 | unsigned int nsect; | 261 | unsigned int nsect; |
261 | 262 | ||
262 | nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count); | 263 | nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count); |
263 | while (nsect--) | 264 | while (nsect--) |
264 | ide_pio_sector(drive, rq, write); | 265 | ide_pio_sector(drive, cmd, write); |
265 | } | 266 | } |
266 | 267 | ||
267 | static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, | 268 | static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd, |
268 | unsigned int write) | 269 | unsigned int write) |
269 | { | 270 | { |
270 | struct ide_cmd *cmd = &drive->hwif->cmd; | ||
271 | u8 saved_io_32bit = drive->io_32bit; | 271 | u8 saved_io_32bit = drive->io_32bit; |
272 | 272 | ||
273 | if (blk_fs_request(rq)) | 273 | if (cmd->tf_flags & IDE_TFLAG_FS) |
274 | rq->errors = 0; | 274 | cmd->rq->errors = 0; |
275 | 275 | ||
276 | if (cmd->tf_flags & IDE_TFLAG_IO_16BIT) | 276 | if (cmd->tf_flags & IDE_TFLAG_IO_16BIT) |
277 | drive->io_32bit = 0; | 277 | drive->io_32bit = 0; |
@@ -281,22 +281,21 @@ static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, | |||
281 | switch (cmd->data_phase) { | 281 | switch (cmd->data_phase) { |
282 | case TASKFILE_MULTI_IN: | 282 | case TASKFILE_MULTI_IN: |
283 | case TASKFILE_MULTI_OUT: | 283 | case TASKFILE_MULTI_OUT: |
284 | ide_pio_multi(drive, rq, write); | 284 | ide_pio_multi(drive, cmd, write); |
285 | break; | 285 | break; |
286 | default: | 286 | default: |
287 | ide_pio_sector(drive, rq, write); | 287 | ide_pio_sector(drive, cmd, write); |
288 | break; | 288 | break; |
289 | } | 289 | } |
290 | 290 | ||
291 | drive->io_32bit = saved_io_32bit; | 291 | drive->io_32bit = saved_io_32bit; |
292 | } | 292 | } |
293 | 293 | ||
294 | static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, | 294 | static ide_startstop_t task_error(ide_drive_t *drive, struct ide_cmd *cmd, |
295 | const char *s, u8 stat) | 295 | const char *s, u8 stat) |
296 | { | 296 | { |
297 | if (blk_fs_request(rq)) { | 297 | if (cmd->tf_flags & IDE_TFLAG_FS) { |
298 | ide_hwif_t *hwif = drive->hwif; | 298 | ide_hwif_t *hwif = drive->hwif; |
299 | struct ide_cmd *cmd = &hwif->cmd; | ||
300 | int sectors = hwif->nsect - hwif->nleft; | 299 | int sectors = hwif->nsect - hwif->nleft; |
301 | 300 | ||
302 | switch (cmd->data_phase) { | 301 | switch (cmd->data_phase) { |
@@ -323,19 +322,17 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, | |||
323 | return ide_error(drive, s, stat); | 322 | return ide_error(drive, s, stat); |
324 | } | 323 | } |
325 | 324 | ||
326 | void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) | 325 | void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat) |
327 | { | 326 | { |
328 | if (blk_fs_request(rq) == 0) { | 327 | if ((cmd->tf_flags & IDE_TFLAG_FS) == 0) { |
329 | struct ide_cmd *cmd = rq->special; | ||
330 | u8 err = ide_read_error(drive); | 328 | u8 err = ide_read_error(drive); |
331 | 329 | ||
332 | if (cmd) | 330 | ide_complete_cmd(drive, cmd, stat, err); |
333 | ide_complete_cmd(drive, cmd, stat, err); | ||
334 | ide_complete_rq(drive, err); | 331 | ide_complete_rq(drive, err); |
335 | return; | 332 | return; |
336 | } | 333 | } |
337 | 334 | ||
338 | ide_end_request(drive, 1, rq->nr_sectors); | 335 | ide_end_request(drive, 1, cmd->rq->nr_sectors); |
339 | } | 336 | } |
340 | 337 | ||
341 | /* | 338 | /* |
@@ -344,11 +341,12 @@ void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) | |||
344 | * It might be a spurious irq (shared irq), but it might be a | 341 | * It might be a spurious irq (shared irq), but it might be a |
345 | * command that had no output. | 342 | * command that had no output. |
346 | */ | 343 | */ |
347 | static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat) | 344 | static ide_startstop_t task_in_unexpected(ide_drive_t *drive, |
345 | struct ide_cmd *cmd, u8 stat) | ||
348 | { | 346 | { |
349 | /* Command all done? */ | 347 | /* Command all done? */ |
350 | if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) { | 348 | if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) { |
351 | task_end_request(drive, rq, stat); | 349 | ide_finish_cmd(drive, cmd, stat); |
352 | return ide_stopped; | 350 | return ide_stopped; |
353 | } | 351 | } |
354 | 352 | ||
@@ -363,25 +361,25 @@ static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq | |||
363 | static ide_startstop_t task_in_intr(ide_drive_t *drive) | 361 | static ide_startstop_t task_in_intr(ide_drive_t *drive) |
364 | { | 362 | { |
365 | ide_hwif_t *hwif = drive->hwif; | 363 | ide_hwif_t *hwif = drive->hwif; |
366 | struct request *rq = hwif->rq; | 364 | struct ide_cmd *cmd = &drive->hwif->cmd; |
367 | u8 stat = hwif->tp_ops->read_status(hwif); | 365 | u8 stat = hwif->tp_ops->read_status(hwif); |
368 | 366 | ||
369 | /* Error? */ | 367 | /* Error? */ |
370 | if (stat & ATA_ERR) | 368 | if (stat & ATA_ERR) |
371 | return task_error(drive, rq, __func__, stat); | 369 | return task_error(drive, cmd, __func__, stat); |
372 | 370 | ||
373 | /* Didn't want any data? Odd. */ | 371 | /* Didn't want any data? Odd. */ |
374 | if ((stat & ATA_DRQ) == 0) | 372 | if ((stat & ATA_DRQ) == 0) |
375 | return task_in_unexpected(drive, rq, stat); | 373 | return task_in_unexpected(drive, cmd, stat); |
376 | 374 | ||
377 | ide_pio_datablock(drive, rq, 0); | 375 | ide_pio_datablock(drive, cmd, 0); |
378 | 376 | ||
379 | /* Are we done? Check status and finish transfer. */ | 377 | /* Are we done? Check status and finish transfer. */ |
380 | if (!hwif->nleft) { | 378 | if (!hwif->nleft) { |
381 | stat = wait_drive_not_busy(drive); | 379 | stat = wait_drive_not_busy(drive); |
382 | if (!OK_STAT(stat, 0, BAD_STAT)) | 380 | if (!OK_STAT(stat, 0, BAD_STAT)) |
383 | return task_error(drive, rq, __func__, stat); | 381 | return task_error(drive, cmd, __func__, stat); |
384 | task_end_request(drive, rq, stat); | 382 | ide_finish_cmd(drive, cmd, stat); |
385 | return ide_stopped; | 383 | return ide_stopped; |
386 | } | 384 | } |
387 | 385 | ||
@@ -397,31 +395,31 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive) | |||
397 | static ide_startstop_t task_out_intr (ide_drive_t *drive) | 395 | static ide_startstop_t task_out_intr (ide_drive_t *drive) |
398 | { | 396 | { |
399 | ide_hwif_t *hwif = drive->hwif; | 397 | ide_hwif_t *hwif = drive->hwif; |
400 | struct request *rq = hwif->rq; | 398 | struct ide_cmd *cmd = &drive->hwif->cmd; |
401 | u8 stat = hwif->tp_ops->read_status(hwif); | 399 | u8 stat = hwif->tp_ops->read_status(hwif); |
402 | 400 | ||
403 | if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) | 401 | if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) |
404 | return task_error(drive, rq, __func__, stat); | 402 | return task_error(drive, cmd, __func__, stat); |
405 | 403 | ||
406 | /* Deal with unexpected ATA data phase. */ | 404 | /* Deal with unexpected ATA data phase. */ |
407 | if (((stat & ATA_DRQ) == 0) ^ !hwif->nleft) | 405 | if (((stat & ATA_DRQ) == 0) ^ !hwif->nleft) |
408 | return task_error(drive, rq, __func__, stat); | 406 | return task_error(drive, cmd, __func__, stat); |
409 | 407 | ||
410 | if (!hwif->nleft) { | 408 | if (!hwif->nleft) { |
411 | task_end_request(drive, rq, stat); | 409 | ide_finish_cmd(drive, cmd, stat); |
412 | return ide_stopped; | 410 | return ide_stopped; |
413 | } | 411 | } |
414 | 412 | ||
415 | /* Still data left to transfer. */ | 413 | /* Still data left to transfer. */ |
416 | ide_pio_datablock(drive, rq, 1); | 414 | ide_pio_datablock(drive, cmd, 1); |
417 | ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); | 415 | ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); |
418 | 416 | ||
419 | return ide_started; | 417 | return ide_started; |
420 | } | 418 | } |
421 | 419 | ||
422 | static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) | 420 | static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, |
421 | struct ide_cmd *cmd) | ||
423 | { | 422 | { |
424 | struct ide_cmd *cmd = &drive->hwif->cmd; | ||
425 | ide_startstop_t startstop; | 423 | ide_startstop_t startstop; |
426 | 424 | ||
427 | if (ide_wait_stat(&startstop, drive, ATA_DRQ, | 425 | if (ide_wait_stat(&startstop, drive, ATA_DRQ, |
@@ -437,7 +435,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) | |||
437 | local_irq_disable(); | 435 | local_irq_disable(); |
438 | 436 | ||
439 | ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); | 437 | ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); |
440 | ide_pio_datablock(drive, rq, 1); | 438 | ide_pio_datablock(drive, cmd, 1); |
441 | 439 | ||
442 | return ide_started; | 440 | return ide_started; |
443 | } | 441 | } |