Blame view

drivers/ide/ide-cd.c 45.9 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
   * 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>
14fa91ccb   Bartlomiej Zolnierkiewicz   ide-cd: unify tra...
7
   * Copyright (C) 2005, 2007-2009  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
   * See Documentation/cdrom/ide-cd for usage information.
   *
   * Suggestions are welcome. Patches that work are more welcome though. ;-)
116e690f4   Bartlomiej Zolnierkiewicz   ide-cd: remove de...
15
16
17
   *
   * Documentation:
   *	Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
   *
03553353e   Bartlomiej Zolnierkiewicz   ide-cd: move hist...
19
20
21
   * For historical changelog please see:
   *	Documentation/ide/ChangeLog.ide-cd.1994-2004
   */
fc8323f79   Borislav Petkov   ide-cd: convert d...
22
23
  #define DRV_NAME "ide-cd"
  #define PFX DRV_NAME ": "
3bb4663bd   Bartlomiej Zolnierkiewicz   ide-cd: update dr...
24
  #define IDECD_VERSION "5.00"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
28
29
30
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/delay.h>
  #include <linux/timer.h>
6d703a81a   Alexey Dobriyan   ide: convert to -...
31
  #include <linux/seq_file.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
34
35
36
37
  #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
  #include <linux/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
  #include <asm/byteorder.h>
9aba468e4   Borislav Petkov   ide-cd: include p...
46
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47
48
49
  #include <asm/unaligned.h>
  
  #include "ide-cd.h"
2a48fc0ab   Arnd Bergmann   block: autoconver...
50
  static DEFINE_MUTEX(ide_cd_mutex);
