Blame view

drivers/ide/ide-taskfile.c 16.6 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
59bca8cc9   Bartlomiej Zolnierkiewicz   ide: update/add m...
2
3
4
   *  Copyright (C) 2000-2002	   Michael Cornwell <cornwell@acm.org>
   *  Copyright (C) 2000-2002	   Andre Hedrick <andre@linux-ide.org>
   *  Copyright (C) 2001-2002	   Klaus Smolin
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
   *					IBM Storage Technology Division
59bca8cc9   Bartlomiej Zolnierkiewicz   ide: update/add m...
6
   *  Copyright (C) 2003-2004, 2007  Bartlomiej Zolnierkiewicz
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
   *
   *  The big the bad and the ugly.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
12
  #include <linux/types.h>
  #include <linux/string.h>
  #include <linux/kernel.h>
38789fda2   Paul Gortmaker   ide/ata: Add expo...
13
  #include <linux/export.h>
651c29a17   Andrew Morton   [PATCH] ide: touc...
14
  #include <linux/sched.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
  #include <linux/interrupt.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
  #include <linux/errno.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
  #include <linux/delay.h>
  #include <linux/hdreg.h>
  #include <linux/ide.h>
55c16a700   Jens Axboe   IDE: sg chaining ...
21
  #include <linux/scatterlist.h>
2d5abcede   Jaswinder Singh Rajput   ide: ide-taskfile...
22
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
  #include <asm/io.h>
3153c26b5   Sergei Shtylyov   ide: refactor tf_...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd)
  {
  	ide_hwif_t *hwif = drive->hwif;
  	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
  
  	/* Be sure we're looking at the low order bytes */
  	tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
  
  	tp_ops->tf_read(drive, &cmd->tf, cmd->valid.in.tf);
  
  	if (cmd->tf_flags & IDE_TFLAG_LBA48) {
  		tp_ops->write_devctl(hwif, ATA_HOB | ATA_DEVCTL_OBS);
  
  		tp_ops->tf_read(drive, &cmd->hob, cmd->valid.in.hob);
  	}
  }
745483f10   Sergei Shtylyov   ide: simplify 'st...
41
  void ide_tf_dump(const char *s, struct ide_cmd *cmd)
9e42237f2   Bartlomiej Zolnierkiewicz   ide: add ide_tf_l...
42
  {
807e35d69   Bartlomiej Zolnierkiewicz   ide: use ide_tf_l...
43
44
45
46
  #ifdef DEBUG
  	printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x "
  		"lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x
  ",
745483f10   Sergei Shtylyov   ide: simplify 'st...
47
48
49
50
51
52
  	       s, cmd->tf.feature, cmd->tf.nsect,
  	       cmd->tf.lbal, cmd->tf.lbam, cmd->tf.lbah,
  	       cmd->tf.device, cmd->tf.command);
  	printk("%s: hob: nsect 0x%02x lbal 0x%02x lbam 0x%02x lbah 0x%02x
  ",
  	       s, cmd->hob.nsect, cmd->hob.lbal, cmd->hob.lbam, cmd->hob.lbah);
807e35d69   Bartlomiej Zolnierkiewicz   ide: use ide_tf_l...
53
  #endif
089c5c7e0   Bartlomiej Zolnierkiewicz   ide: factor out d...
54
  }
