Blame view

drivers/ide/ide-cd.c 56.1 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
3bb4663bd   Bartlomiej Zolnierkiewicz   ide-cd: update dr...
2
   * ATAPI CD-ROM driver.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
   *
59bca8cc9   Bartlomiej Zolnierkiewicz   ide: update/add m...
4
5
6
7
   * Copyright (C) 1994-1996   Scott Snyder <snyder@fnald0.fnal.gov>
   * Copyright (C) 1996-1998   Erik Andersen <andersee@debian.org>
   * Copyright (C) 1998-2000   Jens Axboe <axboe@suse.de>
   * Copyright (C) 2005, 2007  Bartlomiej Zolnierkiewicz
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
   *
   * May be copied or modified under the terms of the GNU General Public
   * License.  See linux/COPYING for more information.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
   * See Documentation/cdrom/ide-cd for usage information.
   *
   * Suggestions are welcome. Patches that work are more welcome though. ;-)
   * For those wishing to work on this driver, please be sure you download
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
16
17
   * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
   * (SFF-8020i rev 2.6) standards. These documents can be obtained by
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
21
   * anonymous ftp from:
   * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
   * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
   *
03553353e   Bartlomiej Zolnierkiewicz   ide-cd: move hist...
22
23
24
   * For historical changelog please see:
   *	Documentation/ide/ChangeLog.ide-cd.1994-2004
   */
3bb4663bd   Bartlomiej Zolnierkiewicz   ide-cd: update dr...
25
  #define IDECD_VERSION "5.00"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
31
32
33
34
35
36
37
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/delay.h>
  #include <linux/timer.h>
  #include <linux/slab.h>
  #include <linux/interrupt.h>
  #include <linux/errno.h>
  #include <linux/cdrom.h>
  #include <linux/ide.h>
  #include <linux/completion.h>
cf8b8975c   Arjan van de Ven   [PATCH] sem2mutex...
38
  #include <linux/mutex.h>
9a6dc668d   Bartlomiej Zolnierkiewicz   ide-cd: use BCD2B...
39
  #include <linux/bcd.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
41
42
  /* For SCSI -> ATAPI command conversion */
  #include <scsi/scsi.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43

9aba468e4   Borislav Petkov   ide-cd: include p...
44
45
  #include <linux/irq.h>
  #include <linux/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  #include <asm/byteorder.h>
9aba468e4   Borislav Petkov   ide-cd: include p...
47
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
49
50
  #include <asm/unaligned.h>
  
  #include "ide-cd.h"