cf8b8975c   Arjan van de Ven   [PATCH] sem2mutex...
51
  static DEFINE_MUTEX(idecd_ref_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52

8fed43684   Bartlomiej Zolnierkiewicz   ide: fix refcount...
53
  static void ide_cd_release(struct device *);
08da591e1   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
54

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
  static struct cdrom_info *ide_cd_get(struct gendisk *disk)
  {
  	struct cdrom_info *cd = NULL;
cf8b8975c   Arjan van de Ven   [PATCH] sem2mutex...
58
  	mutex_lock(&idecd_ref_mutex);
5aeddf907   Borislav Petkov   ide: unify conver...
59
  	cd = ide_drv_g(disk, cdrom_info);
08da591e1   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
60
  	if (cd) {
d3e33ff59   Bartlomiej Zolnierkiewicz   ide: fix regressi...
61
  		if (ide_device_get(cd->drive))
08da591e1   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
62
  			cd = NULL;
d3e33ff59   Bartlomiej Zolnierkiewicz   ide: fix regressi...
63
  		else
8fed43684   Bartlomiej Zolnierkiewicz   ide: fix refcount...
64
  			get_device(&cd->dev);
d3e33ff59   Bartlomiej Zolnierkiewicz   ide: fix regressi...
65

08da591e1   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
66
  	}
cf8b8975c   Arjan van de Ven   [PATCH] sem2mutex...
67
  	mutex_unlock(&idecd_ref_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
  	return cd;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
  static void ide_cd_put(struct cdrom_info *cd)
  {
d3e33ff59   Bartlomiej Zolnierkiewicz   ide: fix regressi...
72
  	ide_drive_t *drive = cd->drive;
cf8b8975c   Arjan van de Ven   [PATCH] sem2mutex...
73
  	mutex_lock(&idecd_ref_mutex);
8fed43684   Bartlomiej Zolnierkiewicz   ide: fix refcount...
74
  	put_device(&cd->dev);
d3e33ff59   Bartlomiej Zolnierkiewicz   ide: fix regressi...
75
  	ide_device_put(drive);
cf8b8975c   Arjan van de Ven   [PATCH] sem2mutex...
76
  	mutex_unlock(&idecd_ref_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
78
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
80
   * Generic packet command support and error handling routines.
   */
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
81
  /* Mark that we've seen a media change and invalidate our internal buffers. */
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
82
  static void cdrom_saw_media_change(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
  {
fe11edfaa   Bartlomiej Zolnierkiewicz   ide: IDE_AFLAG_ME...
84
  	drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
570f89ea5   Borislav Petkov   ide-cd: convert t...
85
  	drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
  }
239f7e253   Borislav Petkov   ide-cd: use whole...
87
  static int cdrom_log_sense(ide_drive_t *drive, struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
  {
239f7e253   Borislav Petkov   ide-cd: use whole...
89
  	struct request_sense *sense = &drive->sense_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
  	int log = 0;
4aff5e233   Jens Axboe   [PATCH] Split str...
91
  	if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
  		return 0;
239f7e253   Borislav Petkov   ide-cd: use whole...
93
  	ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
  	switch (sense->sense_key) {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
95
96
97
98
99
  	case NO_SENSE:
  	case RECOVERED_ERROR:
  		break;
  	case NOT_READY:
  		/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
100
101
  		 * don't care about tray state messages for e.g. capacity
  		 * commands or in-progress or becoming ready
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
102
103
  		 */
  		if (sense->asc == 0x3a || sense->asc == 0x04)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
  			break;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
105
106
107
108
  		log = 1;
  		break;
  	case ILLEGAL_REQUEST:
  		/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
109
110
  		 * 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...
111
112
  		 */
  		if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
  			break;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
114
115
116
117
  		log = 1;
  		break;
  	case UNIT_ATTENTION:
  		/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
118
119
120
  		 * 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...
121
122
123
124
125
126
  		 */
  		cdrom_saw_media_change(drive);
  		break;
  	default:
  		log = 1;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
  	}
  	return log;
  }
e5e076a35   Borislav Petkov   ide-cd: fix remai...
130
  static void cdrom_analyze_sense_data(ide_drive_t *drive,
239f7e253   Borislav Petkov   ide-cd: use whole...
131
  				     struct request *failed_command)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
  {
239f7e253   Borislav Petkov   ide-cd: use whole...
133
134
  	struct request_sense *sense = &drive->sense_data;
  	struct cdrom_info *info = drive->driver_data;
dbe217af3   Alan Cox   [PATCH] IDE CD en...
135
136
  	unsigned long sector;
  	unsigned long bio_sectors;
dbe217af3   Alan Cox   [PATCH] IDE CD en...
137

088b1b886   Borislav Petkov   ide: improve debu...
138
139
  	ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x",
  				     sense->error_code, sense->sense_key);
fc8323f79   Borislav Petkov   ide-cd: convert d...
140
141
  
  	if (failed_command)
088b1b886   Borislav Petkov   ide: improve debu...
142
143
  		ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x",
  					     failed_command->cmd[0]);
fc8323f79   Borislav Petkov   ide-cd: convert d...
144

239f7e253   Borislav Petkov   ide-cd: use whole...
145
  	if (!cdrom_log_sense(drive, failed_command))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
147
148
  		return;
  
  	/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
149
150
151
  	 * 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
152
153
154
155
  	 */
  	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...
156
157
  	/* current error */
  	if (sense->error_code == 0x70) {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
158
  		switch (sense->sense_key) {
dbe217af3   Alan Cox   [PATCH] IDE CD en...
159
160
161
162
163
164
  		case MEDIUM_ERROR:
  		case VOLUME_OVERFLOW:
  		case ILLEGAL_REQUEST:
  			if (!sense->valid)
  				break;
  			if (failed_command == NULL ||
33659ebba   Christoph Hellwig   block: remove wra...
165
  			    failed_command->cmd_type != REQ_TYPE_FS)
dbe217af3   Alan Cox   [PATCH] IDE CD en...
166
167
168
169
170
  				break;
  			sector = (sense->information[0] << 24) |
  				 (sense->information[1] << 16) |
  				 (sense->information[2] <<  8) |
  				 (sense->information[3]);
e1defc4ff   Martin K. Petersen   block: Do away wi...
171
  			if (queue_logical_block_size(drive->queue) == 2048)
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
172
173
  				/* device sector size is 2K */
  				sector <<= 2;
eee49298d   Roel Kluin   ide-cd: clean up ...
174
175
  
  			bio_sectors = max(bio_sectors(failed_command->bio), 4U);
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
176
  			sector &= ~(bio_sectors - 1);
dbe217af3   Alan Cox   [PATCH] IDE CD en...
177

d3dd7107f   Bartlomiej Zolnierkiewicz   ide-cd: document ...
178
179
180
181
182
183
184
185
  			/*
  			 * The SCSI specification allows for the value
  			 * returned by READ CAPACITY to be up to 75 2K
  			 * sectors past the last readable block.
  			 * Therefore, if we hit a medium error within the
  			 * last 75 2K sectors, we decrease the saved size
  			 * value.
  			 */
dbe217af3   Alan Cox   [PATCH] IDE CD en...
186
  			if (sector < get_capacity(info->disk) &&
e5e076a35   Borislav Petkov   ide-cd: fix remai...
187
  			    drive->probed_capacity - sector < 4 * 75)
dbe217af3   Alan Cox   [PATCH] IDE CD en...
188
  				set_capacity(info->disk, sector);
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
189
190
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191

972560fb9   Bartlomiej Zolnierkiewicz   ide-cd: move VERB...
192
  	ide_cd_log_error(drive->name, failed_command, sense);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
  }
299c4852f   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
194
195
196
  static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
  {
  	/*
1f181d2b1   Tejun Heo   ide-cd: don't abu...
197
  	 * For REQ_TYPE_SENSE, "rq->special" points to the original
02e7cf8f8   Tejun Heo   ide-cd,atapi: use...
198
199
200
  	 * failed request.  Also, the sense data should be read
  	 * directly from rq which might be different from the original
  	 * sense buffer if it got copied during mapping.
299c4852f   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
201
  	 */
1f181d2b1   Tejun Heo   ide-cd: don't abu...
202
  	struct request *failed = (struct request *)rq->special;
02e7cf8f8   Tejun Heo   ide-cd,atapi: use...
203
  	void *sense = bio_data(rq->bio);
299c4852f   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
204
205
206
  
  	if (failed) {
  		if (failed->sense) {
c457ce874   Borislav Petkov   ide-cd: convert t...
207
208
209
210
211
212
  			/*
  			 * Sense is always read into drive->sense_data.
  			 * Copy back if the failed request has its
  			 * sense pointer set.
  			 */
  			memcpy(failed->sense, sense, 18);
299c4852f   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
213
214
  			failed->sense_len = rq->sense_len;
  		}
239f7e253   Borislav Petkov   ide-cd: use whole...
215
  		cdrom_analyze_sense_data(drive, failed);
299c4852f   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
216
217
218
219
  
  		if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed)))
  			BUG();
  	} else
239f7e253   Borislav Petkov   ide-cd: use whole...
220
  		cdrom_analyze_sense_data(drive, NULL);
299c4852f   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
221
  }
805ec58ad   Borislav Petkov   ide-cd: carve out...
222

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
223
  /*
805ec58ad   Borislav Petkov   ide-cd: carve out...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
   * Allow the drive 5 seconds to recover; some devices will return NOT_READY
   * while flushing data from cache.
   *
   * returns: 0 failed (write timeout expired)
   *	    1 success
   */
  static int ide_cd_breathe(ide_drive_t *drive, struct request *rq)
  {
  
  	struct cdrom_info *info = drive->driver_data;
  
  	if (!rq->errors)
  		info->write_timeout = jiffies +	ATAPI_WAIT_WRITE_BUSY;
  
  	rq->errors = 1;
  
  	if (time_after(jiffies, info->write_timeout))
  		return 0;
  	else {
805ec58ad   Borislav Petkov   ide-cd: carve out...
243
  		/*
0a41e90bb   Jens Axboe   ide-cd: convert t...
244
  		 * take a breather
805ec58ad   Borislav Petkov   ide-cd: carve out...
245
  		 */
0a41e90bb   Jens Axboe   ide-cd: convert t...
246
  		blk_delay_queue(drive->queue, 1);
805ec58ad   Borislav Petkov   ide-cd: carve out...
247
248
249
250
251
  		return 1;
  	}
  }
  
  /**
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
252
253
   * Returns:
   * 0: if the request should be continued.
8a1169748   Bartlomiej Zolnierkiewicz   ide-cd: unify cdr...
254
255
   * 1: if the request will be going through error recovery.
   * 2: if the request should be ended.
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
256
   */
8e59bfde3   Borislav Petkov   ide-cd: move stat...
257
  static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
258
  {
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
259
  	ide_hwif_t *hwif = drive->hwif;
b65fac32c   Bartlomiej Zolnierkiewicz   ide: merge ide_hw...
260
  	struct request *rq = hwif->rq;
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
261
  	int err, sense_key, do_end_request = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
263
  	/* get the IDE error register */
64a57fe43   Bartlomiej Zolnierkiewicz   ide: add ide_read...
264
  	err = ide_read_error(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  	sense_key = err >> 4;
98036abf3   Borislav Petkov   ide-cd: update de...
266
267
268
  	ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, rq->cmd_type: 0x%x, err: 0x%x, "
  				  "stat 0x%x",
  				  rq->cmd[0], rq->cmd_type, err, stat);
fc8323f79   Borislav Petkov   ide-cd: convert d...
269

33659ebba   Christoph Hellwig   block: remove wra...
270
  	if (rq->cmd_type == REQ_TYPE_SENSE) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
271
272
273
274
275
  		/*
  		 * 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...
276
  		rq->cmd_flags |= REQ_FAILED;
8a1169748   Bartlomiej Zolnierkiewicz   ide-cd: unify cdr...
277
  		return 2;
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
278
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279

674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
280
  	/* if we have an error, pass CHECK_CONDITION as the SCSI status byte */
33659ebba   Christoph Hellwig   block: remove wra...
281
  	if (rq->cmd_type == REQ_TYPE_BLOCK_PC && !rq->errors)
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
282
  		rq->errors = SAM_STAT_CHECK_CONDITION;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283

674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
284
285
  	if (blk_noretry_request(rq))
  		do_end_request = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286

674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
287
288
  	switch (sense_key) {
  	case NOT_READY:
33659ebba   Christoph Hellwig   block: remove wra...
289
  		if (rq->cmd_type == REQ_TYPE_FS && rq_data_dir(rq) == WRITE) {
3c8a48e9a   Borislav Petkov   ide-cd: reverse N...
290
291
292
  			if (ide_cd_breathe(drive, rq))
  				return 1;
  		} else {
e5e076a35   Borislav Petkov   ide-cd: fix remai...
293
  			cdrom_saw_media_change(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294

33659ebba   Christoph Hellwig   block: remove wra...
295
  			if (rq->cmd_type == REQ_TYPE_FS &&
4c4762d10   Christoph Hellwig   block: fix some m...
296
  			    !(rq->cmd_flags & REQ_QUIET))
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
297
298
299
  				printk(KERN_ERR PFX "%s: tray open
  ",
  					drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
  		}
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
301
302
303
304
  		do_end_request = 1;
  		break;
  	case UNIT_ATTENTION:
  		cdrom_saw_media_change(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
305

33659ebba   Christoph Hellwig   block: remove wra...
306
  		if (rq->cmd_type != REQ_TYPE_FS)
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
307
  			return 0;
1920c48d7   Bartlomiej Zolnierkiewicz   ide-cd: unify han...
308

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
309
  		/*
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
310
311
  		 * Arrange to retry the request but be sure to give up if we've
  		 * retried too many times.
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
312
  		 */
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
313
314
315
316
  		if (++rq->errors > ERROR_MAX)
  			do_end_request = 1;
  		break;
  	case ILLEGAL_REQUEST:
bbb89e3d7   Bartlomiej Zolnierkiewicz   ide-cd: unify req...
317
  		/*
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
318
319
320
321
322
  		 * 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!
bbb89e3d7   Bartlomiej Zolnierkiewicz   ide-cd: unify req...
323
  		 */
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
324
325
326
327
328
329
330
331
  		if (rq->cmd[0] == GPCMD_START_STOP_UNIT)
  			break;
  		/* fall-through */
  	case DATA_PROTECT:
  		/*
  		 * No point in retrying after an illegal request or data
  		 * protect error.
  		 */
33659ebba   Christoph Hellwig   block: remove wra...
332
  		if (!(rq->cmd_flags & REQ_QUIET))
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
333
334
335
336
337
338
339
340
  			ide_dump_status(drive, "command error", stat);
  		do_end_request = 1;
  		break;
  	case MEDIUM_ERROR:
  		/*
  		 * No point in re-trying a zillion times on a bad sector.
  		 * If we got here the error is not correctable.
  		 */
33659ebba   Christoph Hellwig   block: remove wra...
341
  		if (!(rq->cmd_flags & REQ_QUIET))
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
342
343
344
345
346
347
  			ide_dump_status(drive, "media error "
  					"(bad sector)", stat);
  		do_end_request = 1;
  		break;
  	case BLANK_CHECK:
  		/* disk appears blank? */
33659ebba   Christoph Hellwig   block: remove wra...
348
  		if (!(rq->cmd_flags & REQ_QUIET))
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
349
350
351
352
353
  			ide_dump_status(drive, "media error (blank)",
  					stat);
  		do_end_request = 1;
  		break;
  	default:
4c4762d10   Christoph Hellwig   block: fix some m...
354
  		if (rq->cmd_type != REQ_TYPE_FS)
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
355
356
357
358
359
360
361
362
  			break;
  		if (err & ~ATA_ABORTED) {
  			/* go to the default handler for other errors */
  			ide_error(drive, "cdrom_decode_status", stat);
  			return 1;
  		} else if (++rq->errors > ERROR_MAX)
  			/* we've racked up too many retries, abort */
  			do_end_request = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
363
  	}
33659ebba   Christoph Hellwig   block: remove wra...
364
  	if (rq->cmd_type != REQ_TYPE_FS) {
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
365
366
367
368
369
370
371
372
373
374
375
376
377
  		rq->cmd_flags |= REQ_FAILED;
  		do_end_request = 1;
  	}
  
  	/*
  	 * End a request through request sense analysis when we have sense data.
  	 * We need this in order to perform end of media processing.
  	 */
  	if (do_end_request)
  		goto end_request;
  
  	/* if we got a CHECK_CONDITION status, queue a request sense command */
  	if (stat & ATA_ERR)
02e7cf8f8   Tejun Heo   ide-cd,atapi: use...
378
  		return ide_queue_sense_rq(drive, NULL) ? 2 : 1;
674f0ea11   Bartlomiej Zolnierkiewicz   ide-cd: fix inten...
379
  	return 1;
bbb89e3d7   Bartlomiej Zolnierkiewicz   ide-cd: unify req...
380
  end_request:
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
381
  	if (stat & ATA_ERR) {
b65fac32c   Bartlomiej Zolnierkiewicz   ide: merge ide_hw...
382
  		hwif->rq = NULL;
02e7cf8f8   Tejun Heo   ide-cd,atapi: use...
383
  		return ide_queue_sense_rq(drive, rq) ? 2 : 1;
bbb89e3d7   Bartlomiej Zolnierkiewicz   ide-cd: unify req...
384
  	} else
8a1169748   Bartlomiej Zolnierkiewicz   ide-cd: unify cdr...
385
  		return 2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386
  }
c7ec89994   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
387
  static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
8ee69f5a8   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
388
  {
c7ec89994   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
389
  	struct request *rq = cmd->rq;
088b1b886   Borislav Petkov   ide: improve debu...
390
  	ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]);
fc8323f79   Borislav Petkov   ide-cd: convert d...
391

8ee69f5a8   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
392
393
394
395
396
  	/*
  	 * Some of the trailing request sense fields are optional,
  	 * and some drives don't send them.  Sigh.
  	 */
  	if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
59a4f6f35   Tejun Heo   ide-cd: clear sen...
397
398
  	    cmd->nleft > 0 && cmd->nleft <= 5)
  		cmd->nleft = 0;
8ee69f5a8   Bartlomiej Zolnierkiewicz   ide-cd: factor ou...
399
  }
5f828546e   FUJITA Tomonori   ide-cd: convert i...
400
401
402
403
  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
404
  {
5f828546e   FUJITA Tomonori   ide-cd: convert i...
405
406
  	struct cdrom_info *info = drive->driver_data;
  	struct request_sense local_sense;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407
  	int retries = 10;
5f828546e   FUJITA Tomonori   ide-cd: convert i...
408
  	unsigned int flags = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409

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

088b1b886   Borislav Petkov   ide: improve debu...
413
414
415
  	ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, "
  				  "cmd_flags: 0x%x",
  				  cmd[0], write, timeout, cmd_flags);
fc8323f79   Borislav Petkov   ide-cd: convert d...
416

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
417
  	/* start of retry loop */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
  	do {
5f828546e   FUJITA Tomonori   ide-cd: convert i...
419
  		struct request *rq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
  		int error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421

5f828546e   FUJITA Tomonori   ide-cd: convert i...
422
423
424
425
426
427
428
429
  		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) {
02e7cf8f8   Tejun Heo   ide-cd,atapi: use...
430
431
432
433
434
435
  			error = blk_rq_map_kern(drive->queue, rq, buffer,
  						*bufflen, GFP_NOIO);
  			if (error) {
  				blk_put_request(rq);
  				return error;
  			}
5f828546e   FUJITA Tomonori   ide-cd: convert i...
436
437
438
439
440
  		}
  
  		error = blk_execute_rq(drive->queue, info->disk, rq, 0);
  
  		if (buffer)
c3a4d78c5   Tejun Heo   block: add rq->re...
441
  			*bufflen = rq->resid_len;
5f828546e   FUJITA Tomonori   ide-cd: convert i...
442
443
444
  
  		flags = rq->cmd_flags;
  		blk_put_request(rq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
446
447
448
449
  		/*
  		 * FIXME: we should probably abort/retry or something in case of
  		 * failure.
  		 */
5f828546e   FUJITA Tomonori   ide-cd: convert i...
450
  		if (flags & REQ_FAILED) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
451
452
453
454
  			/*
  			 * 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...
455
  			struct request_sense *reqbuf = sense;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
457
458
459
460
  
  			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...
461
462
463
464
465
  				/*
  				 * 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
466
467
  				ssleep(2);
  			} else {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
468
  				/* otherwise, don't retry */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469
470
471
472
  				retries = 0;
  			}
  			--retries;
  		}
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
473
  		/* end of retry loop */
5f828546e   FUJITA Tomonori   ide-cd: convert i...
474
  	} while ((flags & REQ_FAILED) && retries >= 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
476
  	/* return an error if the command failed */
5f828546e   FUJITA Tomonori   ide-cd: convert i...
477
  	return (flags & REQ_FAILED) ? -EIO : 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
478
  }
110712828   Borislav Petkov   ide-cd: Do not ac...
479
480
481
482
  /*
   * returns true if rq has been completed
   */
  static bool ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
483
484
485
486
487
  {
  	unsigned int nr_bytes = cmd->nbytes - cmd->nleft;
  
  	if (cmd->tf_flags & IDE_TFLAG_WRITE)
  		nr_bytes -= cmd->last_xfer_len;
110712828   Borislav Petkov   ide-cd: Do not ac...
488
  	if (nr_bytes > 0) {
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
489
  		ide_complete_rq(drive, 0, nr_bytes);
110712828   Borislav Petkov   ide-cd: Do not ac...
490
491
492
493
  		return true;
  	}
  
  	return false;
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
494
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
496
  static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
  {
23579a2a1   Bartlomiej Zolnierkiewicz   ide: remove IDE_*...
497
  	ide_hwif_t *hwif = drive->hwif;
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
498
  	struct ide_cmd *cmd = &hwif->cmd;
b65fac32c   Bartlomiej Zolnierkiewicz   ide: merge ide_hw...
499
  	struct request *rq = hwif->rq;
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
500
  	ide_expiry_t *expiry = NULL;
8e59bfde3   Borislav Petkov   ide-cd: move stat...
501
  	int dma_error = 0, dma, thislen, uptodate = 0;
34b7d2c95   Tejun Heo   ide: cleanup rq->...
502
  	int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0;
33659ebba   Christoph Hellwig   block: remove wra...
503
  	int sense = (rq->cmd_type == REQ_TYPE_SENSE);
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
504
  	unsigned int timeout;
1823649b5   Bartlomiej Zolnierkiewicz   ide: add ide_read...
505
  	u16 len;
8e59bfde3   Borislav Petkov   ide-cd: move stat...
506
  	u8 ireason, stat;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507

98036abf3   Borislav Petkov   ide-cd: update de...
508
  	ide_debug_log(IDE_DBG_PC, "cmd: 0x%x, write: 0x%x", rq->cmd[0], write);
fc8323f79   Borislav Petkov   ide-cd: convert d...
509

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
510
  	/* check for errors */
12469ac0c   Borislav Petkov   ide-cd: move cdro...
511
  	dma = drive->dma;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
  	if (dma) {
12469ac0c   Borislav Petkov   ide-cd: move cdro...
513
  		drive->dma = 0;
88b4132e1   Bartlomiej Zolnierkiewicz   ide: set/clear dr...
514
  		drive->waiting_for_dma = 0;
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
515
  		dma_error = hwif->dma_ops->dma_end(drive);
f094d4d83   Bartlomiej Zolnierkiewicz   ide: sanitize ide...
516
  		ide_dma_unmap_sg(drive, cmd);
eba15fba1   Bartlomiej Zolnierkiewicz   ide-cd: fix DMA e...
517
  		if (dma_error) {
fc8323f79   Borislav Petkov   ide-cd: convert d...
518
519
  			printk(KERN_ERR PFX "%s: DMA %s error
  ", drive->name,
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
520
  					write ? "write" : "read");
eba15fba1   Bartlomiej Zolnierkiewicz   ide-cd: fix DMA e...
521
522
  			ide_dma_off(drive);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
  	}
8e59bfde3   Borislav Petkov   ide-cd: move stat...
524
525
526
527
528
529
530
531
532
533
  	/* check status */
  	stat = hwif->tp_ops->read_status(hwif);
  
  	if (!OK_STAT(stat, 0, BAD_R_STAT)) {
  		rc = cdrom_decode_status(drive, stat);
  		if (rc) {
  			if (rc == 2)
  				goto out_end;
  			return ide_stopped;
  		}
8a1169748   Bartlomiej Zolnierkiewicz   ide-cd: unify cdr...
534
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
536
  	/* using dma, transfer is complete now */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537
  	if (dma) {
eba15fba1   Bartlomiej Zolnierkiewicz   ide-cd: fix DMA e...
538
  		if (dma_error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
  			return ide_error(drive, "dma error", stat);
4a3d8cf48   Bartlomiej Zolnierkiewicz   ide-cd: use commo...
540
  		uptodate = 1;
984c5e597   Bartlomiej Zolnierkiewicz   ide-cd: move sett...
541
  		goto out_end;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
  	}
1823649b5   Bartlomiej Zolnierkiewicz   ide: add ide_read...
543
  	ide_read_bcount_and_ireason(drive, &len, &ireason);
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
544

33659ebba   Christoph Hellwig   block: remove wra...
545
  	thislen = (rq->cmd_type == REQ_TYPE_FS) ? len : cmd->nleft;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
546
547
  	if (thislen > len)
  		thislen = len;
088b1b886   Borislav Petkov   ide: improve debu...
548
549
  	ide_debug_log(IDE_DBG_PC, "DRQ: stat: 0x%x, thislen: %d",
  				  stat, thislen);
fc8323f79   Borislav Petkov   ide-cd: convert d...
550

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
551
  	/* If DRQ is clear, the command has completed. */
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
552
  	if ((stat & ATA_DRQ) == 0) {
33659ebba   Christoph Hellwig   block: remove wra...
553
  		if (rq->cmd_type == REQ_TYPE_FS) {
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
554
555
556
557
558
  			/*
  			 * If we're not done reading/writing, complain.
  			 * Otherwise, complete the command normally.
  			 */
  			uptodate = 1;
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
559
  			if (cmd->nleft > 0) {
fc8323f79   Borislav Petkov   ide-cd: convert d...
560
  				printk(KERN_ERR PFX "%s: %s: data underrun "
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
561
562
563
  					"(%u bytes)
  ", drive->name, __func__,
  					cmd->nleft);
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
564
565
566
567
  				if (!write)
  					rq->cmd_flags |= REQ_FAILED;
  				uptodate = 0;
  			}
33659ebba   Christoph Hellwig   block: remove wra...
568
  		} else if (rq->cmd_type != REQ_TYPE_BLOCK_PC) {
c7ec89994   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
569
  			ide_cd_request_sense_fixup(drive, cmd);
9c72ebef5   Borislav Petkov   ide-cd: handle fr...
570

c7ec89994   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
571
  			uptodate = cmd->nleft ? 0 : 1;
9c72ebef5   Borislav Petkov   ide-cd: handle fr...
572
573
574
575
576
577
578
579
580
581
582
  
  			/*
  			 * suck out the remaining bytes from the drive in an
  			 * attempt to complete the data xfer. (see BZ#13399)
  			 */
  			if (!(stat & ATA_ERR) && !uptodate && thislen) {
  				ide_pio_bytes(drive, cmd, write, thislen);
  				uptodate = cmd->nleft ? 0 : 1;
  			}
  
  			if (!uptodate)
984c5e597   Bartlomiej Zolnierkiewicz   ide-cd: move sett...
583
  				rq->cmd_flags |= REQ_FAILED;
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
584
  		}
984c5e597   Bartlomiej Zolnierkiewicz   ide-cd: move sett...
585
  		goto out_end;
aaa04c28c   Kiyoshi Ueda   blk_end_request: ...
586
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587

103f7033b   Borislav Petkov   ide: unify interr...
588
  	rc = ide_check_ireason(drive, rq, len, ireason, write);
8a1169748   Bartlomiej Zolnierkiewicz   ide-cd: unify cdr...
589
590
  	if (rc)
  		goto out_end;
0041e7c6c   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
591

06a449e30   Bartlomiej Zolnierkiewicz   ide-cd: fix non-S...
592
  	cmd->last_xfer_len = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593

088b1b886   Borislav Petkov   ide: improve debu...
594
595
596
  	ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, "
  				  "ireason: 0x%x",
  				  rq->cmd_type, ireason);
fc8323f79   Borislav Petkov   ide-cd: convert d...
597

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
598
  	/* transfer data */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
599
  	while (thislen > 0) {
c7ec89994   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
600
  		int blen = min_t(int, thislen, cmd->nleft);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
601

14fa91ccb   Bartlomiej Zolnierkiewicz   ide-cd: unify tra...
602
  		if (cmd->nleft == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
603
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604

c7ec89994   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
605
606
  		ide_pio_bytes(drive, cmd, write, blen);
  		cmd->last_xfer_len += blen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
608
609
  
  		thislen -= blen;
  		len -= blen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
610

8a1169748   Bartlomiej Zolnierkiewicz   ide-cd: unify cdr...
611
  		if (sense && write == 0)
bcd88ac3b   Andreas Schwab   ide-cd: fix CD/DV...
612
  			rq->sense_len += blen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613
  	}
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
614
  	/* pad, if necessary */
14fa91ccb   Bartlomiej Zolnierkiewicz   ide-cd: unify tra...
615
  	if (len > 0) {
33659ebba   Christoph Hellwig   block: remove wra...
616
  		if (rq->cmd_type != REQ_TYPE_FS || write == 0)
14fa91ccb   Bartlomiej Zolnierkiewicz   ide-cd: unify tra...
617
618
619
620
621
622
623
624
  			ide_pad_transfer(drive, write, len);
  		else {
  			printk(KERN_ERR PFX "%s: confused, missing data
  ",
  				drive->name);
  			blk_dump_rq_flags(rq, "cdrom_newpc_intr");
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
625

33659ebba   Christoph Hellwig   block: remove wra...
626
  	if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
627
  		timeout = rq->timeout;
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
628
629
  	} else {
  		timeout = ATAPI_WAIT_PC;
33659ebba   Christoph Hellwig   block: remove wra...
630
  		if (rq->cmd_type != REQ_TYPE_FS)
4cad085ef   Borislav Petkov   ide-cd: move cdro...
631
  			expiry = ide_cd_expiry;
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
632
  	}
60c0cd02b   Bartlomiej Zolnierkiewicz   ide: set hwif->ex...
633
634
  	hwif->expiry = expiry;
  	ide_set_handler(drive, cdrom_newpc_intr, timeout);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
635
  	return ide_started;
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
636

984c5e597   Bartlomiej Zolnierkiewicz   ide-cd: move sett...
637
  out_end:
33659ebba   Christoph Hellwig   block: remove wra...
638
  	if (rq->cmd_type == REQ_TYPE_BLOCK_PC && rc == 0) {
5f49f6317   Tejun Heo   block: set rq->re...
639
  		rq->resid_len = 0;
34b7d2c95   Tejun Heo   ide: cleanup rq->...
640
  		blk_end_request_all(rq, 0);
b65fac32c   Bartlomiej Zolnierkiewicz   ide: merge ide_hw...
641
  		hwif->rq = NULL;
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
642
  	} else {
f63174e7a   Bartlomiej Zolnierkiewicz   ide-cd: remove cd...
643
644
  		if (sense && uptodate)
  			ide_cd_complete_failed_rq(drive, rq);
33659ebba   Christoph Hellwig   block: remove wra...
645
  		if (rq->cmd_type == REQ_TYPE_FS) {
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
646
  			if (cmd->nleft == 0)
f63174e7a   Bartlomiej Zolnierkiewicz   ide-cd: remove cd...
647
648
649
650
651
  				uptodate = 1;
  		} else {
  			if (uptodate <= 0 && rq->errors == 0)
  				rq->errors = -EIO;
  		}
39c58f37a   Rainer Weikusat   ide-cd: prevent n...
652
  		if (uptodate == 0 && rq->bio)
110712828   Borislav Petkov   ide-cd: Do not ac...
653
654
  			if (ide_cd_error_cmd(drive, cmd))
  				return ide_stopped;
c7ec89994   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
655

f63174e7a   Bartlomiej Zolnierkiewicz   ide-cd: remove cd...
656
  		/* make sure it's fully ended */
33659ebba   Christoph Hellwig   block: remove wra...
657
  		if (rq->cmd_type != REQ_TYPE_FS) {
5f49f6317   Tejun Heo   block: set rq->re...
658
  			rq->resid_len -= cmd->nbytes - cmd->nleft;
c7ec89994   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
659
  			if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
c3a4d78c5   Tejun Heo   block: add rq->re...
660
  				rq->resid_len += cmd->last_xfer_len;
c7ec89994   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
661
  		}
34b7d2c95   Tejun Heo   ide: cleanup rq->...
662
  		ide_complete_rq(drive, uptodate ? 0 : -EIO, blk_rq_bytes(rq));
f63174e7a   Bartlomiej Zolnierkiewicz   ide-cd: remove cd...
663

8a1169748   Bartlomiej Zolnierkiewicz   ide-cd: unify cdr...
664
665
  		if (sense && rc == 2)
  			ide_error(drive, "request sense failure", stat);
ff1bfbc1f   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
666
667
  	}
  	return ide_stopped;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
  }
21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
669
  static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
  {
21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
671
  	struct cdrom_info *cd = drive->driver_data;
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
672
  	struct request_queue *q = drive->queue;
21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
673
674
  	int write = rq_data_dir(rq) == WRITE;
  	unsigned short sectors_per_frame =
e1defc4ff   Martin K. Petersen   block: Do away wi...
675
  		queue_logical_block_size(q) >> SECTOR_BITS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
676

8652b31ab   Bartlomiej Zolnierkiewicz   ide-cd: merge ide...
677
  	ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, "
088b1b886   Borislav Petkov   ide: improve debu...
678
  				  "secs_per_frame: %u",
8652b31ab   Bartlomiej Zolnierkiewicz   ide-cd: merge ide...
679
  				  rq->cmd[0], rq->cmd_flags, sectors_per_frame);
fc8323f79   Borislav Petkov   ide-cd: convert d...
680

21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
681
  	if (write) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
682
  		/* disk has become write protected */
e0458ccb0   Bartlomiej Zolnierkiewicz   ide-cd: unify ide...
683
  		if (get_disk_ro(cd->disk))
21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
684
  			return ide_stopped;
21ea1f0f0   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
685
686
687
688
689
  	} else {
  		/*
  		 * We may be retrying this request after an error.  Fix up any
  		 * weirdness which might be present in the request packet.
  		 */
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
690
  		q->prep_rq_fn(q, rq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691
  	}
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
692
  	/* fs requests *must* be hardware frame aligned */
9780e2dd8   Tejun Heo   ide: convert to r...
693
694
  	if ((blk_rq_sectors(rq) & (sectors_per_frame - 1)) ||
  	    (blk_rq_pos(rq) & (sectors_per_frame - 1)))
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
695
696
697
698
  		return ide_stopped;
  
  	/* use DMA, if possible */
  	drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
699

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

8652b31ab   Bartlomiej Zolnierkiewicz   ide-cd: merge ide...
703
  	rq->timeout = ATAPI_WAIT_PC;
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
704
  	return ide_started;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
705
  }
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
706
  static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
707
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708

088b1b886   Borislav Petkov   ide: improve debu...
709
710
  	ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x",
  				  rq->cmd[0], rq->cmd_type);
fc8323f79   Borislav Petkov   ide-cd: convert d...
711

33659ebba   Christoph Hellwig   block: remove wra...
712
  	if (rq->cmd_type == REQ_TYPE_BLOCK_PC)
c9f56a801   Bartlomiej Zolnierkiewicz   ide-cd: merge cdr...
713
714
715
  		rq->cmd_flags |= REQ_QUIET;
  	else
  		rq->cmd_flags &= ~REQ_FAILED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716

12469ac0c   Borislav Petkov   ide-cd: move cdro...
717
  	drive->dma = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
718

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
719
  	/* sg request */
02e7cf8f8   Tejun Heo   ide-cd,atapi: use...
720
  	if (rq->bio) {
e5318b531   FUJITA Tomonori   ide: use the dma ...
721
  		struct request_queue *q = drive->queue;
02e7cf8f8   Tejun Heo   ide-cd,atapi: use...
722
  		char *buf = bio_data(rq->bio);
e5318b531   FUJITA Tomonori   ide: use the dma ...
723
  		unsigned int alignment;
e5318b531   FUJITA Tomonori   ide: use the dma ...
724

12469ac0c   Borislav Petkov   ide-cd: move cdro...
725
  		drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726
727
728
  
  		/*
  		 * check if dma is safe
5d9e4ea55   Linus Torvalds   ide-cd: revert DM...
729
730
731
  		 *
  		 * NOTE! The "len" and "addr" checks should possibly have
  		 * separate masks.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
732
  		 */
e5318b531   FUJITA Tomonori   ide: use the dma ...
733
  		alignment = queue_dma_alignment(q) | q->dma_pad_mask;
9bd27cba1   Borislav Petkov   ide-cd: fix DMA a...
734
  		if ((unsigned long)buf & alignment
34b7d2c95   Tejun Heo   ide: cleanup rq->...
735
  		    || blk_rq_bytes(rq) & q->dma_pad_mask
efa402d59   FUJITA Tomonori   ide-cd: use the n...
736
  		    || object_is_on_stack(buf))
12469ac0c   Borislav Petkov   ide-cd: move cdro...
737
  			drive->dma = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
738
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739
  }
99384aeaf   Borislav Petkov   ide-cd: mv ide_do...
740
  static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
e5e076a35   Borislav Petkov   ide-cd: fix remai...
741
  					sector_t block)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
742
  {
b788ee9c6   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
743
  	struct ide_cmd cmd;
3307d0d83   Connor Hansen   ide-cd: signednes...
744
745
  	int uptodate = 0;
  	unsigned int nsectors;
b788ee9c6   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
746

088b1b886   Borislav Petkov   ide: improve debu...
747
748
749
750
751
  	ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu",
  				  rq->cmd[0], (unsigned long long)block);
  
  	if (drive->debug_mask & IDE_DBG_RQ)
  		blk_dump_rq_flags(rq, "ide_cd_do_request");
fc8323f79   Borislav Petkov   ide-cd: convert d...
752

33659ebba   Christoph Hellwig   block: remove wra...
753
754
  	switch (rq->cmd_type) {
  	case REQ_TYPE_FS:
8652b31ab   Bartlomiej Zolnierkiewicz   ide-cd: merge ide...
755
  		if (cdrom_start_rw(drive, rq) == ide_stopped)
e0458ccb0   Bartlomiej Zolnierkiewicz   ide-cd: unify ide...
756
  			goto out_end;
33659ebba   Christoph Hellwig   block: remove wra...
757
758
759
760
  		break;
  	case REQ_TYPE_SENSE:
  	case REQ_TYPE_BLOCK_PC:
  	case REQ_TYPE_ATA_PC:
7fcebda50   Borislav Petkov   ide-cd: move requ...
761
762
  		if (!rq->timeout)
  			rq->timeout = ATAPI_WAIT_PC;
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
763
  		cdrom_do_block_pc(drive, rq);
33659ebba   Christoph Hellwig   block: remove wra...
764
765
  		break;
  	case REQ_TYPE_SPECIAL:
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
766
  		/* right now this can only be a reset... */
e0458ccb0   Bartlomiej Zolnierkiewicz   ide-cd: unify ide...
767
768
  		uptodate = 1;
  		goto out_end;
33659ebba   Christoph Hellwig   block: remove wra...
769
  	default:
2c7eaa43c   Bartlomiej Zolnierkiewicz   ide: BUG() on unk...
770
  		BUG();
33659ebba   Christoph Hellwig   block: remove wra...
771
  	}
b6ca440a8   Borislav Petkov   ide-cd: simplify ...
772

c457ce874   Borislav Petkov   ide-cd: convert t...
773
774
  	/* prepare sense request for this command */
  	ide_prep_sense(drive, rq);
b788ee9c6   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
775
776
777
778
779
780
  	memset(&cmd, 0, sizeof(cmd));
  
  	if (rq_data_dir(rq))
  		cmd.tf_flags |= IDE_TFLAG_WRITE;
  
  	cmd.rq = rq;
33659ebba   Christoph Hellwig   block: remove wra...
781
  	if (rq->cmd_type == REQ_TYPE_FS || blk_rq_bytes(rq)) {
34b7d2c95   Tejun Heo   ide: cleanup rq->...
782
  		ide_init_sg_cmd(&cmd, blk_rq_bytes(rq));
a08915ba5   Bartlomiej Zolnierkiewicz   ide-cd: use scatt...
783
784
  		ide_map_sg(drive, &cmd);
  	}
b788ee9c6   Bartlomiej Zolnierkiewicz   ide: use do_rw_ta...
785
  	return ide_issue_pc(drive, &cmd);
e0458ccb0   Bartlomiej Zolnierkiewicz   ide-cd: unify ide...
786
  out_end:
5b93629b4   Tejun Heo   block: implement ...
787
  	nsectors = blk_rq_sectors(rq);
f63174e7a   Bartlomiej Zolnierkiewicz   ide-cd: remove cd...
788
789
790
791
792
  
  	if (nsectors == 0)
  		nsectors = 1;
  
  	ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
e0458ccb0   Bartlomiej Zolnierkiewicz   ide-cd: unify ide...
793
  	return ide_stopped;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
794
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
795
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
797
   * Ioctl handling.
   *
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
798
799
800
801
802
   * 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
803
   */
e5e076a35   Borislav Petkov   ide-cd: fix remai...
804
  static void msf_from_bcd(struct atapi_msf *msf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
  {
fc99856a4   Adrian Bunk   ide-cd: use bcd2b...
806
807
808
  	msf->minute = bcd2bin(msf->minute);
  	msf->second = bcd2bin(msf->second);
  	msf->frame  = bcd2bin(msf->frame);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
809
  }
f9afd18b5   Borislav Petkov   ide-cd: move the ...
810
  int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
811
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
812
813
  	struct cdrom_info *info = drive->driver_data;
  	struct cdrom_device_info *cdi = &info->devinfo;
5f828546e   FUJITA Tomonori   ide-cd: convert i...
814
  	unsigned char cmd[BLK_MAX_CDB];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815

088b1b886   Borislav Petkov   ide: improve debu...
816
  	ide_debug_log(IDE_DBG_FUNC, "enter");
fc8323f79   Borislav Petkov   ide-cd: convert d...
817

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

cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
821
  	/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
822
823
  	 * 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...
824
  	 */
5f828546e   FUJITA Tomonori   ide-cd: convert i...
825
  	cmd[7] = cdi->sanyo_slot % 3;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
826

141d3b27f   Harvey Harrison   ide: ide-cd.c fix...
827
  	return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, sense, 0, REQ_QUIET);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
830
831
832
833
  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...
834
835
  		__be32 lba;
  		__be32 blocklen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
836
837
838
  	} capbuf;
  
  	int stat;
5f828546e   FUJITA Tomonori   ide-cd: convert i...
839
840
  	unsigned char cmd[BLK_MAX_CDB];
  	unsigned len = sizeof(capbuf);
938bb03d1   Petr Tesarik   ide-cd: fix endia...
841
  	u32 blocklen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
842

088b1b886   Borislav Petkov   ide: improve debu...
843
  	ide_debug_log(IDE_DBG_FUNC, "enter");
fc8323f79   Borislav Petkov   ide-cd: convert d...
844

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

5f828546e   FUJITA Tomonori   ide-cd: convert i...
848
849
  	stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0,
  			       REQ_QUIET);
e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
850
851
852
853
  	if (stat)
  		return stat;
  
  	/*
af054ed00   David S. Miller   ide-cd: Don't war...
854
855
856
  	 * Sanity check the given block size, in so far as making
  	 * sure the sectors_per_frame we give to the caller won't
  	 * end up being bogus.
e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
857
  	 */
938bb03d1   Petr Tesarik   ide-cd: fix endia...
858
  	blocklen = be32_to_cpu(capbuf.blocklen);
af054ed00   David S. Miller   ide-cd: Don't war...
859
  	blocklen = (blocklen >> SECTOR_BITS) << SECTOR_BITS;
938bb03d1   Petr Tesarik   ide-cd: fix endia...
860
861
862
863
864
  	switch (blocklen) {
  	case 512:
  	case 1024:
  	case 2048:
  	case 4096:
e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
865
866
  		break;
  	default:
d9ae62433   Frans Pop   ide-cd: Improve "...
867
868
869
  		printk_once(KERN_ERR PFX "%s: weird block size %u; "
  				"setting default block size to 2048
  ",
fc8323f79   Borislav Petkov   ide-cd: convert d...
870
  				drive->name, blocklen);
938bb03d1   Petr Tesarik   ide-cd: fix endia...
871
  		blocklen = 2048;
e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
872
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
873
  	}
e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
874
  	*capacity = 1 + be32_to_cpu(capbuf.lba);
938bb03d1   Petr Tesarik   ide-cd: fix endia...
875
  	*sectors_per_frame = blocklen >> SECTOR_BITS;
71b429ca4   Borislav Petkov   ide-cd: debug log...
876

088b1b886   Borislav Petkov   ide: improve debu...
877
878
  	ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu",
  				     *capacity, *sectors_per_frame);
71b429ca4   Borislav Petkov   ide-cd: debug log...
879

e8e7b9eb1   Jens Axboe   ide-cd: fix oops ...
880
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
881
882
883
884
885
886
  }
  
  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...
887
  	unsigned char cmd[BLK_MAX_CDB];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
888

088b1b886   Borislav Petkov   ide: improve debu...
889
  	ide_debug_log(IDE_DBG_FUNC, "enter");
fc8323f79   Borislav Petkov   ide-cd: convert d...
890

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

5f828546e   FUJITA Tomonori   ide-cd: convert i...
893
894
895
896
897
  	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
898
899
  
  	if (msf_flag)
5f828546e   FUJITA Tomonori   ide-cd: convert i...
900
  		cmd[1] = 2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
901

5f828546e   FUJITA Tomonori   ide-cd: convert i...
902
  	return ide_cd_queue_pc(drive, cmd, 0, buf, &buflen, sense, 0, REQ_QUIET);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
903
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
904
  /* Try to read the entire TOC for the disk into our internal buffer. */
17802998d   Bartlomiej Zolnierkiewicz   ide-cd: move code...
905
  int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
906
907
908
909
910
911
912
913
914
915
916
  {
  	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;
088b1b886   Borislav Petkov   ide: improve debu...
917
  	ide_debug_log(IDE_DBG_FUNC, "enter");
fc8323f79   Borislav Petkov   ide-cd: convert d...
918

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
  	if (toc == NULL) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
920
  		/* try to allocate space */
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
921
  		toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
922
  		if (toc == NULL) {
fc8323f79   Borislav Petkov   ide-cd: convert d...
923
924
  			printk(KERN_ERR PFX "%s: No cdrom TOC buffer!
  ",
83c8565dc   Borislav Petkov   ide-cd: shorten l...
925
  					drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
926
927
  			return -ENOMEM;
  		}
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
928
  		info->toc = toc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
929
  	}
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
930
931
932
933
  	/*
  	 * Check to see if the existing data is still valid. If it is,
  	 * just return.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
934
  	(void) cdrom_check_status(drive, sense);
570f89ea5   Borislav Petkov   ide-cd: convert t...
935
  	if (drive->atapi_flags & IDE_AFLAG_TOC_VALID)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
936
  		return 0;
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
937
  	/* try to get the total cdrom capacity and sector size */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
938
939
940
941
942
943
  	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...
944
  	/* save a private copy of the TOC capacity for error handling */
dbe217af3   Alan Cox   [PATCH] IDE CD en...
945
  	drive->probed_capacity = toc->capacity * sectors_per_frame;
e1defc4ff   Martin K. Petersen   block: Do away wi...
946
947
  	blk_queue_logical_block_size(drive->queue,
  				     sectors_per_frame << SECTOR_BITS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
948

5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
949
  	/* first read just the header, so we know how long the TOC is */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
950
951
  	stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
  				    sizeof(struct atapi_toc_header), sense);
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
952
953
  	if (stat)
  		return stat;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
954

570f89ea5   Borislav Petkov   ide-cd: convert t...
955
  	if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
fc99856a4   Adrian Bunk   ide-cd: use bcd2b...
956
957
  		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
958
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
959
960
961
962
963
964
  
  	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...
965
  	/* now read the whole schmeer */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
966
967
968
969
970
971
972
  	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...
973
974
975
976
977
978
979
980
981
982
983
984
  		/*
  		 * 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
985
986
987
988
989
990
991
  		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...
992
  		if (stat)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
993
  			return stat;
cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
994

570f89ea5   Borislav Petkov   ide-cd: convert t...
995
  		if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
fc99856a4   Adrian Bunk   ide-cd: use bcd2b...
996
997
  			toc->hdr.first_track = (u8)bin2bcd(CDROM_LEADOUT);
  			toc->hdr.last_track = (u8)bin2bcd(CDROM_LEADOUT);
cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
998
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
999
1000
1001
1002
1003
1004
1005
  			toc->hdr.first_track = CDROM_LEADOUT;
  			toc->hdr.last_track = CDROM_LEADOUT;
  		}
  	}
  
  	if (stat)
  		return stat;
7eb43fd2f   Borislav Petkov   ide-cd: replace n...
1006
  	toc->hdr.toc_length = be16_to_cpu(toc->hdr.toc_length);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1007

570f89ea5   Borislav Petkov   ide-cd: convert t...
1008
  	if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
fc99856a4   Adrian Bunk   ide-cd: use bcd2b...
1009
1010
  		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
1011
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1012

cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
1013
  	for (i = 0; i <= ntracks; i++) {
570f89ea5   Borislav Petkov   ide-cd: convert t...
1014
1015
  		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...
1016
  				toc->ent[i].track = bcd2bin(toc->ent[i].track);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1017
1018
  			msf_from_bcd(&toc->ent[i].addr.msf);
  		}
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1019
1020
1021
  		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
1022
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1023
  	if (toc->hdr.first_track != CDROM_LEADOUT) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1024
  		/* read the multisession information */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1025
1026
  		stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
  					   sizeof(ms_tmp), sense);
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
1027
1028
  		if (stat)
  			return stat;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1029
1030
1031
  
  		toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
  	} else {
e5e076a35   Borislav Petkov   ide-cd: fix remai...
1032
1033
  		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
1034
1035
  		toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
  	}
