aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-io.c68
-rw-r--r--drivers/ide/ide.c52
-rw-r--r--include/linux/ide.h7
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 */
549static 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
629void ide_map_sg(ide_drive_t *drive, struct request *rq) 571void 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 */
320static 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
317static int set_pio_mode(ide_drive_t *drive, int arg) 341static 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);
367ide_gen_devset_rw(keepsettings, ksettings); 399ide_gen_devset_rw(keepsettings, ksettings);
368ide_gen_devset_rw(unmaskirq, unmaskirq); 400ide_gen_devset_rw(unmaskirq, unmaskirq);
369ide_gen_devset_rw(using_dma, using_dma); 401ide_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
372static int generic_ide_suspend(struct device *dev, pm_message_t mesg) 404static 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 */
269typedef union { 267typedef 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 */