2d5abcede   Jaswinder Singh Rajput   ide: ide-taskfile...
55
  int taskfile_lib_get_identify(ide_drive_t *drive, u8 *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  {
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
57
  	struct ide_cmd cmd;
650d841d9   Bartlomiej Zolnierkiewicz   ide: add struct i...
58

22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
59
60
  	memset(&cmd, 0, sizeof(cmd));
  	cmd.tf.nsect = 0x01;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  	if (drive->media == ide_disk)
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
62
  		cmd.tf.command = ATA_CMD_ID_ATA;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
  	else
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
64
  		cmd.tf.command = ATA_CMD_ID_ATAPI;
60f85019c   Sergei Shtylyov   ide: replace IDE_...
65
66
  	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
  	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
67
  	cmd.protocol = ATA_PROT_PIO;
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
68
69
  
  	return ide_raw_taskfile(drive, &cmd, buf, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
  }
1192e528e   Bartlomiej Zolnierkiewicz   ide: use ->data_p...
71
  static ide_startstop_t task_no_data_intr(ide_drive_t *);
adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
72
  static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct ide_cmd *);
901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
73
  static ide_startstop_t task_pio_intr(ide_drive_t *);
1192e528e   Bartlomiej Zolnierkiewicz   ide: use ->data_p...
74

adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
75
  ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
  {
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
77
  	ide_hwif_t *hwif = drive->hwif;
adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
78
  	struct ide_cmd *cmd = &hwif->cmd;
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
79
  	struct ide_taskfile *tf = &cmd->tf;
57d7366b7   Bartlomiej Zolnierkiewicz   ide: remove 'hand...
80
  	ide_handler_t *handler = NULL;
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
81
  	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
f37afdaca   Bartlomiej Zolnierkiewicz   ide: constify str...
82
  	const struct ide_dma_ops *dma_ops = hwif->dma_ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83

0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
84
85
86
  	if (orig_cmd->protocol == ATA_PROT_PIO &&
  	    (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
  	    drive->mult_count == 0) {
2d5abcede   Jaswinder Singh Rajput   ide: ide-taskfile...
87
88
  		pr_err("%s: multimode not set!
  ", drive->name);
0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
89
  		return ide_stopped;
1edee60e9   Bartlomiej Zolnierkiewicz   ide: merge flagge...
90
  	}
adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
91
92
  	if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
  		orig_cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS;
1edee60e9   Bartlomiej Zolnierkiewicz   ide: merge flagge...
93

adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
94
  	memcpy(cmd, orig_cmd, sizeof(*cmd));
d6ff9f64e   Bartlomiej Zolnierkiewicz   ide: merge all TA...
95

22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
96
  	if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
745483f10   Sergei Shtylyov   ide: simplify 'st...
97
  		ide_tf_dump(drive->name, cmd);
ecf3a31d2   Sergei Shtylyov   ide: turn set_irq...
98
  		tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
35218d1ca   Sergei Shtylyov   ide: move data re...
99
100
  
  		if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
745483f10   Sergei Shtylyov   ide: simplify 'st...
101
  			u8 data[2] = { cmd->tf.data, cmd->hob.data };
35218d1ca   Sergei Shtylyov   ide: move data re...
102
103
104
  
  			tp_ops->output_data(drive, cmd, data, 2);
  		}
4109d19af   Sergei Shtylyov   ide: move common ...
105
106
107
108
109
110
111
112
113
  
  		if (cmd->valid.out.tf & IDE_VALID_DEVICE) {
  			u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ?
  				  0xE0 : 0xEF;
  
  			if (!(cmd->ftf_flags & IDE_FTFLAG_FLAGGED))
  				cmd->tf.device &= HIHI;
  			cmd->tf.device |= drive->select;
  		}
c9ff9e7b6   Sergei Shtylyov   ide: refactor tf_...
114
115
  		tp_ops->tf_load(drive, &cmd->hob, cmd->valid.out.hob);
  		tp_ops->tf_load(drive, &cmd->tf,  cmd->valid.out.tf);
089c5c7e0   Bartlomiej Zolnierkiewicz   ide: factor out d...
116
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117

0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
118
119
120
121
122
123
124
  	switch (cmd->protocol) {
  	case ATA_PROT_PIO:
  		if (cmd->tf_flags & IDE_TFLAG_WRITE) {
  			tp_ops->exec_command(hwif, tf->command);
  			ndelay(400);	/* FIXME */
  			return pre_task_out_intr(drive, cmd);
  		}
901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
125
  		handler = task_pio_intr;
1192e528e   Bartlomiej Zolnierkiewicz   ide: use ->data_p...
126
  		/* fall-through */
0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
127
  	case ATA_PROT_NODATA:
57d7366b7   Bartlomiej Zolnierkiewicz   ide: remove 'hand...
128
129
  		if (handler == NULL)
  			handler = task_no_data_intr;
35b5d0be3   Bartlomiej Zolnierkiewicz   ide: remove ide_e...
130
  		ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  		return ide_started;
b788ee9c6   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
132
  	case ATA_PROT_DMA:
5ae5412d9   Bartlomiej Zolnierkiewicz   ide: add ide_dma_...
133
  		if (ide_dma_prepare(drive, cmd))
10d90157c   Bartlomiej Zolnierkiewicz   ide: convert do_r...
134
  			return ide_stopped;
22117d6ea   Bartlomiej Zolnierkiewicz   ide: add ->dma_ti...
135
  		hwif->expiry = dma_ops->dma_timer_expiry;
35b5d0be3   Bartlomiej Zolnierkiewicz   ide: remove ide_e...
136
  		ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD);
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
137
  		dma_ops->dma_start(drive);
b788ee9c6   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
138
  	default:
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
139
  		return ide_started;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
  }
f6e29e35c   Bartlomiej Zolnierkiewicz   ide-disk: use do_...
142
  EXPORT_SYMBOL_GPL(do_rw_taskfile);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143

d6ff9f64e   Bartlomiej Zolnierkiewicz   ide: merge all TA...
144
  static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
  {
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
146
  	ide_hwif_t *hwif = drive->hwif;
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
147
148
149
  	struct ide_cmd *cmd = &hwif->cmd;
  	struct ide_taskfile *tf = &cmd->tf;
  	int custom = (cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
d6ff9f64e   Bartlomiej Zolnierkiewicz   ide: merge all TA...
150
  	int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
  	u8 stat;
90d2c6bc6   Bartlomiej Zolnierkiewicz   ide: enable local...
152
  	local_irq_enable_in_hardirq();
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
153
154
  	while (1) {
  		stat = hwif->tp_ops->read_status(hwif);
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
155
  		if ((stat & ATA_BUSY) == 0 || retries-- == 0)
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
156
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  		udelay(10);
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
158
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159

d6ff9f64e   Bartlomiej Zolnierkiewicz   ide: merge all TA...
160
161
162
  	if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) {
  		if (custom && tf->command == ATA_CMD_SET_MULTI) {
  			drive->mult_req = drive->mult_count = 0;
ca1b96e00   Bartlomiej Zolnierkiewicz   ide: replace spec...
163
  			drive->special_flags |= IDE_SFLAG_RECALIBRATE;
d6ff9f64e   Bartlomiej Zolnierkiewicz   ide: merge all TA...
164
165
166
167
168
  			(void)ide_dump_status(drive, __func__, stat);
  			return ide_stopped;
  		} else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) {
  			if ((stat & (ATA_ERR | ATA_DRQ)) == 0) {
  				ide_set_handler(drive, &task_no_data_intr,
60c0cd02b   Bartlomiej Zolnierkiewicz   ide: set hwif->ex...
169
  						WAIT_WORSTCASE);
d6ff9f64e   Bartlomiej Zolnierkiewicz   ide: merge all TA...
170
171
172
  				return ide_started;
  			}
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
  		return ide_error(drive, "task_no_data_intr", stat);
d6ff9f64e   Bartlomiej Zolnierkiewicz   ide: merge all TA...
174
  	}
c47137a99   Bartlomiej Zolnierkiewicz   ide: add ide_read...
175

e7fedc3ca   Bartlomiej Zolnierkiewicz   ide: use ide_comp...
176
  	if (custom && tf->command == ATA_CMD_SET_MULTI)
d6ff9f64e   Bartlomiej Zolnierkiewicz   ide: merge all TA...
177
  		drive->mult_count = drive->mult_req;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178

d364c7f50   Bartlomiej Zolnierkiewicz   ide: use ide_comp...
179
180
  	if (custom == 0 || tf->command == ATA_CMD_IDLEIMMEDIATE ||
  	    tf->command == ATA_CMD_CHK_POWER) {
a09485df9   Bartlomiej Zolnierkiewicz   ide: move request...
181
  		struct request *rq = hwif->rq;
a09485df9   Bartlomiej Zolnierkiewicz   ide: move request...
182
183
184
  
  		if (blk_pm_request(rq))
  			ide_complete_pm_rq(drive, rq);
2230d90dd   Bartlomiej Zolnierkiewicz   ide: sanitize ide...
185
186
  		else
  			ide_finish_cmd(drive, cmd, stat);
a09485df9   Bartlomiej Zolnierkiewicz   ide: move request...
187
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
  	return ide_stopped;
  }
da6f4c7f6   Adrian Bunk   ide: make wait_dr...
190
  static u8 wait_drive_not_busy(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
  {
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
192
  	ide_hwif_t *hwif = drive->hwif;
b42fa1331   Masatake YAMATO   ide: never called...
193
  	int retries;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
195
196
  	u8 stat;
  
  	/*
25985edce   Lucas De Marchi   Fix common misspe...
197
  	 * Last sector was transferred, wait until device is ready.  This can
f54feafa6   Bartlomiej Zolnierkiewicz   ide: increase tim...
198
  	 * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
  	 */
f54feafa6   Bartlomiej Zolnierkiewicz   ide: increase tim...
200
  	for (retries = 0; retries < 1000; retries++) {
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
201
  		stat = hwif->tp_ops->read_status(hwif);
c47137a99   Bartlomiej Zolnierkiewicz   ide: add ide_read...
202

3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
203
  		if (stat & ATA_BUSY)
b42fa1331   Masatake YAMATO   ide: never called...
204
205
206
207
  			udelay(10);
  		else
  			break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208

3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
209
  	if (stat & ATA_BUSY)
2d5abcede   Jaswinder Singh Rajput   ide: ide-taskfile...
210
211
  		pr_err("%s: drive still BUSY!
  ", drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
213
214
  
  	return stat;
  }
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
215
216
  void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
  		   unsigned int write, unsigned int len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
218
219
  {
  	ide_hwif_t *hwif = drive->hwif;
  	struct scatterlist *sg = hwif->sg_table;
b6308ee0c   Bartlomiej Zolnierkiewicz   ide: move command...
220
  	struct scatterlist *cursg = cmd->cursg;
7fa350b47   David S. Miller   ide: Fix annoying...
221
  	unsigned long uninitialized_var(flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
  	struct page *page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223
224
  	unsigned int offset;
  	u8 *buf;
b6308ee0c   Bartlomiej Zolnierkiewicz   ide: move command...
225
  	cursg = cmd->cursg;
7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
226
227
228
229
230
  	if (cursg == NULL)
  		cursg = cmd->cursg = sg;
  
  	while (len) {
  		unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
a90790521   Jean Delvare   IDE: Save a call ...
231
  		int page_is_high;
55c16a700   Jens Axboe   IDE: sg chaining ...
232

7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
233
234
  		if (nr_bytes > PAGE_SIZE)
  			nr_bytes = PAGE_SIZE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235

7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
236
237
238
239
240
241
  		page = sg_page(cursg);
  		offset = cursg->offset + cmd->cursg_ofs;
  
  		/* get the current page and offset */
  		page = nth_page(page, (offset >> PAGE_SHIFT));
  		offset %= PAGE_SIZE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242

a90790521   Jean Delvare   IDE: Save a call ...
243
244
  		page_is_high = PageHighMem(page);
  		if (page_is_high)
f2bc31673   Bartlomiej Zolnierkiewicz   ide: use PageHigh...
245
  			local_irq_save(flags);
7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
246
  		buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247

7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
248
249
  		cmd->nleft -= nr_bytes;
  		cmd->cursg_ofs += nr_bytes;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250

7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
251
252
253
254
  		if (cmd->cursg_ofs == cursg->length) {
  			cursg = cmd->cursg = sg_next(cmd->cursg);
  			cmd->cursg_ofs = 0;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255

7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
256
257
258
259
260
  		/* do the actual data transfer */
  		if (write)
  			hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes);
  		else
  			hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261

7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
262
  		kunmap_atomic(buf, KM_BIO_SRC_IRQ);
f2bc31673   Bartlomiej Zolnierkiewicz   ide: use PageHigh...
263

a90790521   Jean Delvare   IDE: Save a call ...
264
  		if (page_is_high)
f2bc31673   Bartlomiej Zolnierkiewicz   ide: use PageHigh...
265
  			local_irq_restore(flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266

7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
267
268
  		len -= nr_bytes;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
  }
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
270
  EXPORT_SYMBOL_GPL(ide_pio_bytes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271

adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
272
273
  static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
  			      unsigned int write)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
  {
7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
275
  	unsigned int nr_bytes;
35cf2b94d   Tejun Heo   ide: fix ->io_32b...
276
  	u8 saved_io_32bit = drive->io_32bit;
adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
277
278
  	if (cmd->tf_flags & IDE_TFLAG_FS)
  		cmd->rq->errors = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279

22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
280
  	if (cmd->tf_flags & IDE_TFLAG_IO_16BIT)
e3d9a73a8   Bartlomiej Zolnierkiewicz   ide: remove ->dat...
281
  		drive->io_32bit = 0;
35cf2b94d   Tejun Heo   ide: fix ->io_32b...
282

651c29a17   Andrew Morton   [PATCH] ide: touc...
283
  	touch_softlockup_watchdog();
0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
284
  	if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
285
  		nr_bytes = min_t(unsigned, cmd->nleft, drive->mult_count << 9);
0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
286
  	else
7a00798b1   Bartlomiej Zolnierkiewicz   ide: add support ...
287
288
289
  		nr_bytes = SECTOR_SIZE;
  
  	ide_pio_bytes(drive, cmd, write, nr_bytes);
35cf2b94d   Tejun Heo   ide: fix ->io_32b...
290
291
  
  	drive->io_32bit = saved_io_32bit;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
  }
041cea10a   Bartlomiej Zolnierkiewicz   ide: task_error()...
293
  static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
  {
adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
295
  	if (cmd->tf_flags & IDE_TFLAG_FS) {
bf717c0a2   Bartlomiej Zolnierkiewicz   ide: keep track o...
296
  		int nr_bytes = cmd->nbytes - cmd->nleft;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297

0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
298
299
300
  		if (cmd->protocol == ATA_PROT_PIO &&
  		    ((cmd->tf_flags & IDE_TFLAG_WRITE) || cmd->nleft == 0)) {
  			if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
bf717c0a2   Bartlomiej Zolnierkiewicz   ide: keep track o...
301
  				nr_bytes -= drive->mult_count << 9;
0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
302
  			else
bf717c0a2   Bartlomiej Zolnierkiewicz   ide: keep track o...
303
  				nr_bytes -= SECTOR_SIZE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
  		}
bf717c0a2   Bartlomiej Zolnierkiewicz   ide: keep track o...
305
306
  		if (nr_bytes > 0)
  			ide_complete_rq(drive, 0, nr_bytes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
  }
adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
309
  void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  {
6902a5331   Bartlomiej Zolnierkiewicz   ide: pass error v...
311
  	struct request *rq = drive->hwif->rq;
665d66e8f   Bartlomiej Zolnierkiewicz   ide: fix races in...
312
313
  	u8 err = ide_read_error(drive), nsect = cmd->tf.nsect;
  	u8 set_xfer = !!(cmd->tf_flags & IDE_TFLAG_SET_XFER);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314

2230d90dd   Bartlomiej Zolnierkiewicz   ide: sanitize ide...
315
  	ide_complete_cmd(drive, cmd, stat, err);
6902a5331   Bartlomiej Zolnierkiewicz   ide: pass error v...
316
  	rq->errors = err;
665d66e8f   Bartlomiej Zolnierkiewicz   ide: fix races in...
317
318
319
320
321
  
  	if (err == 0 && set_xfer) {
  		ide_set_xfer_rate(drive, nsect);
  		ide_driveid_update(drive);
  	}
f974b196f   Bartlomiej Zolnierkiewicz   ide: pass number ...
322
  	ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
324
325
  }
  
  /*
901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
326
   * Handler for command with PIO data phase.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
   */
901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
328
  static ide_startstop_t task_pio_intr(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
330
  {
  	ide_hwif_t *hwif = drive->hwif;
adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
331
  	struct ide_cmd *cmd = &drive->hwif->cmd;
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
332
  	u8 stat = hwif->tp_ops->read_status(hwif);
901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
333
  	u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334

901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
335
336
337
  	if (write == 0) {
  		/* Error? */
  		if (stat & ATA_ERR)
0a1248c5a   Bartlomiej Zolnierkiewicz   ide: unify exit p...
338
  			goto out_err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339

901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
340
  		/* Didn't want any data? Odd. */
151055ed8   Bartlomiej Zolnierkiewicz   ide: inline task_...
341
342
  		if ((stat & ATA_DRQ) == 0) {
  			/* Command all done? */
0a1248c5a   Bartlomiej Zolnierkiewicz   ide: unify exit p...
343
344
  			if (OK_STAT(stat, ATA_DRDY, ATA_BUSY))
  				goto out_end;
151055ed8   Bartlomiej Zolnierkiewicz   ide: inline task_...
345
346
  
  			/* Assume it was a spurious irq */
0a1248c5a   Bartlomiej Zolnierkiewicz   ide: unify exit p...
347
  			goto out_wait;
151055ed8   Bartlomiej Zolnierkiewicz   ide: inline task_...
348
  		}
901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
349
350
  	} else {
  		if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
0a1248c5a   Bartlomiej Zolnierkiewicz   ide: unify exit p...
351
  			goto out_err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352

901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
353
354
  		/* Deal with unexpected ATA data phase. */
  		if (((stat & ATA_DRQ) == 0) ^ (cmd->nleft == 0))
0a1248c5a   Bartlomiej Zolnierkiewicz   ide: unify exit p...
355
  			goto out_err;
901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
356
  	}
0a1248c5a   Bartlomiej Zolnierkiewicz   ide: unify exit p...
357
358
  	if (write && cmd->nleft == 0)
  		goto out_end;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359
360
  
  	/* Still data left to transfer. */
901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
361
  	ide_pio_datablock(drive, cmd, write);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362

901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
363
364
365
366
  	/* Are we done? Check status and finish transfer. */
  	if (write == 0 && cmd->nleft == 0) {
  		stat = wait_drive_not_busy(drive);
  		if (!OK_STAT(stat, 0, BAD_STAT))
0a1248c5a   Bartlomiej Zolnierkiewicz   ide: unify exit p...
367
  			goto out_err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368

0a1248c5a   Bartlomiej Zolnierkiewicz   ide: unify exit p...
369
370
371
  		goto out_end;
  	}
  out_wait:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
  	/* Still data left to transfer. */
60c0cd02b   Bartlomiej Zolnierkiewicz   ide: set hwif->ex...
373
  	ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
  	return ide_started;
0a1248c5a   Bartlomiej Zolnierkiewicz   ide: unify exit p...
375
  out_end:
2230d90dd   Bartlomiej Zolnierkiewicz   ide: sanitize ide...
376
377
378
  	if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
  		ide_finish_cmd(drive, cmd, stat);
  	else
9780e2dd8   Tejun Heo   ide: convert to r...
379
  		ide_complete_rq(drive, 0, blk_rq_sectors(cmd->rq) << 9);
0a1248c5a   Bartlomiej Zolnierkiewicz   ide: unify exit p...
380
381
  	return ide_stopped;
  out_err:
041cea10a   Bartlomiej Zolnierkiewicz   ide: task_error()...
382
383
  	ide_error_cmd(drive, cmd);
  	return ide_error(drive, __func__, stat);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
  }
adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
385
386
  static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
  					 struct ide_cmd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
388
  {
  	ide_startstop_t startstop;
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
389
  	if (ide_wait_stat(&startstop, drive, ATA_DRQ,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
  			  drive->bad_wstat, WAIT_DRQ)) {
2d5abcede   Jaswinder Singh Rajput   ide: ide-taskfile...
391
392
  		pr_err("%s: no DRQ after issuing %sWRITE%s
  ", drive->name,
0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
393
  			(cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
394
  			(drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
396
  		return startstop;
  	}
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
397
  	if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
  		local_irq_disable();
60c0cd02b   Bartlomiej Zolnierkiewicz   ide: set hwif->ex...
399
  	ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
901bd08a5   Bartlomiej Zolnierkiewicz   ide: merge task_{...
400

adb1af980   Bartlomiej Zolnierkiewicz   ide: pass command...
401
  	ide_pio_datablock(drive, cmd, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
403
404
  
  	return ide_started;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405

22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
406
407
  int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
  		     u16 nsect)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
  {
154ed280e   FUJITA Tomonori   ide-taskfile: con...
409
410
  	struct request *rq;
  	int error;
720fc22a7   Mikulas Patocka   ide: Fix IDE task...
411
  	int rw = !(cmd->tf_flags & IDE_TFLAG_WRITE) ? READ : WRITE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412

720fc22a7   Mikulas Patocka   ide: Fix IDE task...
413
  	rq = blk_get_request(drive->queue, rw, __GFP_WAIT);
154ed280e   FUJITA Tomonori   ide-taskfile: con...
414
  	rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
d868ca243   Tejun Heo   ide-taskfile: don...
415

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
418
419
420
421
  	/*
  	 * (ks) We transfer currently only whole sectors.
  	 * This is suffient for now.  But, it would be great,
  	 * if we would find a solution to transfer any size.
  	 * To support special commands like READ LONG.
  	 */
d868ca243   Tejun Heo   ide-taskfile: don...
422
423
424
425
426
427
  	if (nsect) {
  		error = blk_rq_map_kern(drive->queue, rq, buf,
  					nsect * SECTOR_SIZE, __GFP_WAIT);
  		if (error)
  			goto put_req;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428

22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
429
430
  	rq->special = cmd;
  	cmd->rq = rq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431

154ed280e   FUJITA Tomonori   ide-taskfile: con...
432
  	error = blk_execute_rq(drive->queue, NULL, rq, 0);
154ed280e   FUJITA Tomonori   ide-taskfile: con...
433

d868ca243   Tejun Heo   ide-taskfile: don...
434
435
  put_req:
  	blk_put_request(rq);
154ed280e   FUJITA Tomonori   ide-taskfile: con...
436
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
437
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
  EXPORT_SYMBOL(ide_raw_taskfile);
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
439
  int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
9a3c49be5   Bartlomiej Zolnierkiewicz   ide: add ide_no_d...
440
  {
0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
441
  	cmd->protocol = ATA_PROT_NODATA;
9a3c49be5   Bartlomiej Zolnierkiewicz   ide: add ide_no_d...
442

22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
443
  	return ide_raw_taskfile(drive, cmd, NULL, 0);
9a3c49be5   Bartlomiej Zolnierkiewicz   ide: add ide_no_d...
444
445
  }
  EXPORT_SYMBOL_GPL(ide_no_data_taskfile);
26a5b0407   Bartlomiej Zolnierkiewicz   ide: add missing ...
446
  #ifdef CONFIG_IDE_TASK_IOCTL
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
447
  int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
449
  {
  	ide_task_request_t	*req_task;
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
450
  	struct ide_cmd		cmd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
452
  	u8 *outbuf		= NULL;
  	u8 *inbuf		= NULL;
ac026ff25   Bartlomiej Zolnierkiewicz   ide: remove 'comm...
453
  	u8 *data_buf		= NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
455
  	int err			= 0;
  	int tasksize		= sizeof(struct ide_task_request_s);
3a42bb223   Alan Cox   [PATCH] ide: add ...
456
457
  	unsigned int taskin	= 0;
  	unsigned int taskout	= 0;
ac026ff25   Bartlomiej Zolnierkiewicz   ide: remove 'comm...
458
  	u16 nsect		= 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
  	char __user *buf = (char __user *)arg;
7d543d846   Julia Lawall   drivers/ide: Use ...
460
461
462
  	req_task = memdup_user(buf, tasksize);
  	if (IS_ERR(req_task))
  		return PTR_ERR(req_task);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463

3a42bb223   Alan Cox   [PATCH] ide: add ...
464
465
  	taskout = req_task->out_size;
  	taskin  = req_task->in_size;
2d5abcede   Jaswinder Singh Rajput   ide: ide-taskfile...
466

3a42bb223   Alan Cox   [PATCH] ide: add ...
467
468
469
470
  	if (taskin > 65536 || taskout > 65536) {
  		err = -EINVAL;
  		goto abort;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471
472
473
  
  	if (taskout) {
  		int outtotal = tasksize;
f5e3c2faa   Deepak Saxena   [PATCH] ide: kmal...
474
  		outbuf = kzalloc(taskout, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
476
477
478
  		if (outbuf == NULL) {
  			err = -ENOMEM;
  			goto abort;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
479
480
481
482
483
484
485
486
  		if (copy_from_user(outbuf, buf + outtotal, taskout)) {
  			err = -EFAULT;
  			goto abort;
  		}
  	}
  
  	if (taskin) {
  		int intotal = tasksize + taskout;
f5e3c2faa   Deepak Saxena   [PATCH] ide: kmal...
487
  		inbuf = kzalloc(taskin, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
488
489
490
491
  		if (inbuf == NULL) {
  			err = -ENOMEM;
  			goto abort;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
493
494
495
496
  		if (copy_from_user(inbuf, buf + intotal, taskin)) {
  			err = -EFAULT;
  			goto abort;
  		}
  	}
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
497
  	memset(&cmd, 0, sizeof(cmd));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498

745483f10   Sergei Shtylyov   ide: simplify 'st...
499
500
  	memcpy(&cmd.hob, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
  	memcpy(&cmd.tf,  req_task->io_ports,  HDIO_DRIVE_TASK_HDR_SIZE);
866e2ec9c   Bartlomiej Zolnierkiewicz   ide: remove 'tf_i...
501

60f85019c   Sergei Shtylyov   ide: replace IDE_...
502
503
504
  	cmd.valid.out.tf = IDE_VALID_DEVICE;
  	cmd.valid.in.tf  = IDE_VALID_DEVICE | IDE_VALID_IN_TF;
  	cmd.tf_flags = IDE_TFLAG_IO_16BIT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
505

60f85019c   Sergei Shtylyov   ide: replace IDE_...
506
507
508
509
  	if (drive->dev_flags & IDE_DFLAG_LBA48) {
  		cmd.tf_flags |= IDE_TFLAG_LBA48;
  		cmd.valid.in.hob = IDE_VALID_IN_HOB;
  	}
a3bbb9d88   Bartlomiej Zolnierkiewicz   ide: remove unnec...
510

74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
511
  	if (req_task->out_flags.all) {
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
512
  		cmd.ftf_flags |= IDE_FTFLAG_FLAGGED;
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
513
514
  
  		if (req_task->out_flags.b.data)
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
515
  			cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA;
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
516
517
  
  		if (req_task->out_flags.b.nsector_hob)
60f85019c   Sergei Shtylyov   ide: replace IDE_...
518
  			cmd.valid.out.hob |= IDE_VALID_NSECT;
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
519
  		if (req_task->out_flags.b.sector_hob)
60f85019c   Sergei Shtylyov   ide: replace IDE_...
520
  			cmd.valid.out.hob |= IDE_VALID_LBAL;
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
521
  		if (req_task->out_flags.b.lcyl_hob)
60f85019c   Sergei Shtylyov   ide: replace IDE_...
522
  			cmd.valid.out.hob |= IDE_VALID_LBAM;
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
523
  		if (req_task->out_flags.b.hcyl_hob)
60f85019c   Sergei Shtylyov   ide: replace IDE_...
524
  			cmd.valid.out.hob |= IDE_VALID_LBAH;
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
525
526
  
  		if (req_task->out_flags.b.error_feature)
60f85019c   Sergei Shtylyov   ide: replace IDE_...
527
  			cmd.valid.out.tf  |= IDE_VALID_FEATURE;
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
528
  		if (req_task->out_flags.b.nsector)
60f85019c   Sergei Shtylyov   ide: replace IDE_...
529
  			cmd.valid.out.tf  |= IDE_VALID_NSECT;
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
530
  		if (req_task->out_flags.b.sector)
60f85019c   Sergei Shtylyov   ide: replace IDE_...
531
  			cmd.valid.out.tf  |= IDE_VALID_LBAL;
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
532
  		if (req_task->out_flags.b.lcyl)
60f85019c   Sergei Shtylyov   ide: replace IDE_...
533
  			cmd.valid.out.tf  |= IDE_VALID_LBAM;
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
534
  		if (req_task->out_flags.b.hcyl)
60f85019c   Sergei Shtylyov   ide: replace IDE_...
535
  			cmd.valid.out.tf  |= IDE_VALID_LBAH;
a3bbb9d88   Bartlomiej Zolnierkiewicz   ide: remove unnec...
536
  	} else {
60f85019c   Sergei Shtylyov   ide: replace IDE_...
537
  		cmd.valid.out.tf |= IDE_VALID_OUT_TF;
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
538
  		if (cmd.tf_flags & IDE_TFLAG_LBA48)
60f85019c   Sergei Shtylyov   ide: replace IDE_...
539
  			cmd.valid.out.hob |= IDE_VALID_OUT_HOB;
74095a91e   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
540
  	}
866e2ec9c   Bartlomiej Zolnierkiewicz   ide: remove 'tf_i...
541
  	if (req_task->in_flags.b.data)
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
542
  		cmd.ftf_flags |= IDE_FTFLAG_IN_DATA;
866e2ec9c   Bartlomiej Zolnierkiewicz   ide: remove 'tf_i...
543

04d09b0e6   Bartlomiej Zolnierkiewicz   ide: set IDE_TFLA...
544
545
546
547
  	if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE) {
  		/* fixup data phase if needed */
  		if (req_task->data_phase == TASKFILE_IN_DMAQ ||
  		    req_task->data_phase == TASKFILE_IN_DMA)
0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
548
  			cmd.tf_flags |= IDE_TFLAG_WRITE;
04d09b0e6   Bartlomiej Zolnierkiewicz   ide: set IDE_TFLA...
549
  	}
0dfb991c6   Bartlomiej Zolnierkiewicz   ide: use ata_tf_p...
550
551
552
  	cmd.protocol = ATA_PROT_DMA;
  
  	switch (req_task->data_phase) {
2d5abcede   Jaswinder Singh Rajput   ide: ide-taskfile...
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
  	case TASKFILE_MULTI_OUT:
  		if (!drive->mult_count) {
  			/* (hs): give up if multcount is not set */
  			pr_err("%s: %s Multimode Write multcount is not set
  ",
  				drive->name, __func__);
  			err = -EPERM;
  			goto abort;
  		}
  		cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
  		/* fall through */
  	case TASKFILE_OUT:
  		cmd.protocol = ATA_PROT_PIO;
  		/* fall through */
  	case TASKFILE_OUT_DMAQ:
  	case TASKFILE_OUT_DMA:
  		cmd.tf_flags |= IDE_TFLAG_WRITE;
  		nsect = taskout / SECTOR_SIZE;
  		data_buf = outbuf;
  		break;
  	case TASKFILE_MULTI_IN:
  		if (!drive->mult_count) {
  			/* (hs): give up if multcount is not set */
  			pr_err("%s: %s Multimode Read multcount is not set
  ",
  				drive->name, __func__);
  			err = -EPERM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
580
  			goto abort;
2d5abcede   Jaswinder Singh Rajput   ide: ide-taskfile...
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
  		}
  		cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
  		/* fall through */
  	case TASKFILE_IN:
  		cmd.protocol = ATA_PROT_PIO;
  		/* fall through */
  	case TASKFILE_IN_DMAQ:
  	case TASKFILE_IN_DMA:
  		nsect = taskin / SECTOR_SIZE;
  		data_buf = inbuf;
  		break;
  	case TASKFILE_NO_DATA:
  		cmd.protocol = ATA_PROT_NODATA;
  		break;
  	default:
  		err = -EFAULT;
  		goto abort;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
  	}
ac026ff25   Bartlomiej Zolnierkiewicz   ide: remove 'comm...
599
600
601
  	if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
  		nsect = 0;
  	else if (!nsect) {
745483f10   Sergei Shtylyov   ide: simplify 'st...
602
  		nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect;
ac026ff25   Bartlomiej Zolnierkiewicz   ide: remove 'comm...
603
604
  
  		if (!nsect) {
2d5abcede   Jaswinder Singh Rajput   ide: ide-taskfile...
605
606
  			pr_err("%s: in/out command without data
  ",
ac026ff25   Bartlomiej Zolnierkiewicz   ide: remove 'comm...
607
608
609
610
611
  					drive->name);
  			err = -EFAULT;
  			goto abort;
  		}
  	}
22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
612
  	err = ide_raw_taskfile(drive, &cmd, data_buf, nsect);
ac026ff25   Bartlomiej Zolnierkiewicz   ide: remove 'comm...
613

745483f10   Sergei Shtylyov   ide: simplify 'st...
614
615
  	memcpy(req_task->hob_ports, &cmd.hob, HDIO_DRIVE_HOB_HDR_SIZE - 2);
  	memcpy(req_task->io_ports,  &cmd.tf,  HDIO_DRIVE_TASK_HDR_SIZE);
866e2ec9c   Bartlomiej Zolnierkiewicz   ide: remove 'tf_i...
616

22aa4b32a   Bartlomiej Zolnierkiewicz   ide: remove ide_t...
617
  	if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) &&
866e2ec9c   Bartlomiej Zolnierkiewicz   ide: remove 'tf_i...
618
619
  	    req_task->in_flags.all == 0) {
  		req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
620
  		if (drive->dev_flags & IDE_DFLAG_LBA48)
866e2ec9c   Bartlomiej Zolnierkiewicz   ide: remove 'tf_i...
621
622
  			req_task->in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
  
  	if (copy_to_user(buf, req_task, tasksize)) {
  		err = -EFAULT;
  		goto abort;
  	}
  	if (taskout) {
  		int outtotal = tasksize;
  		if (copy_to_user(buf + outtotal, outbuf, taskout)) {
  			err = -EFAULT;
  			goto abort;
  		}
  	}
  	if (taskin) {
  		int intotal = tasksize + taskout;
  		if (copy_to_user(buf + intotal, inbuf, taskin)) {
  			err = -EFAULT;
  			goto abort;
  		}
  	}
  abort:
  	kfree(req_task);
6044ec888   Jesper Juhl   [PATCH] kfree cle...
644
645
  	kfree(outbuf);
  	kfree(inbuf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
647
648
  	return err;
  }
26a5b0407   Bartlomiej Zolnierkiewicz   ide: add missing ...
649
  #endif