570f89ea5   Borislav Petkov   ide-cd: convert t...
1036
  	if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) {
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1037
  		/* re-read multisession information using MSF format */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1038
1039
1040
1041
  		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...
1042
  		msf_from_bcd(&ms_tmp.ent.addr.msf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1043
  		toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute,
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1044
  						   ms_tmp.ent.addr.msf.second,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1045
1046
  						   ms_tmp.ent.addr.msf.frame);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1047
1048
  
  	toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1049
  	/* now try to get the total cdrom capacity */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1050
1051
1052
1053
  	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...
1054
  		drive->probed_capacity = toc->capacity * sectors_per_frame;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1055
1056
1057
  	}
  
  	/* Remember that we've read this stuff. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1058
  	drive->atapi_flags |= IDE_AFLAG_TOC_VALID;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1059
1060
1061
  
  	return 0;
  }
17802998d   Bartlomiej Zolnierkiewicz   ide-cd: move code...
1062
  int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
9235e68be   Eric Piel   [PATCH] IDE CD re...
1063
1064
1065
1066
  {
  	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...
1067
  	int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
9235e68be   Eric Piel   [PATCH] IDE CD re...
1068

088b1b886   Borislav Petkov   ide: improve debu...
1069
  	ide_debug_log(IDE_DBG_FUNC, "enter");
fc8323f79   Borislav Petkov   ide-cd: convert d...
1070

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

455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1074
  	init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN);
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1075
1076
  	do {
  		/* we seem to get stat=0x01,err=0x00 the first time (??) */