cf8b8975c   Arjan van de Ven   [PATCH] sem2mutex...
51
  static DEFINE_MUTEX(idecd_ref_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52

9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
53
  #define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
  
  #define ide_cd_g(disk) \
  	container_of((disk)->private_data, struct cdrom_info, driver)
08da591e1   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
57
  static void ide_cd_release(struct kref *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
60
  static struct cdrom_info *ide_cd_get(struct gendisk *disk)
  {
  	struct cdrom_info *cd = NULL;
cf8b8975c   Arjan van de Ven   [PATCH] sem2mutex...
61
  	mutex_lock(&idecd_ref_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
  	cd = ide_cd_g(disk);
08da591e1   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
63
  	if (cd) {
d3e33ff59   Bartlomiej Zolnierkiewicz   ide: fix regressi...
64
  		if (ide_device_get(cd->drive))
08da591e1   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
65
  			cd = NULL;
d3e33ff59   Bartlomiej Zolnierkiewicz   ide: fix regressi...
66
67
  		else
  			kref_get(&cd->kref);
08da591e1   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
68
  	}
cf8b8975c   Arjan van de Ven   [PATCH] sem2mutex...
69
  	mutex_unlock(&idecd_ref_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
  	return cd;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
73
  static void ide_cd_put(struct cdrom_info *cd)
  {
d3e33ff59   Bartlomiej Zolnierkiewicz   ide: fix regressi...
74
  	ide_drive_t *drive = cd->drive;
cf8b8975c   Arjan van de Ven   [PATCH] sem2mutex...
75
  	mutex_lock(&idecd_ref_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
  	kref_put(&cd->kref, ide_cd_release);
d3e33ff59   Bartlomiej Zolnierkiewicz   ide: fix regressi...
77
  	ide_device_put(drive);
cf8b8975c   Arjan van de Ven   [PATCH] sem2mutex...
78
  	mutex_unlock(&idecd_ref_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
80
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
82
   * Generic packet command support and error handling routines.
   */
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
83
  /* Mark that we've seen a media change and invalidate our internal buffers. */
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
84
  static void cdrom_saw_media_change(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
  {
570f89ea5   Borislav Petkov   ide-cd: convert t...
86
87
  	drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
  	drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
91
92
93
  }
  
  static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
  			   struct request_sense *sense)
  {
  	int log = 0;
4aff5e233   Jens Axboe   [PATCH] Split str...
94
  	if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
96
97
  		return 0;
  
  	switch (sense->sense_key) {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
98
99
100
101
102
  	case NO_SENSE:
  	case RECOVERED_ERROR:
  		break;
  	case NOT_READY:
  		/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
103
104
  		 * don't care about tray state messages for e.g. capacity
  		 * commands or in-progress or becoming ready
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
105
106
  		 */
  		if (sense->asc == 0x3a || sense->asc == 0x04)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
  			break;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
108
109
110
111
  		log = 1;
  		break;
  	case ILLEGAL_REQUEST:
  		/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
112
113
  		 * don't log START_STOP unit with LoEj set, since we cannot
  		 * reliably check if drive can auto-close
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
114
115
  		 */
  		if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  			break;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
117
118
119
120
  		log = 1;
  		break;
  	case UNIT_ATTENTION:
  		/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
121
122
123
  		 * Make good and sure we've seen this potential media change.
  		 * Some drives (i.e. Creative) fail to present the correct sense
  		 * key in the error register.
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
124
125
126
127
128
129
  		 */
  		cdrom_saw_media_change(drive);
  		break;
  	default:
  		log = 1;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
131
132
  	}
  	return log;
  }
e5e076a35   Borislav Petkov   ide-cd: fix remai...
133
  static void cdrom_analyze_sense_data(ide_drive_t *drive,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
  			      struct request *failed_command,
  			      struct request_sense *sense)
  {
dbe217af3   Alan Cox   [PATCH] IDE CD en...
137
138
  	unsigned long sector;
  	unsigned long bio_sectors;
dbe217af3   Alan Cox   [PATCH] IDE CD en...
139
  	struct cdrom_info *info = drive->driver_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
142
143
  	if (!cdrom_log_sense(drive, failed_command, sense))
  		return;
  
  	/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
144
145
146
  	 * If a read toc is executed for a CD-R or CD-RW medium where the first
  	 * toc has not been recorded yet, it will fail with 05/24/00 (which is a
  	 * confusing error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
148
149
150
  	 */
  	if (failed_command && failed_command->cmd[0] == GPCMD_READ_TOC_PMA_ATIP)
  		if (sense->sense_key == 0x05 && sense->asc == 0x24)
  			return;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
151
152
  	/* current error */
  	if (sense->error_code == 0x70) {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
153
  		switch (sense->sense_key) {
dbe217af3   Alan Cox   [PATCH] IDE CD en...
154
155
156
157
158
159
160
161
162
163
164
165
  		case MEDIUM_ERROR:
  		case VOLUME_OVERFLOW:
  		case ILLEGAL_REQUEST:
  			if (!sense->valid)
  				break;
  			if (failed_command == NULL ||
  					!blk_fs_request(failed_command))
  				break;
  			sector = (sense->information[0] << 24) |
  				 (sense->information[1] << 16) |
  				 (sense->information[2] <<  8) |
  				 (sense->information[3]);
dbe217af3   Alan Cox   [PATCH] IDE CD en...
166
  			if (drive->queue->hardsect_size == 2048)
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
167
168
  				/* device sector size is 2K */
  				sector <<= 2;
eee49298d   Roel Kluin   ide-cd: clean up ...
169
170
  
  			bio_sectors = max(bio_sectors(failed_command->bio), 4U);
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
171
  			sector &= ~(bio_sectors - 1);
dbe217af3   Alan Cox   [PATCH] IDE CD en...
172

dbe217af3   Alan Cox   [PATCH] IDE CD en...
173
  			if (sector < get_capacity(info->disk) &&
e5e076a35   Borislav Petkov   ide-cd: fix remai...
174
  			    drive->probed_capacity - sector < 4 * 75)
dbe217af3   Alan Cox   [PATCH] IDE CD en...
175
  				set_capacity(info->disk, sector);
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
176
177
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178

972560fb9   Bartlomiej Zolnierkiewicz   ide-cd: move VERB...
179
  	ide_cd_log_error(drive->name, failed_command, sense);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
182
183
184
185
186
187
188
189
190
  static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
  				      struct request *failed_command)
  {
  	struct cdrom_info *info		= drive->driver_data;
  	struct request *rq		= &info->request_sense_request;
  
  	if (sense == NULL)
  		sense = &info->sense_data;
  
  	/* stuff the sense request in front of our current request */
ed820f195   FUJITA Tomonori   ide-cd: remove id...
191
192
193
  	blk_rq_init(NULL, rq);
  	rq->cmd_type = REQ_TYPE_ATA_PC;
  	rq->rq_disk = info->disk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
195
196
  
  	rq->data = sense;
  	rq->cmd[0] = GPCMD_REQUEST_SENSE;
e5e076a35   Borislav Petkov   ide-cd: fix remai...
197
198
  	rq->cmd[4] = 18;
  	rq->data_len = 18;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199

4aff5e233   Jens Axboe   [PATCH] Split str...
200
  	rq->cmd_type = REQ_TYPE_SENSE;
e8a96aa71   Bartlomiej Zolnierkiewicz   ide: set REQ_PREE...
201
  	rq->cmd_flags |= REQ_PREEMPT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
203
204
  
  	/* NOTE! Save the failed command in "rq->buffer" */
  	rq->buffer = (void *) failed_command;
63f5abb09   FUJITA Tomonori   ide: remove actio...
205
  	ide_do_drive_cmd(drive, rq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
  }
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
207
  static void cdrom_end_request(ide_drive_t *drive, int uptodate)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
209
210
  {
  	struct request *rq = HWGROUP(drive)->rq;
  	int nsectors = rq->hard_cur_sectors;
4aff5e233   Jens Axboe   [PATCH] Split str...
211
  	if (blk_sense_request(rq) && uptodate) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
  		/*
4aff5e233   Jens Axboe   [PATCH] Split str...
213
214
  		 * For REQ_TYPE_SENSE, "rq->buffer" points to the original
  		 * failed request
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
216
217
218
219
220
221
222
223
224
225
  		 */
  		struct request *failed = (struct request *) rq->buffer;
  		struct cdrom_info *info = drive->driver_data;
  		void *sense = &info->sense_data;
  		unsigned long flags;
  
  		if (failed) {
  			if (failed->sense) {
  				sense = failed->sense;
  				failed->sense_len = rq->sense_len;
  			}
dbe217af3   Alan Cox   [PATCH] IDE CD en...
226
  			cdrom_analyze_sense_data(drive, failed, sense);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227
  			/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
228
  			 * now end the failed request
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
  			 */
dbe217af3   Alan Cox   [PATCH] IDE CD en...
230
231
232
233
234
235
  			if (blk_fs_request(failed)) {
  				if (ide_end_dequeued_request(drive, failed, 0,
  						failed->hard_nr_sectors))
  					BUG();
  			} else {
  				spin_lock_irqsave(&ide_lock, flags);
5e36bb6ee   Kiyoshi Ueda   blk_end_request: ...
236
237
238
  				if (__blk_end_request(failed, -EIO,
  						      failed->data_len))
  					BUG();
dbe217af3   Alan Cox   [PATCH] IDE CD en...
239
240
241
242
  				spin_unlock_irqrestore(&ide_lock, flags);
  			}
  		} else
  			cdrom_analyze_sense_data(drive, NULL, sense);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
244
245
246
247
248
249
250
251
252
253
254
  	}
  
  	if (!rq->current_nr_sectors && blk_fs_request(rq))
  		uptodate = 1;
  	/* make sure it's fully ended */
  	if (blk_pc_request(rq))
  		nsectors = (rq->data_len + 511) >> 9;
  	if (!nsectors)
  		nsectors = 1;
  
  	ide_end_request(drive, uptodate, nsectors);
  }
83c8565dc   Borislav Petkov   ide-cd: shorten l...
255
  static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st)
dbe217af3   Alan Cox   [PATCH] IDE CD en...
256
  {
83c8565dc   Borislav Petkov   ide-cd: shorten l...
257
  	if (st & 0x80)
dbe217af3   Alan Cox   [PATCH] IDE CD en...
258
  		return;
83c8565dc   Borislav Petkov   ide-cd: shorten l...
259
  	ide_dump_status(drive, msg, st);
dbe217af3   Alan Cox   [PATCH] IDE CD en...
260
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
261
262
263
264
265
  /*
   * Returns:
   * 0: if the request should be continued.
   * 1: if the request was ended.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
267
  static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
  {
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
268
269
  	ide_hwif_t *hwif = drive->hwif;
  	struct request *rq = hwif->hwgroup->rq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
  	int stat, err, sense_key;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
271

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
272
  	/* check for errors */
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
273
  	stat = hwif->tp_ops->read_status(hwif);
c47137a99   Bartlomiej Zolnierkiewicz   ide: add ide_read...
274

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
278
279
  	if (stat_ret)
  		*stat_ret = stat;
  
  	if (OK_STAT(stat, good_stat, BAD_R_STAT))
  		return 0;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
280
  	/* get the IDE error register */
64a57fe43   Bartlomiej Zolnierkiewicz   ide: add ide_read...
281
  	err = ide_read_error(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
284
  	sense_key = err >> 4;
  
  	if (rq == NULL) {
e5e076a35   Borislav Petkov   ide-cd: fix remai...
285
286
287
  		printk(KERN_ERR "%s: missing rq in %s
  ",
  				drive->name, __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
289
  		return 1;
  	}
4aff5e233   Jens Axboe   [PATCH] Split str...
290
  	if (blk_sense_request(rq)) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
291
292
293
294
295
  		/*
  		 * We got an error trying to get sense info from the drive
  		 * (probably while trying to recover from a former error).
  		 * Just give up.
  		 */
4aff5e233   Jens Axboe   [PATCH] Split str...
296
  		rq->cmd_flags |= REQ_FAILED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
298
299
  		cdrom_end_request(drive, 0);
  		ide_error(drive, "request sense failure", stat);
  		return 1;
8770c018d   Jens Axboe   [PATCH] ide-cd: o...
300
  	} else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
  		/* All other functions, except for READ. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
303
304
305
306
  
  		/*
  		 * if we have an error, pass back CHECK_CONDITION as the
  		 * scsi status byte
  		 */
b71567312   Jens Axboe   [PATCH] ide-cd: o...
307
  		if (blk_pc_request(rq) && !rq->errors)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
  			rq->errors = SAM_STAT_CHECK_CONDITION;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
309
  		/* check for tray open */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  		if (sense_key == NOT_READY) {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
311
  			cdrom_saw_media_change(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
  		} else if (sense_key == UNIT_ATTENTION) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
313
  			/* check for media change */
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
314
  			cdrom_saw_media_change(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
  			return 0;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
316
317
318
319
320
321
322
323
324
  		} else if (sense_key == ILLEGAL_REQUEST &&
  			   rq->cmd[0] == GPCMD_START_STOP_UNIT) {
  			/*
  			 * Don't print error message for this condition--
  			 * SFF8090i indicates that 5/24/00 is the correct
  			 * response to a request to close the tray if the
  			 * drive doesn't have that capability.
  			 * cdrom_log_sense() knows this!
  			 */
4aff5e233   Jens Axboe   [PATCH] Split str...
325
  		} else if (!(rq->cmd_flags & REQ_QUIET)) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
326
  			/* otherwise, print an error */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
328
  			ide_dump_status(drive, "packet command error", stat);
  		}
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
329

4aff5e233   Jens Axboe   [PATCH] Split str...
330
  		rq->cmd_flags |= REQ_FAILED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
333
334
335
336
  
  		/*
  		 * instead of playing games with moving completions around,
  		 * remove failed request completely and end it when the
  		 * request sense has completed
  		 */
bbb89e3d7   Bartlomiej Zolnierkiewicz   ide-cd: unify req...
337
  		goto end_request;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
339
340
  
  	} else if (blk_fs_request(rq)) {
  		int do_end_request = 0;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
341
  		/* handle errors from READ and WRITE requests */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
343
344
345
346
  
  		if (blk_noretry_request(rq))
  			do_end_request = 1;
  
  		if (sense_key == NOT_READY) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
347
  			/* tray open */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
  			if (rq_data_dir(rq) == READ) {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
349
  				cdrom_saw_media_change(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
351
  				/* fail the request */
e5e076a35   Borislav Petkov   ide-cd: fix remai...
352
353
  				printk(KERN_ERR "%s: tray open
  ", drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
355
356
  				do_end_request = 1;
  			} else {
  				struct cdrom_info *info = drive->driver_data;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
357
358
  				/*
  				 * Allow the drive 5 seconds to recover, some
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359
  				 * devices will return this error while flushing
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
360
361
  				 * data from cache.
  				 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
  				if (!rq->errors)
83c8565dc   Borislav Petkov   ide-cd: shorten l...
363
364
  					info->write_timeout = jiffies +
  							ATAPI_WAIT_WRITE_BUSY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365
366
367
368
369
370
371
  				rq->errors = 1;
  				if (time_after(jiffies, info->write_timeout))
  					do_end_request = 1;
  				else {
  					unsigned long flags;
  
  					/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
372
373
  					 * take a breather relying on the unplug
  					 * timer to kick us again
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
375
376
  					 */
  					spin_lock_irqsave(&ide_lock, flags);
  					blk_plug_device(drive->queue);
83c8565dc   Borislav Petkov   ide-cd: shorten l...
377
378
  					spin_unlock_irqrestore(&ide_lock,
  								flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
380
381
382
  					return 1;
  				}
  			}
  		} else if (sense_key == UNIT_ATTENTION) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
383
  			/* media change */
e5e076a35   Borislav Petkov   ide-cd: fix remai...
384
  			cdrom_saw_media_change(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385

9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
386
  			/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
387
388
  			 * Arrange to retry the request but be sure to give up
  			 * if we've retried too many times.
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
389
  			 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
391
392
393
  			if (++rq->errors > ERROR_MAX)
  				do_end_request = 1;
  		} else if (sense_key == ILLEGAL_REQUEST ||
  			   sense_key == DATA_PROTECT) {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
394
  			/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
395
396
  			 * No point in retrying after an illegal request or data
  			 * protect error.
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
397
398
  			 */
  			ide_dump_status_no_sense(drive, "command error", stat);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
400
  			do_end_request = 1;
  		} else if (sense_key == MEDIUM_ERROR) {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
401
402
  			/*
  			 * No point in re-trying a zillion times on a bad
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
403
  			 * sector. If we got here the error is not correctable.
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
404
  			 */
83c8565dc   Borislav Petkov   ide-cd: shorten l...
405
406
407
  			ide_dump_status_no_sense(drive,
  						 "media error (bad sector)",
  						 stat);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
409
  			do_end_request = 1;
  		} else if (sense_key == BLANK_CHECK) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
410
  			/* disk appears blank ?? */
83c8565dc   Borislav Petkov   ide-cd: shorten l...
411
412
  			ide_dump_status_no_sense(drive, "media error (blank)",
  						 stat);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
413
  			do_end_request = 1;
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
414
  		} else if ((err & ~ATA_ABORTED) != 0) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
415
  			/* go to the default handler for other errors */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
418
  			ide_error(drive, "cdrom_decode_status", stat);
  			return 1;
  		} else if ((++rq->errors > ERROR_MAX)) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
419
  			/* we've racked up too many retries, abort */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
421
  			do_end_request = 1;
  		}
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
422
423
424
425
426
  		/*
  		 * End a request through request sense analysis when we have
  		 * sense data. We need this in order to perform end of media
  		 * processing.
  		 */
bbb89e3d7   Bartlomiej Zolnierkiewicz   ide-cd: unify req...
427
428
  		if (do_end_request)
  			goto end_request;
dbe217af3   Alan Cox   [PATCH] IDE CD en...
429

bbb89e3d7   Bartlomiej Zolnierkiewicz   ide-cd: unify req...
430
  		/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
431
432
  		 * If we got a CHECK_CONDITION status, queue
  		 * a request sense command.
bbb89e3d7   Bartlomiej Zolnierkiewicz   ide-cd: unify req...
433
  		 */
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
434
  		if (stat & ATA_ERR)
bbb89e3d7   Bartlomiej Zolnierkiewicz   ide-cd: unify req...
435
  			cdrom_queue_request_sense(drive, NULL, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
437
438
439
  	} else {
  		blk_dump_rq_flags(rq, "ide-cd: bad rq");
  		cdrom_end_request(drive, 0);
  	}
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
440
  	/* retry, or handle the next request */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
  	return 1;
bbb89e3d7   Bartlomiej Zolnierkiewicz   ide-cd: unify req...
442
443
  
  end_request:
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
444
  	if (stat & ATA_ERR) {
bbb89e3d7   Bartlomiej Zolnierkiewicz   ide-cd: unify req...
445
446
447
448
449
450
451
452
453
454
455
456
  		unsigned long flags;
  
  		spin_lock_irqsave(&ide_lock, flags);
  		blkdev_dequeue_request(rq);
  		HWGROUP(drive)->rq = NULL;
  		spin_unlock_irqrestore(&ide_lock, flags);
  
  		cdrom_queue_request_sense(drive, rq->sense, rq);
  	} else
  		cdrom_end_request(drive, 0);
  
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
458
459
460
461
462
463
464
  }
  
  static int cdrom_timer_expiry(ide_drive_t *drive)
  {
  	struct request *rq = HWGROUP(drive)->rq;
  	unsigned long wait = 0;
  
  	/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
465
466
467
468
  	 * Some commands are *slow* and normally take a long time to complete.
  	 * Usually we can use the ATAPI "disconnect" to bypass this, but not all
  	 * commands/drives support that. Let ide_timer_expiry keep polling us
  	 * for these.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469
470
  	 */
  	switch (rq->cmd[0]) {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
471
472
473
474
475
476
477
478
479
  	case GPCMD_BLANK:
  	case GPCMD_FORMAT_UNIT:
  	case GPCMD_RESERVE_RZONE_TRACK:
  	case GPCMD_CLOSE_TRACK:
  	case GPCMD_FLUSH_CACHE:
  		wait = ATAPI_WAIT_PC;
  		break;
  	default:
  		if (!(rq->cmd_flags & REQ_QUIET))
83c8565dc   Borislav Petkov   ide-cd: shorten l...
480
481
482
  			printk(KERN_INFO "ide-cd: cmd 0x%x timed out
  ",
  					 rq->cmd[0]);
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
483
484
  		wait = 0;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
486
487
  	}
  	return wait;
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
488
489
490
491
492
493
494
495
  /*
   * Set up the device registers for transferring a packet command on DEV,
   * expecting to later transfer XFERLEN bytes.  HANDLER is the routine
   * which actually transfers the command to the drive.  If this is a
   * drq_interrupt device, this routine will arrange for HANDLER to be
   * called when the interrupt from the drive arrives.  Otherwise, HANDLER
   * will be called immediately after the drive is prepared for the transfer.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
496
497
498
499
  static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
  						  int xferlen,
  						  ide_handler_t *handler)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
500
501
  	struct cdrom_info *info = drive->driver_data;
  	ide_hwif_t *hwif = drive->hwif;
3a6a3549a   Bartlomiej Zolnierkiewicz   ide-cd: fix regis...
502
  	/* FIXME: for Virtual DMA we must check harder */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
  	if (info->dma)
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
504
  		info->dma = !hwif->dma_ops->dma_setup(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
505

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
506
  	/* set up the controller registers */
9a410e79b   Bartlomiej Zolnierkiewicz   ide: remove IDE_T...
507
508
  	ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL,
  			   xferlen, info->dma);
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
509

570f89ea5   Borislav Petkov   ide-cd: convert t...
510
  	if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
f0dd8712e   Albert Lee   ide: clear bmdma ...
511
512
513
  		/* waiting for CDB interrupt, not DMA yet. */
  		if (info->dma)
  			drive->waiting_for_dma = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514
  		/* packet command */
aaaade3f0   Bartlomiej Zolnierkiewicz   ide: WIN_* -> ATA...
515
  		ide_execute_command(drive, ATA_CMD_PACKET, handler,
83c8565dc   Borislav Petkov   ide-cd: shorten l...
516
  				    ATAPI_WAIT_PC, cdrom_timer_expiry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
517
518
  		return ide_started;
  	} else {
1fc142589   Bartlomiej Zolnierkiewicz   ide: add ide_exec...
519
  		ide_execute_pkt_cmd(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
521
522
523
  
  		return (*handler) (drive);
  	}
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
524
525
526
527
528
529
  /*
   * Send a packet command to DRIVE described by CMD_BUF and CMD_LEN. The device
   * registers must have already been prepared by cdrom_start_packet_command.
   * HANDLER is the interrupt handler to call when the command completes or
   * there's data ready.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
530
  #define ATAPI_MIN_CDB_BYTES 12
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
531
  static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
533
534
535
536
537
538
  					  struct request *rq,
  					  ide_handler_t *handler)
  {
  	ide_hwif_t *hwif = drive->hwif;
  	int cmd_len;
  	struct cdrom_info *info = drive->driver_data;
  	ide_startstop_t startstop;
570f89ea5   Borislav Petkov   ide-cd: convert t...
539
  	if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
540
541
542
543
  		/*
  		 * Here we should have been called after receiving an interrupt
  		 * from the device.  DRQ should how be set.
  		 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
544

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
545
  		/* check for errors */
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
546
  		if (cdrom_decode_status(drive, ATA_DRQ, NULL))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
  			return ide_stopped;
f0dd8712e   Albert Lee   ide: clear bmdma ...
548

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
549
  		/* ok, next interrupt will be DMA interrupt */
f0dd8712e   Albert Lee   ide: clear bmdma ...
550
551
  		if (info->dma)
  			drive->waiting_for_dma = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
  	} else {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
553
  		/* otherwise, we must wait for DRQ to get set */
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
554
555
  		if (ide_wait_stat(&startstop, drive, ATA_DRQ,
  				  ATA_BUSY, WAIT_READY))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
556
557
  			return startstop;
  	}
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
558
  	/* arm the interrupt handler */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
560
561
562
563
564
  	ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);
  
  	/* ATAPI commands get padded out to 12 bytes minimum */
  	cmd_len = COMMAND_SIZE(rq->cmd[0]);
  	if (cmd_len < ATAPI_MIN_CDB_BYTES)
  		cmd_len = ATAPI_MIN_CDB_BYTES;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
565
  	/* send the command to the device */
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
566
  	hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
567

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
568
  	/* start the DMA if need be */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
569
  	if (info->dma)
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
570
  		hwif->dma_ops->dma_start(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
571
572
573
  
  	return ide_started;
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
574
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
576
577
578
   * Check the contents of the interrupt reason register from the cdrom
   * and attempt to recover if there are problems.  Returns  0 if everything's
   * ok; nonzero if the request has been terminated.
   */
9f10d9ee0   Bartlomiej Zolnierkiewicz   ide-cd: fix 'irea...
579
580
  static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
  				int len, int ireason, int rw)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
  {
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
582
  	ide_hwif_t *hwif = drive->hwif;
0d6f7e3a1   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
583
584
585
586
587
  	/*
  	 * ireason == 0: the drive wants to receive data from us
  	 * ireason == 2: the drive is expecting to transfer data to us
  	 */
  	if (ireason == (!rw << 1))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
588
  		return 0;
0d6f7e3a1   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
589
  	else if (ireason == (rw << 1)) {
5a5222d9f   Bartlomiej Zolnierkiewicz   ide-cd: add ide_c...
590

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
591
  		/* whoops... */
35379c071   Bartlomiej Zolnierkiewicz   ide-cd: fix error...
592
593
  		printk(KERN_ERR "%s: %s: wrong transfer direction!
  ",
177773ed8   Paolo Ciarrocchi   ide-cd: Replace _...
594
  				drive->name, __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595

ae8789f03   Borislav Petkov   ide-cd: remove id...
596
  		ide_pad_transfer(drive, rw, len);
0d6f7e3a1   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
597
  	} else  if (rw == 0 && ireason == 1) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
598
599
600
  		/*
  		 * Some drives (ASUS) seem to tell us that status info is
  		 * available.  Just get it and ignore.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
601
  		 */
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
602
  		(void)hwif->tp_ops->read_status(hwif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
603
604
  		return 0;
  	} else {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
605
  		/* drive wants a command packet, or invalid ireason... */
35379c071   Bartlomiej Zolnierkiewicz   ide-cd: fix error...
606
607
  		printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x
  ",
177773ed8   Paolo Ciarrocchi   ide-cd: Replace _...
608
  				drive->name, __func__, ireason);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
  	}
9f10d9ee0   Bartlomiej Zolnierkiewicz   ide-cd: fix 'irea...
610
611
  	if (rq->cmd_type == REQ_TYPE_ATA_PC)
  		rq->cmd_flags |= REQ_FAILED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
612
613
614
615
616
  	cdrom_end_request(drive, 0);
  	return -1;
  }
  
  /*
64814f239   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
617
618
619
620
621
   * Assume that the drive will always provide data in multiples of at least
   * SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise.
   */
  static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
  {
64814f239   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
622
623
624
625
626
  	if ((len % SECTOR_SIZE) == 0)
  		return 0;
  
  	printk(KERN_ERR "%s: %s: Bad transfer size %d
  ",
177773ed8   Paolo Ciarrocchi   ide-cd: Replace _...
627
  			drive->name, __func__, len);
64814f239   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
628

570f89ea5   Borislav Petkov   ide-cd: convert t...
629
  	if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES)
64814f239   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
630
631
632
633
634
635
  		printk(KERN_ERR "  This drive is not supported by "
  				"this version of the driver
  ");
  	else {
  		printk(KERN_ERR "  Trying to limit transfer sizes
  ");
570f89ea5   Borislav Petkov   ide-cd: convert t...
636
  		drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES;
64814f239   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
637
638
639
640
  	}
  
  	return 1;
  }
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
641
  static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
94f5a86dc   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
642

90eb808e0   Borislav Petkov   ide-cd: move requ...
643
644
  static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
  						 struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
645
  {
29f3aaca3   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
646
647
648
649
  	if (rq_data_dir(rq) == READ) {
  		unsigned short sectors_per_frame =
  			queue_hardsect_size(drive->queue) >> SECTOR_BITS;
  		int nskip = rq->sector & (sectors_per_frame - 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650

29f3aaca3   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
651
652
653
654
655
656
657
658
659
660
661
  		/*
  		 * If the requested sector doesn't start on a frame boundary,
  		 * we must adjust the start of the transfer so that it does,
  		 * and remember to skip the first few sectors.
  		 *
  		 * If the rq->current_nr_sectors field is larger than the size
  		 * of the buffer, it will mean that we're to skip a number of
  		 * sectors equal to the amount by which rq->current_nr_sectors
  		 * is larger than the buffer size.
  		 */
  		if (nskip > 0) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
662
  			/* sanity check... */
29f3aaca3   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
663
664
665
666
  			if (rq->current_nr_sectors !=
  			    bio_cur_sectors(rq->bio)) {
  				printk(KERN_ERR "%s: %s: buffer botch (%u)
  ",
177773ed8   Paolo Ciarrocchi   ide-cd: Replace _...
667
  						drive->name, __func__,
29f3aaca3   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
668
669
670
671
672
  						rq->current_nr_sectors);
  				cdrom_end_request(drive, 0);
  				return ide_stopped;
  			}
  			rq->current_nr_sectors += nskip;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
673
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
  	}
29f3aaca3   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
675
676
677
678
679
  #if 0
  	else
  		/* the immediate bit */
  		rq->cmd[1] = 1 << 3;
  #endif
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
680
  	/* set up the command */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
  	rq->timeout = ATAPI_WAIT_PC;
90eb808e0   Borislav Petkov   ide-cd: move requ...
682
683
684
685
686
687
688
689
690
691
692
693
  	return ide_started;
  }
  
  /*
   * Routine to send a read/write packet command to the drive. This is usually
   * called directly from cdrom_start_{read,write}(). However, for drq_interrupt
   * devices, it is called from an interrupt when the drive is ready to accept
   * the command.
   */
  static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
  {
  	struct request *rq = drive->hwif->hwgroup->rq;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
694
  	/* send the command to the drive and return */
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
695
  	return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
696
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
697
698
699
  #define IDECD_SEEK_THRESHOLD	(1000)			/* 1000 blocks */
  #define IDECD_SEEK_TIMER	(5 * WAIT_MIN_SLEEP)	/* 100 ms */
  #define IDECD_SEEK_TIMEOUT	(2 * WAIT_CMD)		/* 20 sec */
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
700
  static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
701
702
703
704
705
706
707
  {
  	struct cdrom_info *info = drive->driver_data;
  	int stat;
  	static int retry = 10;
  
  	if (cdrom_decode_status(drive, 0, &stat))
  		return ide_stopped;
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
708

570f89ea5   Borislav Petkov   ide-cd: convert t...
709
  	drive->atapi_flags |= IDE_AFLAG_SEEKING;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710
711
  
  	if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
712
  		if (--retry == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
713
  			drive->dsc_overlap = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
714
715
716
  	}
  	return ide_stopped;
  }
e529c6087   Borislav Petkov   ide-cd: move requ...
717
  static void ide_cd_prepare_seek_request(ide_drive_t *drive, struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
718
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
719
720
721
  	sector_t frame = rq->sector;
  
  	sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS);
d34c87e4b   FUJITA Tomonori   block: replace si...
722
  	memset(rq->cmd, 0, BLK_MAX_CDB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
723
724
725
726
  	rq->cmd[0] = GPCMD_SEEK;
  	put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]);
  
  	rq->timeout = ATAPI_WAIT_PC;
e529c6087   Borislav Petkov   ide-cd: move requ...
727
728
729
730
731
  }
  
  static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive)
  {
  	struct request *rq = drive->hwif->hwgroup->rq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
732
733
  	return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr);
  }
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
734
  /*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
735
736
   * Fix up a possibly partially-processed request so that we can start it over
   * entirely, or even put it back on the request queue.
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
737
738
   */
  static void restore_request(struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739
740
  {
  	if (rq->buffer != bio_data(rq->bio)) {
83c8565dc   Borislav Petkov   ide-cd: shorten l...
741
742
  		sector_t n =
  			(rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
743
744
745
746
747
  
  		rq->buffer = bio_data(rq->bio);
  		rq->nr_sectors += n;
  		rq->sector -= n;
  	}
83c8565dc   Borislav Petkov   ide-cd: shorten l...
748
749
  	rq->current_nr_sectors = bio_cur_sectors(rq->bio);
  	rq->hard_cur_sectors = rq->current_nr_sectors;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750
751
752
753
  	rq->hard_nr_sectors = rq->nr_sectors;
  	rq->hard_sector = rq->sector;
  	rq->q->prep_rq_fn(rq->q, rq);
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
754
755
  /*
   * All other packet commands.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
756
   */
8ee69f5a8   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
757
758
759
760
761
762
763
764
765
766
767
768
769
  static void ide_cd_request_sense_fixup(struct request *rq)
  {
  	/*
  	 * Some of the trailing request sense fields are optional,
  	 * and some drives don't send them.  Sigh.
  	 */
  	if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
  	    rq->data_len > 0 && rq->data_len <= 5)
  		while (rq->data_len > 0) {
  			*(u8 *)rq->data++ = 0;
  			--rq->data_len;
  		}
  }
5f828546e   FUJITA Tomonori   ide-cd: convert i...
770
771
772
773
  int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
  		    int write, void *buffer, unsigned *bufflen,
  		    struct request_sense *sense, int timeout,
  		    unsigned int cmd_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
774
  {
5f828546e   FUJITA Tomonori   ide-cd: convert i...
775
776
  	struct cdrom_info *info = drive->driver_data;
  	struct request_sense local_sense;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
777
  	int retries = 10;
5f828546e   FUJITA Tomonori   ide-cd: convert i...
778
  	unsigned int flags = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779

5f828546e   FUJITA Tomonori   ide-cd: convert i...
780
781
  	if (!sense)
  		sense = &local_sense;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
782

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
783
  	/* start of retry loop */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
784
  	do {
5f828546e   FUJITA Tomonori   ide-cd: convert i...
785
  		struct request *rq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
786
  		int error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
787

5f828546e   FUJITA Tomonori   ide-cd: convert i...
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
  		rq = blk_get_request(drive->queue, write, __GFP_WAIT);
  
  		memcpy(rq->cmd, cmd, BLK_MAX_CDB);
  		rq->cmd_type = REQ_TYPE_ATA_PC;
  		rq->sense = sense;
  		rq->cmd_flags |= cmd_flags;
  		rq->timeout = timeout;
  		if (buffer) {
  			rq->data = buffer;
  			rq->data_len = *bufflen;
  		}
  
  		error = blk_execute_rq(drive->queue, info->disk, rq, 0);
  
  		if (buffer)
  			*bufflen = rq->data_len;
  
  		flags = rq->cmd_flags;
  		blk_put_request(rq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
807

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
808
809
810
811
  		/*
  		 * FIXME: we should probably abort/retry or something in case of
  		 * failure.
  		 */
5f828546e   FUJITA Tomonori   ide-cd: convert i...
812
  		if (flags & REQ_FAILED) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
813
814
815
816
  			/*
  			 * The request failed.  Retry if it was due to a unit
  			 * attention status (usually means media was changed).
  			 */
5f828546e   FUJITA Tomonori   ide-cd: convert i...
817
  			struct request_sense *reqbuf = sense;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
818
819
820
821
822
  
  			if (reqbuf->sense_key == UNIT_ATTENTION)
  				cdrom_saw_media_change(drive);
  			else if (reqbuf->sense_key == NOT_READY &&
  				 reqbuf->asc == 4 && reqbuf->ascq != 4) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
823
824
825
826
827
  				/*
  				 * The drive is in the process of loading
  				 * a disk.  Retry, but wait a little to give
  				 * the drive time to complete the load.
  				 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
829
  				ssleep(2);
  			} else {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
830
  				/* otherwise, don't retry */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
831
832
833
834
  				retries = 0;
  			}
  			--retries;
  		}
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
835
  		/* end of retry loop */
5f828546e   FUJITA Tomonori   ide-cd: convert i...
836
  	} while ((flags & REQ_FAILED) && retries >= 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
837

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
838
  	/* return an error if the command failed */
5f828546e   FUJITA Tomonori   ide-cd: convert i...
839
  	return (flags & REQ_FAILED) ? -EIO : 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
840
841
842
  }
  
  /*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
843
844
845
   * Called from blk_end_request_callback() after the data of the request is
   * completed and before the request itself is completed. By returning value '1',
   * blk_end_request_callback() returns immediately without completing it.
aaa04c28c   Kiyoshi Ueda   blk_end_request: ...
846
847
848
849
850
   */
  static int cdrom_newpc_intr_dummy_cb(struct request *rq)
  {
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851
852
  static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
  {
23579a2a1   Bartlomiej Zolnierkiewicz   ide: remove IDE_*...
853
  	ide_hwif_t *hwif = drive->hwif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
854
855
  	struct cdrom_info *info = drive->driver_data;
  	struct request *rq = HWGROUP(drive)->rq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
  	xfer_func_t *xferfunc;
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
857
  	ide_expiry_t *expiry = NULL;
1823649b5   Bartlomiej Zolnierkiewicz   ide: add ide_read...
858
  	int dma_error = 0, dma, stat, thislen, uptodate = 0;
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
859
860
  	int write = (rq_data_dir(rq) == WRITE) ? 1 : 0;
  	unsigned int timeout;
1823649b5   Bartlomiej Zolnierkiewicz   ide: add ide_read...
861
862
  	u16 len;
  	u8 ireason;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
864
  	/* check for errors */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
865
866
867
  	dma = info->dma;
  	if (dma) {
  		info->dma = 0;
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
868
  		dma_error = hwif->dma_ops->dma_end(drive);
eba15fba1   Bartlomiej Zolnierkiewicz   ide-cd: fix DMA e...
869
870
871
  		if (dma_error) {
  			printk(KERN_ERR "%s: DMA %s error
  ", drive->name,
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
872
  					write ? "write" : "read");
eba15fba1   Bartlomiej Zolnierkiewicz   ide-cd: fix DMA e...
873
874
  			ide_dma_off(drive);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
875
876
877
878
  	}
  
  	if (cdrom_decode_status(drive, 0, &stat))
  		return ide_stopped;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
879
  	/* using dma, transfer is complete now */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
880
  	if (dma) {
eba15fba1   Bartlomiej Zolnierkiewicz   ide-cd: fix DMA e...
881
  		if (dma_error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
882
  			return ide_error(drive, "dma error", stat);
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
883
884
885
886
  		if (blk_fs_request(rq)) {
  			ide_end_request(drive, 1, rq->nr_sectors);
  			return ide_stopped;
  		}
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
887
  		goto end_request;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
888
  	}
1823649b5   Bartlomiej Zolnierkiewicz   ide: add ide_read...
889
  	ide_read_bcount_and_ireason(drive, &len, &ireason);
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
890
891
  
  	thislen = blk_fs_request(rq) ? len : rq->data_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
892
893
  	if (thislen > len)
  		thislen = len;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
894
  	/* If DRQ is clear, the command has completed. */
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
895
  	if ((stat & ATA_DRQ) == 0) {
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
896
897
898
899
900
901
902
903
904
905
  		if (blk_fs_request(rq)) {
  			/*
  			 * If we're not done reading/writing, complain.
  			 * Otherwise, complete the command normally.
  			 */
  			uptodate = 1;
  			if (rq->current_nr_sectors > 0) {
  				printk(KERN_ERR "%s: %s: data underrun "
  						"(%d blocks)
  ",
177773ed8   Paolo Ciarrocchi   ide-cd: Replace _...
906
  						drive->name, __func__,
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
907
908
909
910
911
912
913
914
  						rq->current_nr_sectors);
  				if (!write)
  					rq->cmd_flags |= REQ_FAILED;
  				uptodate = 0;
  			}
  			cdrom_end_request(drive, uptodate);
  			return ide_stopped;
  		} else if (!blk_pc_request(rq)) {
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
915
  			ide_cd_request_sense_fixup(rq);
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
916
  			/* complain if we still have data left to transfer */
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
917
918
919
  			uptodate = rq->data_len ? 0 : 1;
  		}
  		goto end_request;
aaa04c28c   Kiyoshi Ueda   blk_end_request: ...
920
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
921

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
922
  	/* check which way to transfer data */
9f10d9ee0   Bartlomiej Zolnierkiewicz   ide-cd: fix 'irea...
923
924
  	if (ide_cd_check_ireason(drive, rq, len, ireason, write))
  		return ide_stopped;
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
925

9f10d9ee0   Bartlomiej Zolnierkiewicz   ide-cd: fix 'irea...
926
927
  	if (blk_fs_request(rq)) {
  		if (write == 0) {
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
  			int nskip;
  
  			if (ide_cd_check_transfer_size(drive, len)) {
  				cdrom_end_request(drive, 0);
  				return ide_stopped;
  			}
  
  			/*
  			 * First, figure out if we need to bit-bucket
  			 * any of the leading sectors.
  			 */
  			nskip = min_t(int, rq->current_nr_sectors
  					   - bio_cur_sectors(rq->bio),
  					   thislen >> 9);
  			if (nskip > 0) {
ae8789f03   Borislav Petkov   ide-cd: remove id...
943
  				ide_pad_transfer(drive, write, nskip << 9);
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
944
945
946
947
  				rq->current_nr_sectors -= nskip;
  				thislen -= (nskip << 9);
  			}
  		}
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
948
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
949

ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
950
951
  	if (ireason == 0) {
  		write = 1;
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
952
  		xferfunc = hwif->tp_ops->output_data;
9f10d9ee0   Bartlomiej Zolnierkiewicz   ide-cd: fix 'irea...
953
  	} else {
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
954
  		write = 0;
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
955
  		xferfunc = hwif->tp_ops->input_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
956
  	}
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
957
  	/* transfer data */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
958
  	while (thislen > 0) {
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
959
  		u8 *ptr = blk_fs_request(rq) ? NULL : rq->data;
a11e77db4   Bartlomiej Zolnierkiewicz   ide-cd: prepare c...
960
  		int blen = rq->data_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
961

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
962
  		/* bio backed? */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
963
  		if (rq->bio) {
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
964
965
966
967
968
969
970
  			if (blk_fs_request(rq)) {
  				ptr = rq->buffer;
  				blen = rq->current_nr_sectors << 9;
  			} else {
  				ptr = bio_data(rq->bio);
  				blen = bio_iovec(rq->bio)->bv_len;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
971
972
973
  		}
  
  		if (!ptr) {
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
974
975
  			if (blk_fs_request(rq) && !write)
  				/*
968c49641   Borislav Petkov   ide-cd: remove th...
976
  				 * If the buffers are full, pipe the rest into
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
977
978
  				 * oblivion.
  				 */
ae8789f03   Borislav Petkov   ide-cd: remove id...
979
  				ide_pad_transfer(drive, 0, thislen);
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
980
981
982
983
984
985
986
987
  			else {
  				printk(KERN_ERR "%s: confused, missing data
  ",
  						drive->name);
  				blk_dump_rq_flags(rq, rq_data_dir(rq)
  						  ? "cdrom_newpc_intr, write"
  						  : "cdrom_newpc_intr, read");
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
988
989
990
991
992
  			break;
  		}
  
  		if (blen > thislen)
  			blen = thislen;
9567b349f   Bartlomiej Zolnierkiewicz   ide: merge ->atap...
993
  		xferfunc(drive, NULL, ptr, blen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
994
995
996
  
  		thislen -= blen;
  		len -= blen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997

0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
998
999
1000
1001
1002
1003
1004
1005
1006
1007
  		if (blk_fs_request(rq)) {
  			rq->buffer += blen;
  			rq->nr_sectors -= (blen >> 9);
  			rq->current_nr_sectors -= (blen >> 9);
  			rq->sector += (blen >> 9);
  
  			if (rq->current_nr_sectors == 0 && rq->nr_sectors)
  				cdrom_end_request(drive, 1);
  		} else {
  			rq->data_len -= blen;
aaa04c28c   Kiyoshi Ueda   blk_end_request: ...
1008
1009
1010
1011
1012
1013
  			/*
  			 * The request can't be completed until DRQ is cleared.
  			 * So complete the data, but don't complete the request
  			 * using the dummy function for the callback feature
  			 * of blk_end_request_callback().
  			 */
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1014
1015
  			if (rq->bio)
  				blk_end_request_callback(rq, 0, blen,
aaa04c28c   Kiyoshi Ueda   blk_end_request: ...
1016
  						 cdrom_newpc_intr_dummy_cb);
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1017
1018
1019
  			else
  				rq->data += blen;
  		}
bcd88ac3b   Andreas Schwab   ide-cd: fix CD/DV...
1020
1021
  		if (!write && blk_sense_request(rq))
  			rq->sense_len += blen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1022
  	}
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1023
  	/* pad, if necessary */
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1024
  	if (!blk_fs_request(rq) && len > 0)
ae8789f03   Borislav Petkov   ide-cd: remove id...
1025
  		ide_pad_transfer(drive, write, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1026

ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1027
1028
  	if (blk_pc_request(rq)) {
  		timeout = rq->timeout;
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1029
1030
  	} else {
  		timeout = ATAPI_WAIT_PC;
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1031
1032
  		if (!blk_fs_request(rq))
  			expiry = cdrom_timer_expiry;
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1033
1034
1035
  	}
  
  	ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1036
  	return ide_started;
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1037
1038
1039
1040
  
  end_request:
  	if (blk_pc_request(rq)) {
  		unsigned long flags;
14e04c3f6   Kiyoshi Ueda   ide-cd: fix missi...
1041
1042
1043
1044
  		unsigned int dlen = rq->data_len;
  
  		if (dma)
  			rq->data_len = 0;
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1045
1046
  
  		spin_lock_irqsave(&ide_lock, flags);
14e04c3f6   Kiyoshi Ueda   ide-cd: fix missi...
1047
  		if (__blk_end_request(rq, 0, dlen))
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1048
1049
1050
1051
1052
1053
1054
1055
1056
  			BUG();
  		HWGROUP(drive)->rq = NULL;
  		spin_unlock_irqrestore(&ide_lock, flags);
  	} else {
  		if (!uptodate)
  			rq->cmd_flags |= REQ_FAILED;
  		cdrom_end_request(drive, uptodate);
  	}
  	return ide_stopped;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1057
  }
21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1058
  static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1059
  {
21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1060
1061
1062
1063
  	struct cdrom_info *cd = drive->driver_data;
  	int write = rq_data_dir(rq) == WRITE;
  	unsigned short sectors_per_frame =
  		queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1064

21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1065
  	if (write) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1066
  		/* disk has become write protected */
b7db9956e   Tejun Heo   block: move polic...
1067
  		if (get_disk_ro(cd->disk)) {
21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1068
1069
1070
1071
1072
1073
1074
1075
1076
  			cdrom_end_request(drive, 0);
  			return ide_stopped;
  		}
  	} else {
  		/*
  		 * We may be retrying this request after an error.  Fix up any
  		 * weirdness which might be present in the request packet.
  		 */
  		restore_request(rq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1077
  	}
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1078
  	/* use DMA, if possible / writes *must* be hardware frame aligned */
21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1079
1080
1081
1082
1083
1084
1085
1086
1087
  	if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
  	    (rq->sector & (sectors_per_frame - 1))) {
  		if (write) {
  			cdrom_end_request(drive, 0);
  			return ide_stopped;
  		}
  		cd->dma = 0;
  	} else
  		cd->dma = drive->using_dma;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1088

21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1089
1090
  	if (write)
  		cd->devinfo.media_written = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1091

b6ca440a8   Borislav Petkov   ide-cd: simplify ...
1092
  	return ide_started;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1093
1094
1095
1096
1097
  }
  
  static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
  {
  	struct request *rq = HWGROUP(drive)->rq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1098
1099
  	return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
  }
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
1100
  static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1101
1102
  {
  	struct cdrom_info *info = drive->driver_data;
c9f56a801   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1103
1104
1105
1106
  	if (blk_pc_request(rq))
  		rq->cmd_flags |= REQ_QUIET;
  	else
  		rq->cmd_flags &= ~REQ_FAILED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1107
1108
  
  	info->dma = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1109

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1110
  	/* sg request */
e5318b531   FUJITA Tomonori   ide: use the dma ...
1111
1112
1113
  	if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) {
  		struct request_queue *q = drive->queue;
  		unsigned int alignment;
efa402d59   FUJITA Tomonori   ide-cd: use the n...
1114
  		char *buf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1115

e5318b531   FUJITA Tomonori   ide: use the dma ...
1116
  		if (rq->bio)
efa402d59   FUJITA Tomonori   ide-cd: use the n...
1117
  			buf = bio_data(rq->bio);
e5318b531   FUJITA Tomonori   ide: use the dma ...
1118
  		else
efa402d59   FUJITA Tomonori   ide-cd: use the n...
1119
  			buf = rq->data;
e5318b531   FUJITA Tomonori   ide: use the dma ...
1120

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1121
1122
1123
1124
  		info->dma = drive->using_dma;
  
  		/*
  		 * check if dma is safe
5d9e4ea55   Linus Torvalds   ide-cd: revert DM...
1125
1126
1127
  		 *
  		 * NOTE! The "len" and "addr" checks should possibly have
  		 * separate masks.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1128
  		 */
e5318b531   FUJITA Tomonori   ide: use the dma ...
1129
  		alignment = queue_dma_alignment(q) | q->dma_pad_mask;
efa402d59   FUJITA Tomonori   ide-cd: use the n...
1130
1131
  		if ((unsigned long)buf & alignment || rq->data_len & alignment
  		    || object_is_on_stack(buf))
0b6abc177   FUJITA Tomonori   ide: avoid DMA on...
1132
  			info->dma = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1133
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1134
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1135
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1136
1137
   * cdrom driver request routine.
   */
99384aeaf   Borislav Petkov   ide-cd: mv ide_do...
1138
  static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
e5e076a35   Borislav Petkov   ide-cd: fix remai...
1139
  					sector_t block)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1140
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1141
  	struct cdrom_info *info = drive->driver_data;
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
1142
1143
  	ide_handler_t *fn;
  	int xferlen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1144
1145
  
  	if (blk_fs_request(rq)) {
570f89ea5   Borislav Petkov   ide-cd: convert t...
1146
  		if (drive->atapi_flags & IDE_AFLAG_SEEKING) {
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
1147
  			ide_hwif_t *hwif = drive->hwif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1148
  			unsigned long elapsed = jiffies - info->start_seek;
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
1149
  			int stat = hwif->tp_ops->read_status(hwif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1150

3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
1151
  			if ((stat & ATA_DSC) != ATA_DSC) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1152
  				if (elapsed < IDECD_SEEK_TIMEOUT) {
83c8565dc   Borislav Petkov   ide-cd: shorten l...
1153
1154
  					ide_stall_queue(drive,
  							IDECD_SEEK_TIMER);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1155
1156
  					return ide_stopped;
  				}
83c8565dc   Borislav Petkov   ide-cd: shorten l...
1157
1158
1159
  				printk(KERN_ERR "%s: DSC timeout
  ",
  						drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1160
  			}
570f89ea5   Borislav Petkov   ide-cd: convert t...
1161
  			drive->atapi_flags &= ~IDE_AFLAG_SEEKING;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1162
  		}
83c8565dc   Borislav Petkov   ide-cd: shorten l...
1163
1164
  		if (rq_data_dir(rq) == READ &&
  		    IDE_LARGE_SEEK(info->last_block, block,
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
1165
1166
1167
1168
  			    IDECD_SEEK_THRESHOLD) &&
  		    drive->dsc_overlap) {
  			xferlen = 0;
  			fn = cdrom_start_seek_continuation;
e529c6087   Borislav Petkov   ide-cd: move requ...
1169

4b01fcbbe   Borislav Petkov   ide-cd: fold cdro...
1170
1171
  			info->dma = 0;
  			info->start_seek = jiffies;
e529c6087   Borislav Petkov   ide-cd: move requ...
1172
1173
  
  			ide_cd_prepare_seek_request(drive, rq);
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
1174
1175
1176
  		} else {
  			xferlen = 32768;
  			fn = cdrom_start_rw_cont;
90eb808e0   Borislav Petkov   ide-cd: move requ...
1177

b6ca440a8   Borislav Petkov   ide-cd: simplify ...
1178
1179
  			if (cdrom_start_rw(drive, rq) == ide_stopped)
  				return ide_stopped;
90eb808e0   Borislav Petkov   ide-cd: move requ...
1180
1181
1182
  
  			if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped)
  				return ide_stopped;
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
1183
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1184
  		info->last_block = block;
c9f56a801   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
1185
  	} else if (blk_sense_request(rq) || blk_pc_request(rq) ||
cea2885a2   Jens Axboe   [PATCH] ide-cd: f...
1186
  		   rq->cmd_type == REQ_TYPE_ATA_PC) {
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
1187
1188
  		xferlen = rq->data_len;
  		fn = cdrom_do_newpc_cont;
7fcebda50   Borislav Petkov   ide-cd: move requ...
1189
1190
1191
  
  		if (!rq->timeout)
  			rq->timeout = ATAPI_WAIT_PC;
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
1192
  		cdrom_do_block_pc(drive, rq);
4aff5e233   Jens Axboe   [PATCH] Split str...
1193
  	} else if (blk_special_request(rq)) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1194
  		/* right now this can only be a reset... */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1195
1196
  		cdrom_end_request(drive, 1);
  		return ide_stopped;
ab9d6e337   Borislav Petkov   ide-cd: ide_do_rw...
1197
1198
1199
1200
  	} else {
  		blk_dump_rq_flags(rq, "ide-cd bad flags");
  		cdrom_end_request(drive, 0);
  		return ide_stopped;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1201
  	}
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
1202
1203
  
  	return cdrom_start_packet_command(drive, xferlen, fn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1204
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1205
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1206
1207
   * Ioctl handling.
   *
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1208
1209
1210
1211
1212
   * Routines which queue packet commands take as a final argument a pointer to a
   * request_sense struct. If execution of the command results in an error with a
   * CHECK CONDITION status, this structure will be filled with the results of the
   * subsequent request sense command. The pointer can also be NULL, in which case
   * no sense information is returned.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1213
   */
e5e076a35   Borislav Petkov   ide-cd: fix remai...
1214
  static void msf_from_bcd(struct atapi_msf *msf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1215
  {
fc99856a4   Adrian Bunk   ide-cd: use bcd2b...
1216
1217
1218
  	msf->minute = bcd2bin(msf->minute);
  	msf->second = bcd2bin(msf->second);
  	msf->frame  = bcd2bin(msf->frame);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1219
  }
f9afd18b5   Borislav Petkov   ide-cd: move the ...
1220
  int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1221
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1222
1223
  	struct cdrom_info *info = drive->driver_data;
  	struct cdrom_device_info *cdi = &info->devinfo;
5f828546e   FUJITA Tomonori   ide-cd: convert i...
1224
  	unsigned char cmd[BLK_MAX_CDB];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1225

5f828546e   FUJITA Tomonori   ide-cd: convert i...
1226
1227
  	memset(cmd, 0, BLK_MAX_CDB);
  	cmd[0] = GPCMD_TEST_UNIT_READY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1228

cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
1229
  	/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1230
1231
  	 * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs
  	 * instead of supporting the LOAD_UNLOAD opcode.
cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
1232
  	 */
5f828546e   FUJITA Tomonori   ide-cd: convert i...
1233
  	cmd[7] = cdi->sanyo_slot % 3;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1234

141d3b27f   Harvey Harrison   ide: ide-cd.c fix...
1235
  	return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, sense, 0, REQ_QUIET);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1236
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1237
1238
1239
1240
1241
  static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
  			       unsigned long *sectors_per_frame,
  			       struct request_sense *sense)
  {
  	struct {
141d3b27f   Harvey Harrison   ide: ide-cd.c fix...
1242
1243
  		__be32 lba;
  		__be32 blocklen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1244
1245
1246
  	} capbuf;
  
  	int stat;
5f828546e   FUJITA Tomonori   ide-cd: convert i...
1247
1248
  	unsigned char cmd[BLK_MAX_CDB];
  	unsigned len = sizeof(capbuf);
938bb03d1   Petr Tesarik   ide-cd: fix endia...
1249
  	u32 blocklen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1250

5f828546e   FUJITA Tomonori   ide-cd: convert i...
1251
1252
  	memset(cmd, 0, BLK_MAX_CDB);
  	cmd[0] = GPCMD_READ_CDVD_CAPACITY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1253

5f828546e   FUJITA Tomonori   ide-cd: convert i...
1254
1255
  	stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0,
  			       REQ_QUIET);
e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
1256
1257
1258
1259
1260
1261
  	if (stat)
  		return stat;
  
  	/*
  	 * Sanity check the given block size
  	 */
938bb03d1   Petr Tesarik   ide-cd: fix endia...
1262
1263
1264
1265
1266
1267
  	blocklen = be32_to_cpu(capbuf.blocklen);
  	switch (blocklen) {
  	case 512:
  	case 1024:
  	case 2048:
  	case 4096:
e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
1268
1269
1270
1271
  		break;
  	default:
  		printk(KERN_ERR "%s: weird block size %u
  ",
938bb03d1   Petr Tesarik   ide-cd: fix endia...
1272
  			drive->name, blocklen);
e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
1273
1274
1275
  		printk(KERN_ERR "%s: default to 2kb block size
  ",
  			drive->name);
938bb03d1   Petr Tesarik   ide-cd: fix endia...
1276
  		blocklen = 2048;
e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
1277
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1278
  	}
e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
1279
  	*capacity = 1 + be32_to_cpu(capbuf.lba);
938bb03d1   Petr Tesarik   ide-cd: fix endia...
1280
  	*sectors_per_frame = blocklen >> SECTOR_BITS;
e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
1281
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1282
1283
1284
1285
1286
1287
  }
  
  static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
  				int format, char *buf, int buflen,
  				struct request_sense *sense)
  {
5f828546e   FUJITA Tomonori   ide-cd: convert i...
1288
  	unsigned char cmd[BLK_MAX_CDB];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1289

5f828546e   FUJITA Tomonori   ide-cd: convert i...
1290
  	memset(cmd, 0, BLK_MAX_CDB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1291

5f828546e   FUJITA Tomonori   ide-cd: convert i...
1292
1293
1294
1295
1296
  	cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
  	cmd[6] = trackno;
  	cmd[7] = (buflen >> 8);
  	cmd[8] = (buflen & 0xff);
  	cmd[9] = (format << 6);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1297
1298
  
  	if (msf_flag)
5f828546e   FUJITA Tomonori   ide-cd: convert i...
1299
  		cmd[1] = 2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1300

5f828546e   FUJITA Tomonori   ide-cd: convert i...
1301
  	return ide_cd_queue_pc(drive, cmd, 0, buf, &buflen, sense, 0, REQ_QUIET);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1302
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1303
  /* Try to read the entire TOC for the disk into our internal buffer. */
17802998d   Bartlomiej Zolnierkiewicz   ide-cd: move code...
1304
  int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
  {
  	int stat, ntracks, i;
  	struct cdrom_info *info = drive->driver_data;
  	struct cdrom_device_info *cdi = &info->devinfo;
  	struct atapi_toc *toc = info->toc;
  	struct {
  		struct atapi_toc_header hdr;
  		struct atapi_toc_entry  ent;
  	} ms_tmp;
  	long last_written;
  	unsigned long sectors_per_frame = SECTORS_PER_FRAME;
  
  	if (toc == NULL) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1318
  		/* try to allocate space */
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
1319
  		toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1320
  		if (toc == NULL) {
83c8565dc   Borislav Petkov   ide-cd: shorten l...
1321
1322
1323
  			printk(KERN_ERR "%s: No cdrom TOC buffer!
  ",
  					drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1324
1325
  			return -ENOMEM;
  		}
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
1326
  		info->toc = toc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1327
  	}
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1328
1329
1330
1331
  	/*
  	 * Check to see if the existing data is still valid. If it is,
  	 * just return.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1332
  	(void) cdrom_check_status(drive, sense);
570f89ea5   Borislav Petkov   ide-cd: convert t...
1333
  	if (drive->atapi_flags & IDE_AFLAG_TOC_VALID)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1334
  		return 0;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1335
  	/* try to get the total cdrom capacity and sector size */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1336
1337
1338
1339
1340
1341
  	stat = cdrom_read_capacity(drive, &toc->capacity, &sectors_per_frame,
  				   sense);
  	if (stat)
  		toc->capacity = 0x1fffff;
  
  	set_capacity(info->disk, toc->capacity * sectors_per_frame);
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1342
  	/* save a private copy of the TOC capacity for error handling */
dbe217af3   Alan Cox   [PATCH] IDE CD en...
1343
  	drive->probed_capacity = toc->capacity * sectors_per_frame;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1344
1345
  	blk_queue_hardsect_size(drive->queue,
  				sectors_per_frame << SECTOR_BITS);
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1346
  	/* first read just the header, so we know how long the TOC is */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1347
1348
  	stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
  				    sizeof(struct atapi_toc_header), sense);
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
1349
1350
  	if (stat)
  		return stat;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1351

570f89ea5   Borislav Petkov   ide-cd: convert t...
1352
  	if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
fc99856a4   Adrian Bunk   ide-cd: use bcd2b...
1353
1354
  		toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
  		toc->hdr.last_track  = bcd2bin(toc->hdr.last_track);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1355
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1356
1357
1358
1359
1360
1361
  
  	ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
  	if (ntracks <= 0)
  		return -EIO;
  	if (ntracks > MAX_TRACKS)
  		ntracks = MAX_TRACKS;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1362
  	/* now read the whole schmeer */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1363
1364
1365
1366
1367
1368
1369
  	stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0,
  				  (char *)&toc->hdr,
  				   sizeof(struct atapi_toc_header) +
  				   (ntracks + 1) *
  				   sizeof(struct atapi_toc_entry), sense);
  
  	if (stat && toc->hdr.first_track > 1) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
  		/*
  		 * Cds with CDI tracks only don't have any TOC entries, despite
  		 * of this the returned values are
  		 * first_track == last_track = number of CDI tracks + 1,
  		 * so that this case is indistinguishable from the same layout
  		 * plus an additional audio track. If we get an error for the
  		 * regular case, we assume a CDI without additional audio
  		 * tracks. In this case the readable TOC is empty (CDI tracks
  		 * are not included) and only holds the Leadout entry.
  		 *
  		 * Heiko Eißfeldt.
  		 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1382
1383
1384
1385
1386
1387
1388
  		ntracks = 0;
  		stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
  					   (char *)&toc->hdr,
  					   sizeof(struct atapi_toc_header) +
  					   (ntracks + 1) *
  					   sizeof(struct atapi_toc_entry),
  					   sense);
cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
1389
  		if (stat)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1390
  			return stat;
cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
1391

570f89ea5   Borislav Petkov   ide-cd: convert t...
1392
  		if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
fc99856a4   Adrian Bunk   ide-cd: use bcd2b...
1393
1394
  			toc->hdr.first_track = (u8)bin2bcd(CDROM_LEADOUT);
  			toc->hdr.last_track = (u8)bin2bcd(CDROM_LEADOUT);
cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
1395
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1396
1397
1398
1399
1400
1401
1402
  			toc->hdr.first_track = CDROM_LEADOUT;
  			toc->hdr.last_track = CDROM_LEADOUT;
  		}
  	}
  
  	if (stat)
  		return stat;
7eb43fd2f   Borislav Petkov   ide-cd: replace n...
1403
  	toc->hdr.toc_length = be16_to_cpu(toc->hdr.toc_length);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1404

570f89ea5   Borislav Petkov   ide-cd: convert t...
1405
  	if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
fc99856a4   Adrian Bunk   ide-cd: use bcd2b...
1406
1407
  		toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
  		toc->hdr.last_track  = bcd2bin(toc->hdr.last_track);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1408
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1409

cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
1410
  	for (i = 0; i <= ntracks; i++) {
570f89ea5   Borislav Petkov   ide-cd: convert t...
1411
1412
  		if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) {
  			if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD)
fc99856a4   Adrian Bunk   ide-cd: use bcd2b...
1413
  				toc->ent[i].track = bcd2bin(toc->ent[i].track);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1414
1415
  			msf_from_bcd(&toc->ent[i].addr.msf);
  		}
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1416
1417
1418
  		toc->ent[i].addr.lba = msf_to_lba(toc->ent[i].addr.msf.minute,
  						  toc->ent[i].addr.msf.second,
  						  toc->ent[i].addr.msf.frame);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1419
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1420
  	if (toc->hdr.first_track != CDROM_LEADOUT) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1421
  		/* read the multisession information */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1422
1423
  		stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
  					   sizeof(ms_tmp), sense);
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
1424
1425
  		if (stat)
  			return stat;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1426
1427
1428
  
  		toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
  	} else {
e5e076a35   Borislav Petkov   ide-cd: fix remai...
1429
1430
  		ms_tmp.hdr.last_track = CDROM_LEADOUT;
  		ms_tmp.hdr.first_track = ms_tmp.hdr.last_track;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1431
1432
  		toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
  	}
570f89ea5   Borislav Petkov   ide-cd: convert t...
1433
  	if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1434
  		/* re-read multisession information using MSF format */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1435
1436
1437
1438
  		stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
  					   sizeof(ms_tmp), sense);
  		if (stat)
  			return stat;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1439
  		msf_from_bcd(&ms_tmp.ent.addr.msf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1440
  		toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute,
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1441
  						   ms_tmp.ent.addr.msf.second,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1442
1443
  						   ms_tmp.ent.addr.msf.frame);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444
1445
  
  	toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1446
  	/* now try to get the total cdrom capacity */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1447
1448
1449
1450
  	stat = cdrom_get_last_written(cdi, &last_written);
  	if (!stat && (last_written > toc->capacity)) {
  		toc->capacity = last_written;
  		set_capacity(info->disk, toc->capacity * sectors_per_frame);
dbe217af3   Alan Cox   [PATCH] IDE CD en...
1451
  		drive->probed_capacity = toc->capacity * sectors_per_frame;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1452
1453
1454
  	}
  
  	/* Remember that we've read this stuff. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1455
  	drive->atapi_flags |= IDE_AFLAG_TOC_VALID;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1456
1457
1458
  
  	return 0;
  }
17802998d   Bartlomiej Zolnierkiewicz   ide-cd: move code...
1459
  int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
9235e68be   Eric Piel   [PATCH] IDE CD re...
1460
1461
1462
1463
  {
  	struct cdrom_info *info = drive->driver_data;
  	struct cdrom_device_info *cdi = &info->devinfo;
  	struct packet_command cgc;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1464
  	int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
9235e68be   Eric Piel   [PATCH] IDE CD re...
1465

570f89ea5   Borislav Petkov   ide-cd: convert t...
1466
  	if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0)
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1467
  		size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
9235e68be   Eric Piel   [PATCH] IDE CD re...
1468

455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1469
  	init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN);
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1470
1471
  	do {
  		/* we seem to get stat=0x01,err=0x00 the first time (??) */
9235e68be   Eric Piel   [PATCH] IDE CD re...
1472
1473
1474
1475
1476
1477
  		stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
  		if (!stat)
  			break;
  	} while (--attempts);
  	return stat;
  }
17802998d   Bartlomiej Zolnierkiewicz   ide-cd: move code...
1478
  void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
9235e68be   Eric Piel   [PATCH] IDE CD re...
1479
  {
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1480
  	struct cdrom_info *cd = drive->driver_data;
481c8c647   Bartlomiej Zolnierkiewicz   ide-cd: cleanup i...
1481
  	u16 curspeed, maxspeed;
570f89ea5   Borislav Petkov   ide-cd: convert t...
1482
  	if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) {
141d3b27f   Harvey Harrison   ide: ide-cd.c fix...
1483
1484
  		curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]);
  		maxspeed = le16_to_cpup((__le16 *)&buf[8 + 8]);
9235e68be   Eric Piel   [PATCH] IDE CD re...
1485
  	} else {
141d3b27f   Harvey Harrison   ide: ide-cd.c fix...
1486
1487
  		curspeed = be16_to_cpup((__be16 *)&buf[8 + 14]);
  		maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
9235e68be   Eric Piel   [PATCH] IDE CD re...
1488
  	}
481c8c647   Bartlomiej Zolnierkiewicz   ide-cd: cleanup i...
1489

2bc4cf2d8   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1490
1491
  	cd->current_speed = (curspeed + (176/2)) / 176;
  	cd->max_speed = (maxspeed + (176/2)) / 176;
9235e68be   Eric Piel   [PATCH] IDE CD re...
1492
  }
20e7f7efa   Bartlomiej Zolnierkiewicz   ide-cd: add IDE_C...
1493
1494
1495
1496
1497
1498
  #define IDE_CD_CAPABILITIES \
  	(CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | \
  	 CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | \
  	 CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R | \
  	 CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_GENERIC_PACKET | \
  	 CDC_MO_DRIVE | CDC_MRW | CDC_MRW_W | CDC_RAM)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1499

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
  static struct cdrom_device_ops ide_cdrom_dops = {
  	.open			= ide_cdrom_open_real,
  	.release		= ide_cdrom_release_real,
  	.drive_status		= ide_cdrom_drive_status,
  	.media_changed		= ide_cdrom_check_media_change_real,
  	.tray_move		= ide_cdrom_tray_move,
  	.lock_door		= ide_cdrom_lock_door,
  	.select_speed		= ide_cdrom_select_speed,
  	.get_last_session	= ide_cdrom_get_last_session,
  	.get_mcn		= ide_cdrom_get_mcn,
  	.reset			= ide_cdrom_reset,
  	.audio_ioctl		= ide_cdrom_audio_ioctl,
20e7f7efa   Bartlomiej Zolnierkiewicz   ide-cd: add IDE_C...
1512
  	.capability		= IDE_CD_CAPABILITIES,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1513
1514
  	.generic_packet		= ide_cdrom_packet,
  };
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1515
  static int ide_cdrom_register(ide_drive_t *drive, int nslots)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1516
1517
1518
1519
1520
  {
  	struct cdrom_info *info = drive->driver_data;
  	struct cdrom_device_info *devinfo = &info->devinfo;
  
  	devinfo->ops = &ide_cdrom_dops;
2bc4cf2d8   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1521
  	devinfo->speed = info->current_speed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1522
  	devinfo->capacity = nslots;
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
1523
  	devinfo->handle = drive;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1524
  	strcpy(devinfo->name, drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1525

570f89ea5   Borislav Petkov   ide-cd: convert t...
1526
  	if (drive->atapi_flags & IDE_AFLAG_NO_SPEED_SELECT)
3cbd814ef   Bartlomiej Zolnierkiewicz   ide-cd: fix SAMSU...
1527
  		devinfo->mask |= CDC_SELECT_SPEED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1528
1529
1530
  	devinfo->disk = info->disk;
  	return register_cdrom(devinfo);
  }
e5e076a35   Borislav Petkov   ide-cd: fix remai...
1531
  static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1532
  {
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1533
1534
  	struct cdrom_info *cd = drive->driver_data;
  	struct cdrom_device_info *cdi = &cd->devinfo;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1535
1536
  	u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
  	mechtype_t mechtype;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1537
  	int nslots = 1;
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1538
1539
1540
  	cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R |
  		     CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO |
  		     CDC_MO_DRIVE | CDC_RAM);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1541
  	if (drive->media == ide_optical) {
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1542
  		cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM);
83c8565dc   Borislav Petkov   ide-cd: shorten l...
1543
1544
1545
  		printk(KERN_ERR "%s: ATAPI magneto-optical drive
  ",
  				drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1546
1547
  		return nslots;
  	}
570f89ea5   Borislav Petkov   ide-cd: convert t...
1548
1549
  	if (drive->atapi_flags & IDE_AFLAG_PRE_ATAPI12) {
  		drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT;
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1550
  		cdi->mask &= ~CDC_PLAY_AUDIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1551
1552
1553
1554
  		return nslots;
  	}
  
  	/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1555
1556
1557
1558
  	 * We have to cheat a little here. the packet will eventually be queued
  	 * with ide_cdrom_packet(), which extracts the drive from cdi->handle.
  	 * Since this device hasn't been registered with the Uniform layer yet,
  	 * it can't do this. Same goes for cdi->ops.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1559
  	 */
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
1560
  	cdi->handle = drive;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1561
  	cdi->ops = &ide_cdrom_dops;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1562
  	if (ide_cdrom_get_capabilities(drive, buf))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1563
  		return 0;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1564
  	if ((buf[8 + 6] & 0x01) == 0)
570f89ea5   Borislav Petkov   ide-cd: convert t...
1565
  		drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1566
  	if (buf[8 + 6] & 0x08)
570f89ea5   Borislav Petkov   ide-cd: convert t...
1567
  		drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1568
  	if (buf[8 + 3] & 0x01)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1569
  		cdi->mask &= ~CDC_CD_R;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1570
  	if (buf[8 + 3] & 0x02)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1571
  		cdi->mask &= ~(CDC_CD_RW | CDC_RAM);
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1572
  	if (buf[8 + 2] & 0x38)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1573
  		cdi->mask &= ~CDC_DVD;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1574
  	if (buf[8 + 3] & 0x20)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1575
  		cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM);
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1576
  	if (buf[8 + 3] & 0x10)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1577
  		cdi->mask &= ~CDC_DVD_R;
570f89ea5   Borislav Petkov   ide-cd: convert t...
1578
  	if ((buf[8 + 4] & 0x01) || (drive->atapi_flags & IDE_AFLAG_PLAY_AUDIO_OK))
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1579
  		cdi->mask &= ~CDC_PLAY_AUDIO;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1580
1581
  
  	mechtype = buf[8 + 6] >> 5;
f20f25860   Borislav Petkov   ide-cd: temporary...
1582
1583
1584
  	if (mechtype == mechtype_caddy ||
  	    mechtype == mechtype_popup ||
  	    (drive->atapi_flags & IDE_AFLAG_NO_AUTOCLOSE))
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1585
  		cdi->mask |= CDC_CLOSE_TRAY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1586

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1587
  	if (cdi->sanyo_slot > 0) {
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1588
  		cdi->mask &= ~CDC_SELECT_DISC;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1589
  		nslots = 3;
cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
1590
1591
  	} else if (mechtype == mechtype_individual_changer ||
  		   mechtype == mechtype_cartridge_changer) {
2609d06d3   Bartlomiej Zolnierkiewicz   ide-cd: remove un...
1592
1593
  		nslots = cdrom_number_of_slots(cdi);
  		if (nslots > 1)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1594
  			cdi->mask &= ~CDC_SELECT_DISC;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1595
  	}
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1596
  	ide_cdrom_update_speed(drive, buf);
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1597

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1598
  	printk(KERN_INFO "%s: ATAPI", drive->name);
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1599
1600
  
  	/* don't print speed if the drive reported 0 */
2bc4cf2d8   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1601
1602
  	if (cd->max_speed)
  		printk(KERN_CONT " %dX", cd->max_speed);
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1603

3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1604
  	printk(KERN_CONT " %s", (cdi->mask & CDC_DVD) ? "CD-ROM" : "DVD-ROM");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1605

3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1606
1607
1608
1609
  	if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0)
  		printk(KERN_CONT " DVD%s%s",
  				 (cdi->mask & CDC_DVD_R) ? "" : "-R",
  				 (cdi->mask & CDC_DVD_RAM) ? "" : "-RAM");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1610

3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1611
1612
1613
1614
  	if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0)
  		printk(KERN_CONT " CD%s%s",
  				 (cdi->mask & CDC_CD_R) ? "" : "-R",
  				 (cdi->mask & CDC_CD_RW) ? "" : "/RW");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1615

3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1616
1617
1618
1619
  	if ((cdi->mask & CDC_SELECT_DISC) == 0)
  		printk(KERN_CONT " changer w/%d slots", nslots);
  	else
  		printk(KERN_CONT " drive");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1620

141d3b27f   Harvey Harrison   ide: ide-cd.c fix...
1621
1622
  	printk(KERN_CONT ", %dkB Cache
  ", be16_to_cpup((__be16 *)&buf[8 + 12]));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1623
1624
1625
  
  	return nslots;
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1626
  /* standard prep_rq_fn that builds 10 byte cmds */
165125e1e   Jens Axboe   [BLOCK] Get rid o...
1627
  static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1628
1629
1630
1631
  {
  	int hard_sect = queue_hardsect_size(q);
  	long block = (long)rq->hard_sector / (hard_sect >> 9);
  	unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
d34c87e4b   FUJITA Tomonori   block: replace si...
1632
  	memset(rq->cmd, 0, BLK_MAX_CDB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
  
  	if (rq_data_dir(rq) == READ)
  		rq->cmd[0] = GPCMD_READ_10;
  	else
  		rq->cmd[0] = GPCMD_WRITE_10;
  
  	/*
  	 * fill in lba
  	 */
  	rq->cmd[2] = (block >> 24) & 0xff;
  	rq->cmd[3] = (block >> 16) & 0xff;
  	rq->cmd[4] = (block >>  8) & 0xff;
  	rq->cmd[5] = block & 0xff;
  
  	/*
  	 * and transfer length
  	 */
  	rq->cmd[7] = (blocks >> 8) & 0xff;
  	rq->cmd[8] = blocks & 0xff;
  	rq->cmd_len = 10;
  	return BLKPREP_OK;
  }
  
  /*
   * Most of the SCSI commands are supported directly by ATAPI devices.
   * This transform handles the few exceptions.
   */
  static int ide_cdrom_prep_pc(struct request *rq)
  {
  	u8 *c = rq->cmd;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1663
  	/* transform 6-byte read/write commands to the 10-byte version */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
  	if (c[0] == READ_6 || c[0] == WRITE_6) {
  		c[8] = c[4];
  		c[5] = c[3];
  		c[4] = c[2];
  		c[3] = c[1] & 0x1f;
  		c[2] = 0;
  		c[1] &= 0xe0;
  		c[0] += (READ_10 - READ_6);
  		rq->cmd_len = 10;
  		return BLKPREP_OK;
  	}
  
  	/*
  	 * it's silly to pretend we understand 6-byte sense commands, just
  	 * reject with ILLEGAL_REQUEST and the caller should take the
  	 * appropriate action
  	 */
  	if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) {
  		rq->errors = ILLEGAL_REQUEST;
  		return BLKPREP_KILL;
  	}
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1685

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1686
1687
  	return BLKPREP_OK;
  }
165125e1e   Jens Axboe   [BLOCK] Get rid o...
1688
  static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1689
  {
4aff5e233   Jens Axboe   [PATCH] Split str...
1690
  	if (blk_fs_request(rq))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1691
  		return ide_cdrom_prep_fs(q, rq);
4aff5e233   Jens Axboe   [PATCH] Split str...
1692
  	else if (blk_pc_request(rq))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1693
1694
1695
1696
  		return ide_cdrom_prep_pc(rq);
  
  	return 0;
  }
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1697
1698
1699
1700
1701
  struct cd_list_entry {
  	const char	*id_model;
  	const char	*id_firmware;
  	unsigned int	cd_flags;
  };
5e657a9e2   Borislav Petkov   ide-cd: put all p...
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
  #ifdef CONFIG_IDE_PROC_FS
  static sector_t ide_cdrom_capacity(ide_drive_t *drive)
  {
  	unsigned long capacity, sectors_per_frame;
  
  	if (cdrom_read_capacity(drive, &capacity, &sectors_per_frame, NULL))
  		return 0;
  
  	return capacity * sectors_per_frame;
  }
e5e076a35   Borislav Petkov   ide-cd: fix remai...
1712
1713
  static int proc_idecd_read_capacity(char *page, char **start, off_t off,
  					int count, int *eof, void *data)
5e657a9e2   Borislav Petkov   ide-cd: put all p...
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
  {
  	ide_drive_t *drive = data;
  	int len;
  
  	len = sprintf(page, "%llu
  ", (long long)ide_cdrom_capacity(drive));
  	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
  }
  
  static ide_proc_entry_t idecd_proc[] = {
  	{ "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
  	{ NULL, 0, NULL, NULL }
  };
8185d5aa9   Bartlomiej Zolnierkiewicz   ide: /proc/ide/hd...
1727
1728
1729
1730
1731
1732
  ide_devset_rw(dsc_overlap, 0, 1, dsc_overlap);
  
  static const struct ide_devset *idecd_settings[] = {
  	&ide_devset_dsc_overlap,
  	NULL
  };
5e657a9e2   Borislav Petkov   ide-cd: put all p...
1733
  #endif
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1734
1735
  static const struct cd_list_entry ide_cd_quirks_list[] = {
  	/* Limit transfer size per interrupt. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1736
1737
  	{ "SAMSUNG CD-ROM SCR-2430", NULL,   IDE_AFLAG_LIMIT_NFRAMES	     },
  	{ "SAMSUNG CD-ROM SCR-2432", NULL,   IDE_AFLAG_LIMIT_NFRAMES	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1738
  	/* SCR-3231 doesn't support the SET_CD_SPEED command. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1739
  	{ "SAMSUNG CD-ROM SCR-3231", NULL,   IDE_AFLAG_NO_SPEED_SELECT	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1740
  	/* Old NEC260 (not R) was released before ATAPI 1.2 spec. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1741
1742
  	{ "NEC CD-ROM DRIVE:260",    "1.01", IDE_AFLAG_TOCADDR_AS_BCD |
  					     IDE_AFLAG_PRE_ATAPI12,	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1743
  	/* Vertos 300, some versions of this drive like to talk BCD. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1744
  	{ "V003S0DS",		     NULL,   IDE_AFLAG_VERTOS_300_SSD,	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1745
  	/* Vertos 600 ESD. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1746
  	{ "V006E0DS",		     NULL,   IDE_AFLAG_VERTOS_600_ESD,	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1747
1748
1749
1750
  	/*
  	 * Sanyo 3 CD changer uses a non-standard command for CD changing
  	 * (by default standard ATAPI support for CD changers is used).
  	 */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1751
1752
1753
  	{ "CD-ROM CDR-C3 G",	     NULL,   IDE_AFLAG_SANYO_3CD	     },
  	{ "CD-ROM CDR-C3G",	     NULL,   IDE_AFLAG_SANYO_3CD	     },
  	{ "CD-ROM CDR_C36",	     NULL,   IDE_AFLAG_SANYO_3CD	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1754
  	/* Stingray 8X CD-ROM. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1755
  	{ "STINGRAY 8422 IDE 8X CD-ROM 7-27-95", NULL, IDE_AFLAG_PRE_ATAPI12 },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1756
1757
1758
1759
  	/*
  	 * ACER 50X CD-ROM and WPI 32X CD-ROM require the full spec length
  	 * mode sense page capabilities size, but older drives break.
  	 */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1760
1761
  	{ "ATAPI CD ROM DRIVE 50X MAX",	NULL,	IDE_AFLAG_FULL_CAPS_PAGE     },
  	{ "WPI CDS-32X",		NULL,	IDE_AFLAG_FULL_CAPS_PAGE     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1762
  	/* ACER/AOpen 24X CD-ROM has the speed fields byte-swapped. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1763
  	{ "",			     "241N", IDE_AFLAG_LE_SPEED_FIELDS       },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1764
1765
1766
1767
  	/*
  	 * Some drives used by Apple don't advertise audio play
  	 * but they do support reading TOC & audio datas.
  	 */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1768
1769
1770
1771
1772
  	{ "MATSHITADVD-ROM SR-8187", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
  	{ "MATSHITADVD-ROM SR-8186", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
  	{ "MATSHITADVD-ROM SR-8176", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
  	{ "MATSHITADVD-ROM SR-8174", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
  	{ "Optiarc DVD RW AD-5200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
f3e85ee70   Bodo Eggert   ide-cd: Optiarc D...
1773
  	{ "Optiarc DVD RW AD-7200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
f20f25860   Borislav Petkov   ide-cd: temporary...
1774
  	{ "Optiarc DVD RW AD-7543A", NULL,   IDE_AFLAG_NO_AUTOCLOSE	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1775
1776
  	{ NULL, NULL, 0 }
  };
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1777
  static unsigned int ide_cd_flags(u16 *id)
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1778
1779
1780
1781
  {
  	const struct cd_list_entry *cle = ide_cd_quirks_list;
  
  	while (cle->id_model) {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1782
  		if (strcmp(cle->id_model, (char *)&id[ATA_ID_PROD]) == 0 &&
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1783
  		    (cle->id_firmware == NULL ||
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1784
  		     strstr((char *)&id[ATA_ID_FW_REV], cle->id_firmware)))
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1785
1786
1787
1788
1789
1790
  			return cle->cd_flags;
  		cle++;
  	}
  
  	return 0;
  }
e5e076a35   Borislav Petkov   ide-cd: fix remai...
1791
  static int ide_cdrom_setup(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1792
  {
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1793
1794
  	struct cdrom_info *cd = drive->driver_data;
  	struct cdrom_device_info *cdi = &cd->devinfo;
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1795
1796
  	u16 *id = drive->id;
  	char *fw_rev = (char *)&id[ATA_ID_FW_REV];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1797
1798
1799
1800
  	int nslots;
  
  	blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
  	blk_queue_dma_alignment(drive->queue, 31);
e5318b531   FUJITA Tomonori   ide: use the dma ...
1801
  	blk_queue_update_dma_pad(drive->queue, 15);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1802
1803
1804
1805
1806
  	drive->queue->unplug_delay = (1 * HZ) / 1000;
  	if (!drive->queue->unplug_delay)
  		drive->queue->unplug_delay = 1;
  
  	drive->special.all	= 0;
570f89ea5   Borislav Petkov   ide-cd: convert t...
1807
  	drive->atapi_flags = IDE_AFLAG_MEDIA_CHANGED | IDE_AFLAG_NO_EJECT |
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1808
  		       ide_cd_flags(id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1809

4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1810
  	if ((id[ATA_ID_CONFIG] & 0x0060) == 0x20)
570f89ea5   Borislav Petkov   ide-cd: convert t...
1811
  		drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1812

570f89ea5   Borislav Petkov   ide-cd: convert t...
1813
  	if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) &&
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1814
  	    fw_rev[4] == '1' && fw_rev[6] <= '2')
570f89ea5   Borislav Petkov   ide-cd: convert t...
1815
1816
1817
  		drive->atapi_flags |= (IDE_AFLAG_TOCTRACKS_AS_BCD |
  				     IDE_AFLAG_TOCADDR_AS_BCD);
  	else if ((drive->atapi_flags & IDE_AFLAG_VERTOS_600_ESD) &&
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1818
  		 fw_rev[4] == '1' && fw_rev[6] <= '2')
570f89ea5   Borislav Petkov   ide-cd: convert t...
1819
1820
  		drive->atapi_flags |= IDE_AFLAG_TOCTRACKS_AS_BCD;
  	else if (drive->atapi_flags & IDE_AFLAG_SANYO_3CD)
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1821
1822
  		/* 3 => use CD in slot 0 */
  		cdi->sanyo_slot = 3;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1823

9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1824
  	nslots = ide_cdrom_probe_capabilities(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1825

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1826
  	/* set correct block size */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1827
  	blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
cc12175ff   Bartlomiej Zolnierkiewicz   ide: remove obsol...
1828
  	drive->dsc_overlap = (drive->next != drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1829
1830
  
  	if (ide_cdrom_register(drive, nslots)) {
83c8565dc   Borislav Petkov   ide-cd: shorten l...
1831
1832
1833
  		printk(KERN_ERR "%s: %s failed to register device with the"
  				" cdrom driver.
  ", drive->name, __func__);
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1834
  		cd->devinfo.handle = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1835
1836
  		return 1;
  	}
1e874f448   Bartlomiej Zolnierkiewicz   ide: call ide_pro...
1837
1838
  
  	ide_proc_register_driver(drive, cd->driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1839
1840
  	return 0;
  }
4031bbe4b   Russell King   [PATCH] Add ide_b...
1841
  static void ide_cd_remove(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1842
1843
  {
  	struct cdrom_info *info = drive->driver_data;
7662d046d   Bartlomiej Zolnierkiewicz   ide: move IDE set...
1844
  	ide_proc_unregister_driver(drive, info->driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1845
1846
1847
1848
  
  	del_gendisk(info->disk);
  
  	ide_cd_put(info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1849
1850
1851
1852
1853
1854
1855
1856
  }
  
  static void ide_cd_release(struct kref *kref)
  {
  	struct cdrom_info *info = to_ide_cd(kref);
  	struct cdrom_device_info *devinfo = &info->devinfo;
  	ide_drive_t *drive = info->drive;
  	struct gendisk *g = info->disk;
6044ec888   Jesper Juhl   [PATCH] kfree cle...
1857
  	kfree(info->toc);
0a0c4114d   Akinobu Mita   cdrom: make unreg...
1858
1859
  	if (devinfo->handle == drive)
  		unregister_cdrom(devinfo);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1860
1861
1862
1863
1864
1865
1866
  	drive->dsc_overlap = 0;
  	drive->driver_data = NULL;
  	blk_queue_prep_rq(drive->queue, NULL);
  	g->private_data = NULL;
  	put_disk(g);
  	kfree(info);
  }
4031bbe4b   Russell King   [PATCH] Add ide_b...
1867
  static int ide_cd_probe(ide_drive_t *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1868

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1869
  static ide_driver_t ide_cdrom_driver = {
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
1870
  	.gen_driver = {
4ef3b8f4a   Laurent Riffard   [PATCH] ide: remo...
1871
  		.owner		= THIS_MODULE,
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
1872
1873
  		.name		= "ide-cdrom",
  		.bus		= &ide_bus_type,
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
1874
  	},
4031bbe4b   Russell King   [PATCH] Add ide_b...
1875
1876
  	.probe			= ide_cd_probe,
  	.remove			= ide_cd_remove,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1877
1878
  	.version		= IDECD_VERSION,
  	.media			= ide_cdrom,
99384aeaf   Borislav Petkov   ide-cd: mv ide_do...
1879
  	.do_request		= ide_cd_do_request,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1880
1881
  	.end_request		= ide_end_request,
  	.error			= __ide_error,
7662d046d   Bartlomiej Zolnierkiewicz   ide: move IDE set...
1882
  #ifdef CONFIG_IDE_PROC_FS
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1883
  	.proc			= idecd_proc,
8185d5aa9   Bartlomiej Zolnierkiewicz   ide: /proc/ide/hd...
1884
  	.settings		= idecd_settings,
7662d046d   Bartlomiej Zolnierkiewicz   ide: move IDE set...
1885
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1886
  };
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1887
  static int idecd_open(struct inode *inode, struct file *file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1888
1889
1890
  {
  	struct gendisk *disk = inode->i_bdev->bd_disk;
  	struct cdrom_info *info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1891
  	int rc = -ENOMEM;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1892
1893
  	info = ide_cd_get(disk);
  	if (!info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1894
  		return -ENXIO;
968c49641   Borislav Petkov   ide-cd: remove th...
1895
  	rc = cdrom_open(&info->devinfo, inode, file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1896
1897
1898
1899
1900
1901
  
  	if (rc < 0)
  		ide_cd_put(info);
  
  	return rc;
  }
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1902
  static int idecd_release(struct inode *inode, struct file *file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1903
1904
1905
  {
  	struct gendisk *disk = inode->i_bdev->bd_disk;
  	struct cdrom_info *info = ide_cd_g(disk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1906

9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1907
  	cdrom_release(&info->devinfo, file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1908
1909
1910
1911
1912
  
  	ide_cd_put(info);
  
  	return 0;
  }
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
  static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg)
  {
  	struct packet_command cgc;
  	char buffer[16];
  	int stat;
  	char spindown;
  
  	if (copy_from_user(&spindown, (void __user *)arg, sizeof(char)))
  		return -EFAULT;
  
  	init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
  
  	stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
  	if (stat)
  		return stat;
  
  	buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
  	return cdrom_mode_select(cdi, &cgc);
  }
  
  static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
  {
  	struct packet_command cgc;
  	char buffer[16];
  	int stat;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1938
  	char spindown;
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1939
1940
1941
1942
1943
1944
1945
1946
  
  	init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
  
  	stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
  	if (stat)
  		return stat;
  
  	spindown = buffer[11] & 0x0f;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1947
  	if (copy_to_user((void __user *)arg, &spindown, sizeof(char)))
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1948
1949
1950
  		return -EFAULT;
  	return 0;
  }
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1951
  static int idecd_ioctl(struct inode *inode, struct file *file,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1952
1953
1954
1955
1956
  			unsigned int cmd, unsigned long arg)
  {
  	struct block_device *bdev = inode->i_bdev;
  	struct cdrom_info *info = ide_cd_g(bdev->bd_disk);
  	int err;
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1957
  	switch (cmd) {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1958
  	case CDROMSETSPINDOWN:
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1959
  		return idecd_set_spindown(&info->devinfo, arg);
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1960
  	case CDROMGETSPINDOWN:
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1961
1962
1963
  		return idecd_get_spindown(&info->devinfo, arg);
  	default:
  		break;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1964
  	}
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1965
1966
  
  	err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
  	if (err == -EINVAL)
  		err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
  
  	return err;
  }
  
  static int idecd_media_changed(struct gendisk *disk)
  {
  	struct cdrom_info *info = ide_cd_g(disk);
  	return cdrom_media_changed(&info->devinfo);
  }
  
  static int idecd_revalidate_disk(struct gendisk *disk)
  {
  	struct cdrom_info *info = ide_cd_g(disk);
  	struct request_sense sense;
139c829d9   Bartlomiej Zolnierkiewicz   ide-cd: rename cd...
1983
1984
  
  	ide_cd_read_toc(info->drive, &sense);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1985
1986
1987
1988
  	return  0;
  }
  
  static struct block_device_operations idecd_ops = {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1989
1990
1991
1992
1993
1994
  	.owner			= THIS_MODULE,
  	.open			= idecd_open,
  	.release		= idecd_release,
  	.ioctl			= idecd_ioctl,
  	.media_changed		= idecd_media_changed,
  	.revalidate_disk	= idecd_revalidate_disk
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1995
  };
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1996
  /* module options */
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1997
  static char *ignore;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1998
1999
2000
  
  module_param(ignore, charp, 0400);
  MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
4031bbe4b   Russell King   [PATCH] Add ide_b...
2001
  static int ide_cd_probe(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2002
2003
2004
2005
2006
2007
2008
  {
  	struct cdrom_info *info;
  	struct gendisk *g;
  	struct request_sense sense;
  
  	if (!strstr("ide-cdrom", drive->driver_req))
  		goto failed;
2a924662b   Bartlomiej Zolnierkiewicz   ide: remove needl...
2009

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2010
2011
  	if (drive->media != ide_cdrom && drive->media != ide_optical)
  		goto failed;
2a924662b   Bartlomiej Zolnierkiewicz   ide: remove needl...
2012

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2013
2014
2015
  	/* skip drives that we were told to ignore */
  	if (ignore != NULL) {
  		if (strstr(ignore, drive->name)) {
83c8565dc   Borislav Petkov   ide-cd: shorten l...
2016
2017
2018
  			printk(KERN_INFO "ide-cd: ignoring drive %s
  ",
  					 drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2019
2020
2021
  			goto failed;
  		}
  	}
f5e3c2faa   Deepak Saxena   [PATCH] ide: kmal...
2022
  	info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2023
  	if (info == NULL) {
83c8565dc   Borislav Petkov   ide-cd: shorten l...
2024
2025
2026
  		printk(KERN_ERR "%s: Can't allocate a cdrom structure
  ",
  				drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2027
2028
2029
2030
2031
2032
2033
2034
  		goto failed;
  	}
  
  	g = alloc_disk(1 << PARTN_BITS);
  	if (!g)
  		goto out_free_cd;
  
  	ide_init_disk(g, drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2035
2036
2037
2038
2039
2040
2041
2042
2043
  	kref_init(&info->kref);
  
  	info->drive = drive;
  	info->driver = &ide_cdrom_driver;
  	info->disk = g;
  
  	g->private_data = &info->driver;
  
  	drive->driver_data = info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2044
  	g->minors = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2045
2046
2047
  	g->driverfs_dev = &drive->gendev;
  	g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
  	if (ide_cdrom_setup(drive)) {
05017db3b   Bartlomiej Zolnierkiewicz   ide-cd: use ide_c...
2048
  		ide_cd_release(&info->kref);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2049
2050
  		goto failed;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2051

139c829d9   Bartlomiej Zolnierkiewicz   ide-cd: rename cd...
2052
  	ide_cd_read_toc(drive, &sense);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2053
2054
2055
2056
  	g->fops = &idecd_ops;
  	g->flags |= GENHD_FL_REMOVABLE;
  	add_disk(g);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2057
2058
2059
  out_free_cd:
  	kfree(info);
  failed:
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
2060
  	return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2061
2062
2063
2064
  }
  
  static void __exit ide_cdrom_exit(void)
  {
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
2065
  	driver_unregister(&ide_cdrom_driver.gen_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2066
  }
17514e8a6   Bartlomiej Zolnierkiewicz   [PATCH] ide: add ...
2067
2068
  
  static int __init ide_cdrom_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2069
  {
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
2070
  	return driver_register(&ide_cdrom_driver.gen_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2071
  }
263756ec2   Kay Sievers   [PATCH] ide: MODA...
2072
  MODULE_ALIAS("ide:*m-cdrom*");
972560fb9   Bartlomiej Zolnierkiewicz   ide-cd: move VERB...
2073
  MODULE_ALIAS("ide-cd");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2074
2075
2076
  module_init(ide_cdrom_init);
  module_exit(ide_cdrom_exit);
  MODULE_LICENSE("GPL");