diff options
| -rw-r--r-- | drivers/ide/ide-io.c | 68 | ||||
| -rw-r--r-- | drivers/ide/ide.c | 52 | ||||
| -rw-r--r-- | include/linux/ide.h | 7 |
3 files changed, 48 insertions, 79 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index ecfb87c10097..ec709269c066 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
| @@ -543,30 +543,6 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) | |||
| 543 | return ide_started; | 543 | return ide_started; |
| 544 | } | 544 | } |
| 545 | 545 | ||
| 546 | /* | ||
| 547 | * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away | ||
| 548 | */ | ||
| 549 | static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) | ||
| 550 | { | ||
| 551 | switch (req_pio) { | ||
| 552 | case 202: | ||
| 553 | case 201: | ||
| 554 | case 200: | ||
| 555 | case 102: | ||
| 556 | case 101: | ||
| 557 | case 100: | ||
| 558 | return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0; | ||
| 559 | case 9: | ||
| 560 | case 8: | ||
| 561 | return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0; | ||
| 562 | case 7: | ||
| 563 | case 6: | ||
| 564 | return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0; | ||
| 565 | default: | ||
| 566 | return 0; | ||
| 567 | } | ||
| 568 | } | ||
| 569 | |||
| 570 | /** | 546 | /** |
| 571 | * do_special - issue some special commands | 547 | * do_special - issue some special commands |
| 572 | * @drive: drive the command is for | 548 | * @drive: drive the command is for |
| @@ -584,46 +560,12 @@ static ide_startstop_t do_special (ide_drive_t *drive) | |||
| 584 | #ifdef DEBUG | 560 | #ifdef DEBUG |
| 585 | printk("%s: do_special: 0x%02x\n", drive->name, s->all); | 561 | printk("%s: do_special: 0x%02x\n", drive->name, s->all); |
| 586 | #endif | 562 | #endif |
| 587 | if (s->b.set_tune) { | 563 | if (drive->media == ide_disk) |
| 588 | ide_hwif_t *hwif = drive->hwif; | 564 | return ide_disk_special(drive); |
| 589 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
| 590 | u8 req_pio = drive->tune_req; | ||
| 591 | |||
| 592 | s->b.set_tune = 0; | ||
| 593 | |||
| 594 | if (set_pio_mode_abuse(drive->hwif, req_pio)) { | ||
| 595 | /* | ||
| 596 | * take ide_lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT | ||
| 597 | */ | ||
| 598 | if (req_pio == 8 || req_pio == 9) { | ||
| 599 | unsigned long flags; | ||
| 600 | |||
| 601 | spin_lock_irqsave(&ide_lock, flags); | ||
| 602 | port_ops->set_pio_mode(drive, req_pio); | ||
| 603 | spin_unlock_irqrestore(&ide_lock, flags); | ||
| 604 | } else | ||
| 605 | port_ops->set_pio_mode(drive, req_pio); | ||
| 606 | } else { | ||
| 607 | int keep_dma = | ||
| 608 | !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | ||
| 609 | |||
| 610 | ide_set_pio(drive, req_pio); | ||
| 611 | |||
| 612 | if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { | ||
| 613 | if (keep_dma) | ||
| 614 | ide_dma_on(drive); | ||
| 615 | } | ||
| 616 | } | ||
| 617 | |||
| 618 | return ide_stopped; | ||
| 619 | } else { | ||
| 620 | if (drive->media == ide_disk) | ||
| 621 | return ide_disk_special(drive); | ||
| 622 | 565 | ||
| 623 | s->all = 0; | 566 | s->all = 0; |
| 624 | drive->mult_req = 0; | 567 | drive->mult_req = 0; |
| 625 | return ide_stopped; | 568 | return ide_stopped; |
| 626 | } | ||
| 627 | } | 569 | } |
| 628 | 570 | ||
| 629 | void ide_map_sg(ide_drive_t *drive, struct request *rq) | 571 | void ide_map_sg(ide_drive_t *drive, struct request *rq) |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 9d3482d907c9..73e1cc5839d3 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
| @@ -314,9 +314,32 @@ out: | |||
| 314 | #endif | 314 | #endif |
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | /* | ||
| 318 | * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away | ||
| 319 | */ | ||
| 320 | static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) | ||
| 321 | { | ||
| 322 | switch (req_pio) { | ||
| 323 | case 202: | ||
| 324 | case 201: | ||
| 325 | case 200: | ||
| 326 | case 102: | ||
| 327 | case 101: | ||
| 328 | case 100: | ||
| 329 | return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0; | ||
| 330 | case 9: | ||
| 331 | case 8: | ||
| 332 | return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0; | ||
| 333 | case 7: | ||
| 334 | case 6: | ||
| 335 | return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0; | ||
| 336 | default: | ||
| 337 | return 0; | ||
| 338 | } | ||
| 339 | } | ||
| 340 | |||
| 317 | static int set_pio_mode(ide_drive_t *drive, int arg) | 341 | static int set_pio_mode(ide_drive_t *drive, int arg) |
| 318 | { | 342 | { |
| 319 | struct request *rq; | ||
| 320 | ide_hwif_t *hwif = drive->hwif; | 343 | ide_hwif_t *hwif = drive->hwif; |
| 321 | const struct ide_port_ops *port_ops = hwif->port_ops; | 344 | const struct ide_port_ops *port_ops = hwif->port_ops; |
| 322 | 345 | ||
| @@ -327,17 +350,26 @@ static int set_pio_mode(ide_drive_t *drive, int arg) | |||
| 327 | (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) | 350 | (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) |
| 328 | return -ENOSYS; | 351 | return -ENOSYS; |
| 329 | 352 | ||
| 330 | if (drive->special.b.set_tune) | 353 | if (set_pio_mode_abuse(drive->hwif, arg)) { |
| 331 | return -EBUSY; | 354 | if (arg == 8 || arg == 9) { |
| 355 | unsigned long flags; | ||
| 332 | 356 | ||
| 333 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | 357 | /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */ |
| 334 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; | 358 | spin_lock_irqsave(&ide_lock, flags); |
| 359 | port_ops->set_pio_mode(drive, arg); | ||
| 360 | spin_unlock_irqrestore(&ide_lock, flags); | ||
| 361 | } else | ||
| 362 | port_ops->set_pio_mode(drive, arg); | ||
| 363 | } else { | ||
| 364 | int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | ||
| 335 | 365 | ||
| 336 | drive->tune_req = (u8) arg; | 366 | ide_set_pio(drive, arg); |
| 337 | drive->special.b.set_tune = 1; | ||
| 338 | 367 | ||
| 339 | blk_execute_rq(drive->queue, NULL, rq, 0); | 368 | if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { |
| 340 | blk_put_request(rq); | 369 | if (keep_dma) |
| 370 | ide_dma_on(drive); | ||
| 371 | } | ||
| 372 | } | ||
| 341 | 373 | ||
| 342 | return 0; | 374 | return 0; |
| 343 | } | 375 | } |
| @@ -367,7 +399,7 @@ ide_gen_devset_rw(io_32bit, io_32bit); | |||
| 367 | ide_gen_devset_rw(keepsettings, ksettings); | 399 | ide_gen_devset_rw(keepsettings, ksettings); |
| 368 | ide_gen_devset_rw(unmaskirq, unmaskirq); | 400 | ide_gen_devset_rw(unmaskirq, unmaskirq); |
| 369 | ide_gen_devset_rw(using_dma, using_dma); | 401 | ide_gen_devset_rw(using_dma, using_dma); |
| 370 | __IDE_DEVSET(pio_mode, 0, NULL, set_pio_mode); | 402 | __IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode); |
| 371 | 403 | ||
| 372 | static int generic_ide_suspend(struct device *dev, pm_message_t mesg) | 404 | static int generic_ide_suspend(struct device *dev, pm_message_t mesg) |
| 373 | { | 405 | { |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 3e418b996ef5..a5e1888b1dab 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
| @@ -262,8 +262,6 @@ static inline int __ide_default_irq(unsigned long base) | |||
| 262 | * set_geometry : respecify drive geometry | 262 | * set_geometry : respecify drive geometry |
| 263 | * recalibrate : seek to cyl 0 | 263 | * recalibrate : seek to cyl 0 |
| 264 | * set_multmode : set multmode count | 264 | * set_multmode : set multmode count |
| 265 | * set_tune : tune interface for drive | ||
| 266 | * serviced : service command | ||
| 267 | * reserved : unused | 265 | * reserved : unused |
| 268 | */ | 266 | */ |
| 269 | typedef union { | 267 | typedef union { |
| @@ -272,9 +270,7 @@ typedef union { | |||
| 272 | unsigned set_geometry : 1; | 270 | unsigned set_geometry : 1; |
| 273 | unsigned recalibrate : 1; | 271 | unsigned recalibrate : 1; |
| 274 | unsigned set_multmode : 1; | 272 | unsigned set_multmode : 1; |
| 275 | unsigned set_tune : 1; | 273 | unsigned reserved : 5; |
| 276 | unsigned serviced : 1; | ||
| 277 | unsigned reserved : 3; | ||
| 278 | } b; | 274 | } b; |
| 279 | } special_t; | 275 | } special_t; |
| 280 | 276 | ||
| @@ -514,7 +510,6 @@ struct ide_drive_s { | |||
| 514 | u8 ready_stat; /* min status value for drive ready */ | 510 | u8 ready_stat; /* min status value for drive ready */ |
| 515 | u8 mult_count; /* current multiple sector setting */ | 511 | u8 mult_count; /* current multiple sector setting */ |
| 516 | u8 mult_req; /* requested multiple sector setting */ | 512 | u8 mult_req; /* requested multiple sector setting */ |
| 517 | u8 tune_req; /* requested drive tuning setting */ | ||
| 518 | u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ | 513 | u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ |
| 519 | u8 bad_wstat; /* used for ignoring ATA_DF */ | 514 | u8 bad_wstat; /* used for ignoring ATA_DF */ |
| 520 | u8 head; /* "real" number of heads */ | 515 | u8 head; /* "real" number of heads */ |