9235e68be   Eric Piel   [PATCH] IDE CD re...
1077
1078
1079
1080
1081
1082
  		stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
  		if (!stat)
  			break;
  	} while (--attempts);
  	return stat;
  }
17802998d   Bartlomiej Zolnierkiewicz   ide-cd: move code...
1083
  void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
9235e68be   Eric Piel   [PATCH] IDE CD re...
1084
  {
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1085
  	struct cdrom_info *cd = drive->driver_data;
481c8c647   Bartlomiej Zolnierkiewicz   ide-cd: cleanup i...
1086
  	u16 curspeed, maxspeed;
088b1b886   Borislav Petkov   ide: improve debu...
1087
  	ide_debug_log(IDE_DBG_FUNC, "enter");
fc8323f79   Borislav Petkov   ide-cd: convert d...
1088

570f89ea5   Borislav Petkov   ide-cd: convert t...
1089
  	if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) {
141d3b27f   Harvey Harrison   ide: ide-cd.c fix...
1090
1091
  		curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]);
  		maxspeed = le16_to_cpup((__le16 *)&buf[8 + 8]);
9235e68be   Eric Piel   [PATCH] IDE CD re...
1092
  	} else {
141d3b27f   Harvey Harrison   ide: ide-cd.c fix...
1093
1094
  		curspeed = be16_to_cpup((__be16 *)&buf[8 + 14]);
  		maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
9235e68be   Eric Piel   [PATCH] IDE CD re...
1095
  	}
