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