ide-devsets.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include <linux/kernel.h>
  2. #include <linux/gfp.h>
  3. #include <linux/ide.h>
  4. DEFINE_MUTEX(ide_setting_mtx);
  5. ide_devset_get(io_32bit, io_32bit);
  6. static int set_io_32bit(ide_drive_t *drive, int arg)
  7. {
  8. if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
  9. return -EPERM;
  10. if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
  11. return -EINVAL;
  12. drive->io_32bit = arg;
  13. return 0;
  14. }
  15. ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
  16. static int set_ksettings(ide_drive_t *drive, int arg)
  17. {
  18. if (arg < 0 || arg > 1)
  19. return -EINVAL;
  20. if (arg)
  21. drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
  22. else
  23. drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
  24. return 0;
  25. }
  26. ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
  27. static int set_using_dma(ide_drive_t *drive, int arg)
  28. {
  29. #ifdef CONFIG_BLK_DEV_IDEDMA
  30. int err = -EPERM;
  31. if (arg < 0 || arg > 1)
  32. return -EINVAL;
  33. if (ata_id_has_dma(drive->id) == 0)
  34. goto out;
  35. if (drive->hwif->dma_ops == NULL)
  36. goto out;
  37. err = 0;
  38. if (arg) {
  39. if (ide_set_dma(drive))
  40. err = -EIO;
  41. } else
  42. ide_dma_off(drive);
  43. out:
  44. return err;
  45. #else
  46. if (arg < 0 || arg > 1)
  47. return -EINVAL;
  48. return -EPERM;
  49. #endif
  50. }
  51. /*
  52. * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
  53. */
  54. static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
  55. {
  56. switch (req_pio) {
  57. case 202:
  58. case 201:
  59. case 200:
  60. case 102:
  61. case 101:
  62. case 100:
  63. return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
  64. case 9:
  65. case 8:
  66. return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
  67. case 7:
  68. case 6:
  69. return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
  70. default:
  71. return 0;
  72. }
  73. }
  74. static int set_pio_mode(ide_drive_t *drive, int arg)
  75. {
  76. ide_hwif_t *hwif = drive->hwif;
  77. const struct ide_port_ops *port_ops = hwif->port_ops;
  78. if (arg < 0 || arg > 255)
  79. return -EINVAL;
  80. if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
  81. (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
  82. return -ENOSYS;
  83. if (set_pio_mode_abuse(drive->hwif, arg)) {
  84. drive->pio_mode = arg + XFER_PIO_0;
  85. if (arg == 8 || arg == 9) {
  86. unsigned long flags;
  87. /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
  88. spin_lock_irqsave(&hwif->lock, flags);
  89. port_ops->set_pio_mode(hwif, drive);
  90. spin_unlock_irqrestore(&hwif->lock, flags);
  91. } else
  92. port_ops->set_pio_mode(hwif, drive);
  93. } else {
  94. int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
  95. ide_set_pio(drive, arg);
  96. if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
  97. if (keep_dma)
  98. ide_dma_on(drive);
  99. }
  100. }
  101. return 0;
  102. }
  103. ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
  104. static int set_unmaskirq(ide_drive_t *drive, int arg)
  105. {
  106. if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
  107. return -EPERM;
  108. if (arg < 0 || arg > 1)
  109. return -EINVAL;
  110. if (arg)
  111. drive->dev_flags |= IDE_DFLAG_UNMASK;
  112. else
  113. drive->dev_flags &= ~IDE_DFLAG_UNMASK;
  114. return 0;
  115. }
  116. ide_ext_devset_rw_sync(io_32bit, io_32bit);
  117. ide_ext_devset_rw_sync(keepsettings, ksettings);
  118. ide_ext_devset_rw_sync(unmaskirq, unmaskirq);
  119. ide_ext_devset_rw_sync(using_dma, using_dma);
  120. __IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode);
  121. int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
  122. int arg)
  123. {
  124. struct request_queue *q = drive->queue;
  125. struct request *rq;
  126. int ret = 0;
  127. if (!(setting->flags & DS_SYNC))
  128. return setting->set(drive, arg);
  129. rq = blk_get_request(q, READ, __GFP_RECLAIM);
  130. rq->cmd_type = REQ_TYPE_DRV_PRIV;
  131. rq->cmd_len = 5;
  132. rq->cmd[0] = REQ_DEVSET_EXEC;
  133. *(int *)&rq->cmd[1] = arg;
  134. rq->special = setting->set;
  135. if (blk_execute_rq(q, NULL, rq, 0))
  136. ret = rq->errors;
  137. blk_put_request(rq);
  138. return ret;
  139. }
  140. ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq)
  141. {
  142. int err, (*setfunc)(ide_drive_t *, int) = rq->special;
  143. err = setfunc(drive, *(int *)&rq->cmd[1]);
  144. if (err)
  145. rq->errors = err;
  146. ide_complete_rq(drive, err, blk_rq_bytes(rq));
  147. return ide_stopped;
  148. }