481c8c647   Bartlomiej Zolnierkiewicz   ide-cd: cleanup i...
1096

088b1b886   Borislav Petkov   ide: improve debu...
1097
1098
  	ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u",
  				     curspeed, maxspeed);
71b429ca4   Borislav Petkov   ide-cd: debug log...
1099

72db37b2c   Julia Lawall   drivers/ide/ide-c...
1100
1101
  	cd->current_speed = DIV_ROUND_CLOSEST(curspeed, 176);
  	cd->max_speed = DIV_ROUND_CLOSEST(maxspeed, 176);
9235e68be   Eric Piel   [PATCH] IDE CD re...
1102
  }
20e7f7efa   Bartlomiej Zolnierkiewicz   ide-cd: add IDE_C...
1103
1104
1105
1106
1107
1108
  #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
1109

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1110
1111
1112
1113
  static struct cdrom_device_ops ide_cdrom_dops = {
  	.open			= ide_cdrom_open_real,
  	.release		= ide_cdrom_release_real,
  	.drive_status		= ide_cdrom_drive_status,
5b03a1b14   Tejun Heo   ide: Convert to b...
1114
  	.check_events		= ide_cdrom_check_events_real,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1115
1116
1117
1118
1119
1120
1121
  	.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...
1122
  	.capability		= IDE_CD_CAPABILITIES,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1123
1124
  	.generic_packet		= ide_cdrom_packet,
  };
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1125
  static int ide_cdrom_register(ide_drive_t *drive, int nslots)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1126
1127
1128
  {
  	struct cdrom_info *info = drive->driver_data;
  	struct cdrom_device_info *devinfo = &info->devinfo;
088b1b886   Borislav Petkov   ide: improve debu...
1129
  	ide_debug_log(IDE_DBG_PROBE, "nslots: %d", nslots);
fc8323f79   Borislav Petkov   ide-cd: convert d...
1130

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1131
  	devinfo->ops = &ide_cdrom_dops;
2bc4cf2d8   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1132
  	devinfo->speed = info->current_speed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1133
  	devinfo->capacity = nslots;
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
1134
  	devinfo->handle = drive;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1135
  	strcpy(devinfo->name, drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1136

570f89ea5   Borislav Petkov   ide-cd: convert t...
1137
  	if (drive->atapi_flags & IDE_AFLAG_NO_SPEED_SELECT)
3cbd814ef   Bartlomiej Zolnierkiewicz   ide-cd: fix SAMSU...
1138
  		devinfo->mask |= CDC_SELECT_SPEED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1139
1140
1141
  	devinfo->disk = info->disk;
  	return register_cdrom(devinfo);
  }
e5e076a35   Borislav Petkov   ide-cd: fix remai...
1142
  static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1143
  {
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1144
1145
  	struct cdrom_info *cd = drive->driver_data;
  	struct cdrom_device_info *cdi = &cd->devinfo;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1146
1147
  	u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
  	mechtype_t mechtype;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1148
  	int nslots = 1;
088b1b886   Borislav Petkov   ide: improve debu...
1149
1150
  	ide_debug_log(IDE_DBG_PROBE, "media: 0x%x, atapi_flags: 0x%lx",
  				     drive->media, drive->atapi_flags);
fc8323f79   Borislav Petkov   ide-cd: convert d...
1151

3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1152
1153
1154
  	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
1155
  	if (drive->media == ide_optical) {
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1156
  		cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM);
fc8323f79   Borislav Petkov   ide-cd: convert d...
1157
1158
  		printk(KERN_ERR PFX "%s: ATAPI magneto-optical drive
  ",
83c8565dc   Borislav Petkov   ide-cd: shorten l...
1159
  				drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1160
1161
  		return nslots;
  	}
570f89ea5   Borislav Petkov   ide-cd: convert t...
1162
1163
  	if (drive->atapi_flags & IDE_AFLAG_PRE_ATAPI12) {
  		drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT;
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1164
  		cdi->mask &= ~CDC_PLAY_AUDIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1165
1166
1167
1168
  		return nslots;
  	}
  
  	/*
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1169
1170
1171
1172
  	 * 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
1173
  	 */
2a91f3e54   Jesper Juhl   [PATCH] ide-cd mi...
1174
  	cdi->handle = drive;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1175
  	cdi->ops = &ide_cdrom_dops;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1176
  	if (ide_cdrom_get_capabilities(drive, buf))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1177
  		return 0;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1178
  	if ((buf[8 + 6] & 0x01) == 0)
42619d35c   Bartlomiej Zolnierkiewicz   ide: remove IDE_A...
1179
  		drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1180
  	if (buf[8 + 6] & 0x08)
570f89ea5   Borislav Petkov   ide-cd: convert t...
1181
  		drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1182
  	if (buf[8 + 3] & 0x01)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1183
  		cdi->mask &= ~CDC_CD_R;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1184
  	if (buf[8 + 3] & 0x02)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1185
  		cdi->mask &= ~(CDC_CD_RW | CDC_RAM);
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1186
  	if (buf[8 + 2] & 0x38)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1187
  		cdi->mask &= ~CDC_DVD;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1188
  	if (buf[8 + 3] & 0x20)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1189
  		cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM);
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1190
  	if (buf[8 + 3] & 0x10)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1191
  		cdi->mask &= ~CDC_DVD_R;
570f89ea5   Borislav Petkov   ide-cd: convert t...
1192
  	if ((buf[8 + 4] & 0x01) || (drive->atapi_flags & IDE_AFLAG_PLAY_AUDIO_OK))
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1193
  		cdi->mask &= ~CDC_PLAY_AUDIO;
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1194
1195
  
  	mechtype = buf[8 + 6] >> 5;
f20f25860   Borislav Petkov   ide-cd: temporary...
1196
1197
1198
  	if (mechtype == mechtype_caddy ||
  	    mechtype == mechtype_popup ||
  	    (drive->atapi_flags & IDE_AFLAG_NO_AUTOCLOSE))
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1199
  		cdi->mask |= CDC_CLOSE_TRAY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1200

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1201
  	if (cdi->sanyo_slot > 0) {
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1202
  		cdi->mask &= ~CDC_SELECT_DISC;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1203
  		nslots = 3;
cdf6000d7   Bartlomiej Zolnierkiewicz   ide-cd: remove ST...
1204
1205
  	} else if (mechtype == mechtype_individual_changer ||
  		   mechtype == mechtype_cartridge_changer) {
2609d06d3   Bartlomiej Zolnierkiewicz   ide-cd: remove un...
1206
1207
  		nslots = cdrom_number_of_slots(cdi);
  		if (nslots > 1)
3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1208
  			cdi->mask &= ~CDC_SELECT_DISC;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1209
  	}
455d80a95   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1210
  	ide_cdrom_update_speed(drive, buf);
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1211

fc8323f79   Borislav Petkov   ide-cd: convert d...
1212
  	printk(KERN_INFO PFX "%s: ATAPI", drive->name);
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1213
1214
  
  	/* don't print speed if the drive reported 0 */
2bc4cf2d8   Bartlomiej Zolnierkiewicz   ide-cd: remove st...
1215
1216
  	if (cd->max_speed)
  		printk(KERN_CONT " %dX", cd->max_speed);
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1217

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

3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1220
1221
1222
  	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",
419a5b67c   Borislav Petkov   ide-cd: small dri...
1223
  				 (cdi->mask & CDC_DVD_RAM) ? "" : "/RAM");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1224

3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1225
1226
1227
1228
  	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
1229

3f1b86d89   Bartlomiej Zolnierkiewicz   ide-cd: remove re...
1230
1231
1232
1233
  	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
1234

fc8323f79   Borislav Petkov   ide-cd: convert d...
1235
1236
1237
  	printk(KERN_CONT ", %dkB Cache
  ",
  			 be16_to_cpup((__be16 *)&buf[8 + 12]));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1238
1239
1240
  
  	return nslots;
  }
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1241
  /* standard prep_rq_fn that builds 10 byte cmds */
165125e1e   Jens Axboe   [BLOCK] Get rid o...
1242
  static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1243
  {
e1defc4ff   Martin K. Petersen   block: Do away wi...
1244
  	int hard_sect = queue_logical_block_size(q);
5b93629b4   Tejun Heo   block: implement ...
1245
1246
  	long block = (long)blk_rq_pos(rq) / (hard_sect >> 9);
  	unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1247

d34c87e4b   FUJITA Tomonori   block: replace si...
1248
  	memset(rq->cmd, 0, BLK_MAX_CDB);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
  
  	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...
1279
  	/* transform 6-byte read/write commands to the 10-byte version */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
  	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...
1301

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1302
1303
  	return BLKPREP_OK;
  }
165125e1e   Jens Axboe   [BLOCK] Get rid o...
1304
  static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1305
  {
33659ebba   Christoph Hellwig   block: remove wra...
1306
  	if (rq->cmd_type == REQ_TYPE_FS)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1307
  		return ide_cdrom_prep_fs(q, rq);
33659ebba   Christoph Hellwig   block: remove wra...
1308
  	else if (rq->cmd_type == REQ_TYPE_BLOCK_PC)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1309
1310
1311
1312
  		return ide_cdrom_prep_pc(rq);
  
  	return 0;
  }
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1313
1314
1315
1316
1317
  struct cd_list_entry {
  	const char	*id_model;
  	const char	*id_firmware;
  	unsigned int	cd_flags;
  };
5e657a9e2   Borislav Petkov   ide-cd: put all p...
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
  #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;
  }
6d703a81a   Alexey Dobriyan   ide: convert to -...
1328
  static int idecd_capacity_proc_show(struct seq_file *m, void *v)
5e657a9e2   Borislav Petkov   ide-cd: put all p...
1329
  {
6d703a81a   Alexey Dobriyan   ide: convert to -...
1330
  	ide_drive_t *drive = m->private;
5e657a9e2   Borislav Petkov   ide-cd: put all p...
1331

6d703a81a   Alexey Dobriyan   ide: convert to -...
1332
1333
1334
1335
1336
1337
1338
1339
  	seq_printf(m, "%llu
  ", (long long)ide_cdrom_capacity(drive));
  	return 0;
  }
  
  static int idecd_capacity_proc_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, idecd_capacity_proc_show, PDE(inode)->data);
5e657a9e2   Borislav Petkov   ide-cd: put all p...
1340
  }
6d703a81a   Alexey Dobriyan   ide: convert to -...
1341
1342
1343
1344
1345
1346
1347
  static const struct file_operations idecd_capacity_proc_fops = {
  	.owner		= THIS_MODULE,
  	.open		= idecd_capacity_proc_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= single_release,
  };
5e657a9e2   Borislav Petkov   ide-cd: put all p...
1348
  static ide_proc_entry_t idecd_proc[] = {
6d703a81a   Alexey Dobriyan   ide: convert to -...
1349
1350
  	{ "capacity", S_IFREG|S_IRUGO, &idecd_capacity_proc_fops },
  	{}
5e657a9e2   Borislav Petkov   ide-cd: put all p...
1351
  };
79cb38039   Bartlomiej Zolnierkiewicz   ide: allow device...
1352
1353
1354
1355
1356
1357
1358
  static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive)
  {
  	return idecd_proc;
  }
  
  static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive)
  {
519d68082   Bartlomiej Zolnierkiewicz   ide-cd: remove de...
1359
  	return NULL;
79cb38039   Bartlomiej Zolnierkiewicz   ide: allow device...
1360
  }
5e657a9e2   Borislav Petkov   ide-cd: put all p...
1361
  #endif
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1362
  static const struct cd_list_entry ide_cd_quirks_list[] = {
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1363
  	/* SCR-3231 doesn't support the SET_CD_SPEED command. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1364
  	{ "SAMSUNG CD-ROM SCR-3231", NULL,   IDE_AFLAG_NO_SPEED_SELECT	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1365
  	/* Old NEC260 (not R) was released before ATAPI 1.2 spec. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1366
1367
  	{ "NEC CD-ROM DRIVE:260",    "1.01", IDE_AFLAG_TOCADDR_AS_BCD |
  					     IDE_AFLAG_PRE_ATAPI12,	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1368
  	/* Vertos 300, some versions of this drive like to talk BCD. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1369
  	{ "V003S0DS",		     NULL,   IDE_AFLAG_VERTOS_300_SSD,	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1370
  	/* Vertos 600 ESD. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1371
  	{ "V006E0DS",		     NULL,   IDE_AFLAG_VERTOS_600_ESD,	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1372
1373
1374
1375
  	/*
  	 * 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...
1376
1377
1378
  	{ "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...
1379
  	/* Stingray 8X CD-ROM. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1380
  	{ "STINGRAY 8422 IDE 8X CD-ROM 7-27-95", NULL, IDE_AFLAG_PRE_ATAPI12 },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1381
1382
1383
1384
  	/*
  	 * 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...
1385
1386
  	{ "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...
1387
  	/* ACER/AOpen 24X CD-ROM has the speed fields byte-swapped. */
570f89ea5   Borislav Petkov   ide-cd: convert t...
1388
  	{ "",			     "241N", IDE_AFLAG_LE_SPEED_FIELDS       },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1389
1390
1391
1392
  	/*
  	 * 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...
1393
1394
1395
1396
1397
  	{ "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...
1398
  	{ "Optiarc DVD RW AD-7200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
f20f25860   Borislav Petkov   ide-cd: temporary...
1399
  	{ "Optiarc DVD RW AD-7543A", NULL,   IDE_AFLAG_NO_AUTOCLOSE	     },
64c2eae22   Márton Németh   ide-cd: add TEAC ...
1400
  	{ "TEAC CD-ROM CD-224E",     NULL,   IDE_AFLAG_NO_AUTOCLOSE	     },
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1401
1402
  	{ NULL, NULL, 0 }
  };
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1403
  static unsigned int ide_cd_flags(u16 *id)
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1404
1405
1406
1407
  {
  	const struct cd_list_entry *cle = ide_cd_quirks_list;
  
  	while (cle->id_model) {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1408
  		if (strcmp(cle->id_model, (char *)&id[ATA_ID_PROD]) == 0 &&
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1409
  		    (cle->id_firmware == NULL ||
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1410
  		     strstr((char *)&id[ATA_ID_FW_REV], cle->id_firmware)))
e59724c7d   Bartlomiej Zolnierkiewicz   ide-cd: re-organi...
1411
1412
1413
1414
1415
1416
  			return cle->cd_flags;
  		cle++;
  	}
  
  	return 0;
  }
e5e076a35   Borislav Petkov   ide-cd: fix remai...
1417
  static int ide_cdrom_setup(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1418
  {
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1419
1420
  	struct cdrom_info *cd = drive->driver_data;
  	struct cdrom_device_info *cdi = &cd->devinfo;
e698ea83a   Bartlomiej Zolnierkiewicz   ide-cd: minor ide...
1421
  	struct request_queue *q = drive->queue;
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1422
1423
  	u16 *id = drive->id;
  	char *fw_rev = (char *)&id[ATA_ID_FW_REV];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1424
  	int nslots;
088b1b886   Borislav Petkov   ide: improve debu...
1425
  	ide_debug_log(IDE_DBG_PROBE, "enter");
fc8323f79   Borislav Petkov   ide-cd: convert d...
1426

e698ea83a   Bartlomiej Zolnierkiewicz   ide-cd: minor ide...
1427
1428
1429
  	blk_queue_prep_rq(q, ide_cdrom_prep_fn);
  	blk_queue_dma_alignment(q, 31);
  	blk_queue_update_dma_pad(q, 15);
fe11edfaa   Bartlomiej Zolnierkiewicz   ide: IDE_AFLAG_ME...
1430
1431
  	drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
  	drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1432

570f89ea5   Borislav Petkov   ide-cd: convert t...
1433
  	if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) &&
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
1434
  	    fw_rev[4] == '1' && fw_rev[6] <= '2')
570f89ea5   Borislav Petkov   ide-cd: convert t...
1435
1436
1437
  		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->...
1438
  		 fw_rev[4] == '1' && fw_rev[6] <= '2')
570f89ea5   Borislav Petkov   ide-cd: convert t...
1439
1440
  		drive->atapi_flags |= IDE_AFLAG_TOCTRACKS_AS_BCD;
  	else if (drive->atapi_flags & IDE_AFLAG_SANYO_3CD)
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1441
1442
  		/* 3 => use CD in slot 0 */
  		cdi->sanyo_slot = 3;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1443

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

e1defc4ff   Martin K. Petersen   block: Do away wi...
1446
  	blk_queue_logical_block_size(q, CD_FRAMESIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1447

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448
  	if (ide_cdrom_register(drive, nslots)) {
fc8323f79   Borislav Petkov   ide-cd: convert d...
1449
  		printk(KERN_ERR PFX "%s: %s failed to register device with the"
83c8565dc   Borislav Petkov   ide-cd: shorten l...
1450
1451
  				" cdrom driver.
  ", drive->name, __func__);
4fe671786   Bartlomiej Zolnierkiewicz   ide-cd: kill CDRO...
1452
  		cd->devinfo.handle = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1453
1454
  		return 1;
  	}
1e874f448   Bartlomiej Zolnierkiewicz   ide: call ide_pro...
1455
1456
  
  	ide_proc_register_driver(drive, cd->driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1457
1458
  	return 0;
  }
4031bbe4b   Russell King   [PATCH] Add ide_b...
1459
  static void ide_cd_remove(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1460
1461
  {
  	struct cdrom_info *info = drive->driver_data;
088b1b886   Borislav Petkov   ide: improve debu...
1462
  	ide_debug_log(IDE_DBG_FUNC, "enter");
fc8323f79   Borislav Petkov   ide-cd: convert d...
1463

7662d046d   Bartlomiej Zolnierkiewicz   ide: move IDE set...
1464
  	ide_proc_unregister_driver(drive, info->driver);
8fed43684   Bartlomiej Zolnierkiewicz   ide: fix refcount...
1465
  	device_del(&info->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1466
  	del_gendisk(info->disk);
8fed43684   Bartlomiej Zolnierkiewicz   ide: fix refcount...
1467
1468
1469
  	mutex_lock(&idecd_ref_mutex);
  	put_device(&info->dev);
  	mutex_unlock(&idecd_ref_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1470
  }
8fed43684   Bartlomiej Zolnierkiewicz   ide: fix refcount...
1471
  static void ide_cd_release(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1472
  {
8fed43684   Bartlomiej Zolnierkiewicz   ide: fix refcount...
1473
  	struct cdrom_info *info = to_ide_drv(dev, cdrom_info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1474
1475
1476
  	struct cdrom_device_info *devinfo = &info->devinfo;
  	ide_drive_t *drive = info->drive;
  	struct gendisk *g = info->disk;
088b1b886   Borislav Petkov   ide: improve debu...
1477
  	ide_debug_log(IDE_DBG_FUNC, "enter");
fc8323f79   Borislav Petkov   ide-cd: convert d...
1478

6044ec888   Jesper Juhl   [PATCH] kfree cle...
1479
  	kfree(info->toc);
0a0c4114d   Akinobu Mita   cdrom: make unreg...
1480
1481
  	if (devinfo->handle == drive)
  		unregister_cdrom(devinfo);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1482
1483
1484
1485
1486
1487
  	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...
1488
  static int ide_cd_probe(ide_drive_t *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1489

7f3c868ba   Bartlomiej Zolnierkiewicz   ide: remove ide_d...
1490
  static struct ide_driver ide_cdrom_driver = {
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
1491
  	.gen_driver = {
4ef3b8f4a   Laurent Riffard   [PATCH] ide: remo...
1492
  		.owner		= THIS_MODULE,
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
1493
1494
  		.name		= "ide-cdrom",
  		.bus		= &ide_bus_type,
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
1495
  	},
4031bbe4b   Russell King   [PATCH] Add ide_b...
1496
1497
  	.probe			= ide_cd_probe,
  	.remove			= ide_cd_remove,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1498
  	.version		= IDECD_VERSION,
99384aeaf   Borislav Petkov   ide-cd: mv ide_do...
1499
  	.do_request		= ide_cd_do_request,
7662d046d   Bartlomiej Zolnierkiewicz   ide: move IDE set...
1500
  #ifdef CONFIG_IDE_PROC_FS
79cb38039   Bartlomiej Zolnierkiewicz   ide: allow device...
1501
1502
  	.proc_entries		= ide_cd_proc_entries,
  	.proc_devsets		= ide_cd_proc_devsets,
7662d046d   Bartlomiej Zolnierkiewicz   ide: move IDE set...
1503
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1504
  };
488ca606f   Al Viro   [PATCH] switch id...
1505
  static int idecd_open(struct block_device *bdev, fmode_t mode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1506
  {
6e9624b8c   Arnd Bergmann   block: push down ...
1507
1508
  	struct cdrom_info *info;
  	int rc = -ENXIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1509

2a48fc0ab   Arnd Bergmann   block: autoconver...
1510
  	mutex_lock(&ide_cd_mutex);
6e9624b8c   Arnd Bergmann   block: push down ...
1511
  	info = ide_cd_get(bdev->bd_disk);
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1512
  	if (!info)
6e9624b8c   Arnd Bergmann   block: push down ...
1513
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1514

488ca606f   Al Viro   [PATCH] switch id...
1515
  	rc = cdrom_open(&info->devinfo, bdev, mode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1516
1517
  	if (rc < 0)
  		ide_cd_put(info);
6e9624b8c   Arnd Bergmann   block: push down ...
1518
  out:
2a48fc0ab   Arnd Bergmann   block: autoconver...
1519
  	mutex_unlock(&ide_cd_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1520
1521
  	return rc;
  }
488ca606f   Al Viro   [PATCH] switch id...
1522
  static int idecd_release(struct gendisk *disk, fmode_t mode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1523
  {
5aeddf907   Borislav Petkov   ide: unify conver...
1524
  	struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1525

2a48fc0ab   Arnd Bergmann   block: autoconver...
1526
  	mutex_lock(&ide_cd_mutex);
488ca606f   Al Viro   [PATCH] switch id...
1527
  	cdrom_release(&info->devinfo, mode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1528
1529
  
  	ide_cd_put(info);
2a48fc0ab   Arnd Bergmann   block: autoconver...
1530
  	mutex_unlock(&ide_cd_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1531
1532
1533
  
  	return 0;
  }
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
  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...
1559
  	char spindown;
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1560
1561
1562
1563
1564
1565
1566
1567
  
  	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...
1568
  	if (copy_to_user((void __user *)arg, &spindown, sizeof(char)))
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1569
1570
1571
  		return -EFAULT;
  	return 0;
  }
8a6cfeb6d   Arnd Bergmann   block: push down ...
1572
  static int idecd_locked_ioctl(struct block_device *bdev, fmode_t mode,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1573
1574
  			unsigned int cmd, unsigned long arg)
  {
5aeddf907   Borislav Petkov   ide: unify conver...
1575
  	struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1576
  	int err;
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1577
  	switch (cmd) {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1578
  	case CDROMSETSPINDOWN:
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1579
  		return idecd_set_spindown(&info->devinfo, arg);
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1580
  	case CDROMGETSPINDOWN:
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1581
1582
1583
  		return idecd_get_spindown(&info->devinfo, arg);
  	default:
  		break;
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1584
  	}
6a2900b67   Christoph Hellwig   [PATCH] kill cdro...
1585

1bddd9e64   Al Viro   [PATCH] lose the ...
1586
  	err = generic_ide_ioctl(info->drive, bdev, cmd, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1587
  	if (err == -EINVAL)
488ca606f   Al Viro   [PATCH] switch id...
1588
  		err = cdrom_ioctl(&info->devinfo, bdev, mode, cmd, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1589
1590
1591
  
  	return err;
  }
8a6cfeb6d   Arnd Bergmann   block: push down ...
1592
1593
1594
1595
  static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
  			     unsigned int cmd, unsigned long arg)
  {
  	int ret;
2a48fc0ab   Arnd Bergmann   block: autoconver...
1596
  	mutex_lock(&ide_cd_mutex);
8a6cfeb6d   Arnd Bergmann   block: push down ...
1597
  	ret = idecd_locked_ioctl(bdev, mode, cmd, arg);
2a48fc0ab   Arnd Bergmann   block: autoconver...
1598
  	mutex_unlock(&ide_cd_mutex);
8a6cfeb6d   Arnd Bergmann   block: push down ...
1599
1600
1601
  
  	return ret;
  }
5b03a1b14   Tejun Heo   ide: Convert to b...
1602
1603
  static unsigned int idecd_check_events(struct gendisk *disk,
  				       unsigned int clearing)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1604
  {
5aeddf907   Borislav Petkov   ide: unify conver...
1605
  	struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
5b03a1b14   Tejun Heo   ide: Convert to b...
1606
  	return cdrom_check_events(&info->devinfo, clearing);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1607
1608
1609
1610
  }
  
  static int idecd_revalidate_disk(struct gendisk *disk)
  {
5aeddf907   Borislav Petkov   ide: unify conver...
1611
  	struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1612
  	struct request_sense sense;
139c829d9   Bartlomiej Zolnierkiewicz   ide-cd: rename cd...
1613
1614
  
  	ide_cd_read_toc(info->drive, &sense);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1615
1616
  	return  0;
  }
83d5cde47   Alexey Dobriyan   const: make block...
1617
  static const struct block_device_operations idecd_ops = {
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1618
  	.owner			= THIS_MODULE,
488ca606f   Al Viro   [PATCH] switch id...
1619
1620
  	.open			= idecd_open,
  	.release		= idecd_release,
8a6cfeb6d   Arnd Bergmann   block: push down ...
1621
  	.ioctl			= idecd_ioctl,
5b03a1b14   Tejun Heo   ide: Convert to b...
1622
  	.check_events		= idecd_check_events,
9ce70fb2b   Paolo Ciarrocchi   IDE: Coding Style...
1623
  	.revalidate_disk	= idecd_revalidate_disk
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1624
  };
5a3ea3b42   Borislav Petkov   ide-cd: fixup com...
1625
  /* module options */
35d9b17fe   Borislav Petkov   ide-cd: add a deb...
1626
1627
  static unsigned long debug_mask;
  module_param(debug_mask, ulong, 0644);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1628
  MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
4031bbe4b   Russell King   [PATCH] Add ide_b...
1629
  static int ide_cd_probe(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1630
1631
1632
1633
  {
  	struct cdrom_info *info;
  	struct gendisk *g;
  	struct request_sense sense;
088b1b886   Borislav Petkov   ide: improve debu...
1634
1635
  	ide_debug_log(IDE_DBG_PROBE, "driver_req: %s, media: 0x%x",
  				     drive->driver_req, drive->media);
fc8323f79   Borislav Petkov   ide-cd: convert d...
1636

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1637
1638
  	if (!strstr("ide-cdrom", drive->driver_req))
  		goto failed;
2a924662b   Bartlomiej Zolnierkiewicz   ide: remove needl...
1639

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

35d9b17fe   Borislav Petkov   ide-cd: add a deb...
1643
  	drive->debug_mask = debug_mask;
d6251d448   Borislav Petkov   ide-cd: convert t...
1644
  	drive->irq_handler = cdrom_newpc_intr;
35d9b17fe   Borislav Petkov   ide-cd: add a deb...
1645

f5e3c2faa   Deepak Saxena   [PATCH] ide: kmal...
1646
  	info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1647
  	if (info == NULL) {
fc8323f79   Borislav Petkov   ide-cd: convert d...
1648
1649
  		printk(KERN_ERR PFX "%s: Can't allocate a cdrom structure
  ",
83c8565dc   Borislav Petkov   ide-cd: shorten l...
1650
  				drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1651
1652
1653
1654
1655
1656
1657
1658
  		goto failed;
  	}
  
  	g = alloc_disk(1 << PARTN_BITS);
  	if (!g)
  		goto out_free_cd;
  
  	ide_init_disk(g, drive);
8fed43684   Bartlomiej Zolnierkiewicz   ide: fix refcount...
1659
1660
1661
1662
1663
1664
  	info->dev.parent = &drive->gendev;
  	info->dev.release = ide_cd_release;
  	dev_set_name(&info->dev, dev_name(&drive->gendev));
  
  	if (device_register(&info->dev))
  		goto out_free_disk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1665
1666
1667
1668
1669
1670
1671
1672
  
  	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
1673
  	g->minors = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1674
1675
1676
  	g->driverfs_dev = &drive->gendev;
  	g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
  	if (ide_cdrom_setup(drive)) {
8fed43684   Bartlomiej Zolnierkiewicz   ide: fix refcount...
1677
  		put_device(&info->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1678
1679
  		goto failed;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1680

139c829d9   Bartlomiej Zolnierkiewicz   ide-cd: rename cd...
1681
  	ide_cd_read_toc(drive, &sense);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1682
  	g->fops = &idecd_ops;
d4dc210f6   Tejun Heo   block: don't bloc...
1683
  	g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1684
1685
  	add_disk(g);
  	return 0;
8fed43684   Bartlomiej Zolnierkiewicz   ide: fix refcount...
1686
1687
  out_free_disk:
  	put_disk(g);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1688
1689
1690
  out_free_cd:
  	kfree(info);
  failed:
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
1691
  	return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1692
1693
1694
1695
  }
  
  static void __exit ide_cdrom_exit(void)
  {
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
1696
  	driver_unregister(&ide_cdrom_driver.gen_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1697
  }
17514e8a6   Bartlomiej Zolnierkiewicz   [PATCH] ide: add ...
1698
1699
  
  static int __init ide_cdrom_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1700
  {
fc8323f79   Borislav Petkov   ide-cd: convert d...
1701
1702
  	printk(KERN_INFO DRV_NAME " driver " IDECD_VERSION "
  ");
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
1703
  	return driver_register(&ide_cdrom_driver.gen_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1704
  }
263756ec2   Kay Sievers   [PATCH] ide: MODA...
1705
  MODULE_ALIAS("ide:*m-cdrom*");
972560fb9   Bartlomiej Zolnierkiewicz   ide-cd: move VERB...
1706
  MODULE_ALIAS("ide-cd");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1707
1708
1709
  module_init(ide_cdrom_init);
  module_exit(ide_cdrom_exit);
  MODULE_LICENSE("GPL");