Commit 93c164af19f608c5f737eb9bed8cb4de3a872329
Committed by
Bartlomiej Zolnierkiewicz
1 parent
07bd3f4731
Exists in
master
and in
7 other branches
remove ide-scsi
As planed, this removes ide-scsi. The 2.6 kernel supports direct writing to ide CD drives, which eliminates the need for ide-scsi. ide-scsi has been unmaintained and marked as deprecated. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: James.Bottomley@HansenPartnership.com Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Showing 6 changed files with 4 additions and 876 deletions Side-by-side Diff
Documentation/feature-removal-schedule.txt
... | ... | @@ -310,15 +310,6 @@ |
310 | 310 | |
311 | 311 | --------------------------- |
312 | 312 | |
313 | -What: ide-scsi (BLK_DEV_IDESCSI) | |
314 | -When: 2.6.29 | |
315 | -Why: The 2.6 kernel supports direct writing to ide CD drives, which | |
316 | - eliminates the need for ide-scsi. The new method is more | |
317 | - efficient in every way. | |
318 | -Who: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | |
319 | - | |
320 | ---------------------------- | |
321 | - | |
322 | 313 | What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client() |
323 | 314 | When: 2.6.29 (ideally) or 2.6.30 (more likely) |
324 | 315 | Why: Deprecated by the new (standard) device driver binding model. Use |
MAINTAINERS
... | ... | @@ -2146,11 +2146,6 @@ |
2146 | 2146 | L: linux-kernel@vger.kernel.org |
2147 | 2147 | S: Maintained |
2148 | 2148 | |
2149 | -IDE-SCSI DRIVER | |
2150 | -L: linux-ide@vger.kernel.org | |
2151 | -L: linux-scsi@vger.kernel.org | |
2152 | -S: Orphan | |
2153 | - | |
2154 | 2149 | IDLE-I7300 |
2155 | 2150 | P: Andy Henroid |
2156 | 2151 | M: andrew.d.henroid@intel.com |
drivers/ide/Kconfig
... | ... | @@ -185,23 +185,6 @@ |
185 | 185 | To compile this driver as a module, choose M here: the |
186 | 186 | module will be called ide-tape. |
187 | 187 | |
188 | -config BLK_DEV_IDESCSI | |
189 | - tristate "SCSI emulation support (DEPRECATED)" | |
190 | - depends on SCSI | |
191 | - select IDE_ATAPI | |
192 | - ---help--- | |
193 | - WARNING: ide-scsi is no longer needed for cd writing applications! | |
194 | - The 2.6 kernel supports direct writing to ide-cd, which eliminates | |
195 | - the need for ide-scsi + the entire scsi stack just for writing a | |
196 | - cd. The new method is more efficient in every way. | |
197 | - | |
198 | - This will provide SCSI host adapter emulation for IDE ATAPI devices, | |
199 | - and will allow you to use a SCSI device driver instead of a native | |
200 | - ATAPI driver. | |
201 | - | |
202 | - If both this SCSI emulation and native ATAPI support are compiled | |
203 | - into the kernel, the native support will be used. | |
204 | - | |
205 | 188 | config BLK_DEV_IDEACPI |
206 | 189 | bool "IDE ACPI support" |
207 | 190 | depends on ACPI |
drivers/scsi/Kconfig
... | ... | @@ -21,7 +21,7 @@ |
21 | 21 | You also need to say Y here if you have a device which speaks |
22 | 22 | the SCSI protocol. Examples of this include the parallel port |
23 | 23 | version of the IOMEGA ZIP drive, USB storage devices, Fibre |
24 | - Channel, FireWire storage and the IDE-SCSI emulation driver. | |
24 | + Channel, and FireWire storage. | |
25 | 25 | |
26 | 26 | To compile this driver as a module, choose M here and read |
27 | 27 | <file:Documentation/scsi/scsi.txt>. |
... | ... | @@ -101,9 +101,9 @@ |
101 | 101 | ---help--- |
102 | 102 | The OnStream SC-x0 SCSI tape drives cannot be driven by the |
103 | 103 | standard st driver, but instead need this special osst driver and |
104 | - use the /dev/osstX char device nodes (major 206). Via usb-storage | |
105 | - and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives | |
106 | - as well. Note that there is also a second generation of OnStream | |
104 | + use the /dev/osstX char device nodes (major 206). Via usb-storage, | |
105 | + you may be able to drive the USB-x0 and DI-x0 drives as well. | |
106 | + Note that there is also a second generation of OnStream | |
107 | 107 | tape drives (ADR-x0) that supports the standard SCSI-2 commands for |
108 | 108 | tapes (QIC-157) and can be driven by the standard driver st. |
109 | 109 | For more information, you may have a look at the SCSI-HOWTO |
drivers/scsi/Makefile
... | ... | @@ -105,7 +105,6 @@ |
105 | 105 | obj-$(CONFIG_SCSI_INITIO) += initio.o |
106 | 106 | obj-$(CONFIG_SCSI_INIA100) += a100u2w.o |
107 | 107 | obj-$(CONFIG_SCSI_QLOGICPTI) += qlogicpti.o |
108 | -obj-$(CONFIG_BLK_DEV_IDESCSI) += ide-scsi.o | |
109 | 108 | obj-$(CONFIG_SCSI_MESH) += mesh.o |
110 | 109 | obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o |
111 | 110 | obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o |
drivers/scsi/ide-scsi.c
1 | -/* | |
2 | - * Copyright (C) 1996-1999 Gadi Oxman <gadio@netvision.net.il> | |
3 | - * Copyright (C) 2004-2005 Bartlomiej Zolnierkiewicz | |
4 | - */ | |
5 | - | |
6 | -/* | |
7 | - * Emulation of a SCSI host adapter for IDE ATAPI devices. | |
8 | - * | |
9 | - * With this driver, one can use the Linux SCSI drivers instead of the | |
10 | - * native IDE ATAPI drivers. | |
11 | - * | |
12 | - * Ver 0.1 Dec 3 96 Initial version. | |
13 | - * Ver 0.2 Jan 26 97 Fixed bug in cleanup_module() and added emulation | |
14 | - * of MODE_SENSE_6/MODE_SELECT_6 for cdroms. Thanks | |
15 | - * to Janos Farkas for pointing this out. | |
16 | - * Avoid using bitfields in structures for m68k. | |
17 | - * Added Scatter/Gather and DMA support. | |
18 | - * Ver 0.4 Dec 7 97 Add support for ATAPI PD/CD drives. | |
19 | - * Use variable timeout for each command. | |
20 | - * Ver 0.5 Jan 2 98 Fix previous PD/CD support. | |
21 | - * Allow disabling of SCSI-6 to SCSI-10 transformation. | |
22 | - * Ver 0.6 Jan 27 98 Allow disabling of SCSI command translation layer | |
23 | - * for access through /dev/sg. | |
24 | - * Fix MODE_SENSE_6/MODE_SELECT_6/INQUIRY translation. | |
25 | - * Ver 0.7 Dec 04 98 Ignore commands where lun != 0 to avoid multiple | |
26 | - * detection of devices with CONFIG_SCSI_MULTI_LUN | |
27 | - * Ver 0.8 Feb 05 99 Optical media need translation too. Reverse 0.7. | |
28 | - * Ver 0.9 Jul 04 99 Fix a bug in SG_SET_TRANSFORM. | |
29 | - * Ver 0.91 Jun 10 02 Fix "off by one" error in transforms | |
30 | - * Ver 0.92 Dec 31 02 Implement new SCSI mid level API | |
31 | - */ | |
32 | - | |
33 | -#define IDESCSI_VERSION "0.92" | |
34 | - | |
35 | -#include <linux/module.h> | |
36 | -#include <linux/types.h> | |
37 | -#include <linux/string.h> | |
38 | -#include <linux/kernel.h> | |
39 | -#include <linux/mm.h> | |
40 | -#include <linux/ioport.h> | |
41 | -#include <linux/blkdev.h> | |
42 | -#include <linux/errno.h> | |
43 | -#include <linux/slab.h> | |
44 | -#include <linux/ide.h> | |
45 | -#include <linux/scatterlist.h> | |
46 | -#include <linux/delay.h> | |
47 | -#include <linux/mutex.h> | |
48 | -#include <linux/bitops.h> | |
49 | - | |
50 | -#include <asm/io.h> | |
51 | -#include <asm/uaccess.h> | |
52 | - | |
53 | -#include <scsi/scsi.h> | |
54 | -#include <scsi/scsi_cmnd.h> | |
55 | -#include <scsi/scsi_device.h> | |
56 | -#include <scsi/scsi_host.h> | |
57 | -#include <scsi/scsi_tcq.h> | |
58 | -#include <scsi/sg.h> | |
59 | - | |
60 | -#define IDESCSI_DEBUG_LOG 0 | |
61 | - | |
62 | -#if IDESCSI_DEBUG_LOG | |
63 | -#define debug_log(fmt, args...) \ | |
64 | - printk(KERN_INFO "ide-scsi: " fmt, ## args) | |
65 | -#else | |
66 | -#define debug_log(fmt, args...) do {} while (0) | |
67 | -#endif | |
68 | - | |
69 | -/* | |
70 | - * SCSI command transformation layer | |
71 | - */ | |
72 | -#define IDESCSI_SG_TRANSFORM 1 /* /dev/sg transformation */ | |
73 | - | |
74 | -/* | |
75 | - * Log flags | |
76 | - */ | |
77 | -#define IDESCSI_LOG_CMD 0 /* Log SCSI commands */ | |
78 | - | |
79 | -typedef struct ide_scsi_obj { | |
80 | - ide_drive_t *drive; | |
81 | - ide_driver_t *driver; | |
82 | - struct gendisk *disk; | |
83 | - struct Scsi_Host *host; | |
84 | - | |
85 | - unsigned long transform; /* SCSI cmd translation layer */ | |
86 | - unsigned long log; /* log flags */ | |
87 | -} idescsi_scsi_t; | |
88 | - | |
89 | -static DEFINE_MUTEX(idescsi_ref_mutex); | |
90 | -/* Set by module param to skip cd */ | |
91 | -static int idescsi_nocd; | |
92 | - | |
93 | -#define ide_scsi_g(disk) \ | |
94 | - container_of((disk)->private_data, struct ide_scsi_obj, driver) | |
95 | - | |
96 | -static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk) | |
97 | -{ | |
98 | - struct ide_scsi_obj *scsi = NULL; | |
99 | - | |
100 | - mutex_lock(&idescsi_ref_mutex); | |
101 | - scsi = ide_scsi_g(disk); | |
102 | - if (scsi) { | |
103 | - if (ide_device_get(scsi->drive)) | |
104 | - scsi = NULL; | |
105 | - else | |
106 | - scsi_host_get(scsi->host); | |
107 | - } | |
108 | - mutex_unlock(&idescsi_ref_mutex); | |
109 | - return scsi; | |
110 | -} | |
111 | - | |
112 | -static void ide_scsi_put(struct ide_scsi_obj *scsi) | |
113 | -{ | |
114 | - ide_drive_t *drive = scsi->drive; | |
115 | - | |
116 | - mutex_lock(&idescsi_ref_mutex); | |
117 | - scsi_host_put(scsi->host); | |
118 | - ide_device_put(drive); | |
119 | - mutex_unlock(&idescsi_ref_mutex); | |
120 | -} | |
121 | - | |
122 | -static inline idescsi_scsi_t *scsihost_to_idescsi(struct Scsi_Host *host) | |
123 | -{ | |
124 | - return (idescsi_scsi_t*) (&host[1]); | |
125 | -} | |
126 | - | |
127 | -static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive) | |
128 | -{ | |
129 | - return scsihost_to_idescsi(ide_drive->driver_data); | |
130 | -} | |
131 | - | |
132 | -static void ide_scsi_hex_dump(u8 *data, int len) | |
133 | -{ | |
134 | - print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0); | |
135 | -} | |
136 | - | |
137 | -static int idescsi_end_request(ide_drive_t *, int, int); | |
138 | - | |
139 | -static void ide_scsi_callback(ide_drive_t *drive, int dsc) | |
140 | -{ | |
141 | - idescsi_scsi_t *scsi = drive_to_idescsi(drive); | |
142 | - struct ide_atapi_pc *pc = drive->pc; | |
143 | - | |
144 | - if (pc->flags & PC_FLAG_TIMEDOUT) | |
145 | - debug_log("%s: got timed out packet %lu at %lu\n", __func__, | |
146 | - pc->scsi_cmd->serial_number, jiffies); | |
147 | - /* end this request now - scsi should retry it*/ | |
148 | - else if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | |
149 | - printk(KERN_INFO "Packet command completed, %d bytes" | |
150 | - " transferred\n", pc->xferred); | |
151 | - | |
152 | - idescsi_end_request(drive, 1, 0); | |
153 | -} | |
154 | - | |
155 | -static int idescsi_check_condition(ide_drive_t *drive, | |
156 | - struct request *failed_cmd) | |
157 | -{ | |
158 | - idescsi_scsi_t *scsi = drive_to_idescsi(drive); | |
159 | - struct ide_atapi_pc *pc; | |
160 | - struct request *rq; | |
161 | - u8 *buf; | |
162 | - | |
163 | - /* stuff a sense request in front of our current request */ | |
164 | - pc = kzalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC); | |
165 | - rq = blk_get_request(drive->queue, READ, GFP_ATOMIC); | |
166 | - buf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC); | |
167 | - if (!pc || !rq || !buf) { | |
168 | - kfree(buf); | |
169 | - if (rq) | |
170 | - blk_put_request(rq); | |
171 | - kfree(pc); | |
172 | - return -ENOMEM; | |
173 | - } | |
174 | - rq->special = (char *) pc; | |
175 | - pc->rq = rq; | |
176 | - pc->buf = buf; | |
177 | - pc->c[0] = REQUEST_SENSE; | |
178 | - pc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE; | |
179 | - rq->cmd_type = REQ_TYPE_SENSE; | |
180 | - rq->cmd_flags |= REQ_PREEMPT; | |
181 | - pc->timeout = jiffies + WAIT_READY; | |
182 | - /* NOTE! Save the failed packet command in "rq->buffer" */ | |
183 | - rq->buffer = (void *) failed_cmd->special; | |
184 | - pc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd; | |
185 | - if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { | |
186 | - printk ("ide-scsi: %s: queue cmd = ", drive->name); | |
187 | - ide_scsi_hex_dump(pc->c, 6); | |
188 | - } | |
189 | - rq->rq_disk = scsi->disk; | |
190 | - rq->ref_count++; | |
191 | - memcpy(rq->cmd, pc->c, 12); | |
192 | - ide_do_drive_cmd(drive, rq); | |
193 | - return 0; | |
194 | -} | |
195 | - | |
196 | -static ide_startstop_t | |
197 | -idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | |
198 | -{ | |
199 | - ide_hwif_t *hwif = drive->hwif; | |
200 | - | |
201 | - if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ)) | |
202 | - /* force an abort */ | |
203 | - hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE); | |
204 | - | |
205 | - rq->errors++; | |
206 | - | |
207 | - idescsi_end_request(drive, 0, 0); | |
208 | - | |
209 | - return ide_stopped; | |
210 | -} | |
211 | - | |
212 | -static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) | |
213 | -{ | |
214 | - idescsi_scsi_t *scsi = drive_to_idescsi(drive); | |
215 | - struct request *rq = HWGROUP(drive)->rq; | |
216 | - struct ide_atapi_pc *pc = (struct ide_atapi_pc *) rq->special; | |
217 | - int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); | |
218 | - struct Scsi_Host *host; | |
219 | - int errors = rq->errors; | |
220 | - unsigned long flags; | |
221 | - | |
222 | - if (!blk_special_request(rq) && !blk_sense_request(rq)) { | |
223 | - ide_end_request(drive, uptodate, nrsecs); | |
224 | - return 0; | |
225 | - } | |
226 | - ide_end_drive_cmd (drive, 0, 0); | |
227 | - if (blk_sense_request(rq)) { | |
228 | - struct ide_atapi_pc *opc = (struct ide_atapi_pc *) rq->buffer; | |
229 | - if (log) { | |
230 | - printk ("ide-scsi: %s: wrap up check %lu, rst = ", drive->name, opc->scsi_cmd->serial_number); | |
231 | - ide_scsi_hex_dump(pc->buf, 16); | |
232 | - } | |
233 | - memcpy((void *) opc->scsi_cmd->sense_buffer, pc->buf, | |
234 | - SCSI_SENSE_BUFFERSIZE); | |
235 | - kfree(pc->buf); | |
236 | - kfree(pc); | |
237 | - blk_put_request(rq); | |
238 | - pc = opc; | |
239 | - rq = pc->rq; | |
240 | - pc->scsi_cmd->result = (CHECK_CONDITION << 1) | | |
241 | - (((pc->flags & PC_FLAG_TIMEDOUT) ? | |
242 | - DID_TIME_OUT : | |
243 | - DID_OK) << 16); | |
244 | - } else if (pc->flags & PC_FLAG_TIMEDOUT) { | |
245 | - if (log) | |
246 | - printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n", | |
247 | - drive->name, pc->scsi_cmd->serial_number); | |
248 | - pc->scsi_cmd->result = DID_TIME_OUT << 16; | |
249 | - } else if (errors >= ERROR_MAX) { | |
250 | - pc->scsi_cmd->result = DID_ERROR << 16; | |
251 | - if (log) | |
252 | - printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number); | |
253 | - } else if (errors) { | |
254 | - if (log) | |
255 | - printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number); | |
256 | - if (!idescsi_check_condition(drive, rq)) | |
257 | - /* we started a request sense, so we'll be back, exit for now */ | |
258 | - return 0; | |
259 | - pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16); | |
260 | - } else { | |
261 | - pc->scsi_cmd->result = DID_OK << 16; | |
262 | - } | |
263 | - host = pc->scsi_cmd->device->host; | |
264 | - spin_lock_irqsave(host->host_lock, flags); | |
265 | - pc->done(pc->scsi_cmd); | |
266 | - spin_unlock_irqrestore(host->host_lock, flags); | |
267 | - kfree(pc); | |
268 | - blk_put_request(rq); | |
269 | - drive->pc = NULL; | |
270 | - return 0; | |
271 | -} | |
272 | - | |
273 | -static inline int idescsi_set_direction(struct ide_atapi_pc *pc) | |
274 | -{ | |
275 | - switch (pc->c[0]) { | |
276 | - case READ_6: case READ_10: case READ_12: | |
277 | - pc->flags &= ~PC_FLAG_WRITING; | |
278 | - return 0; | |
279 | - case WRITE_6: case WRITE_10: case WRITE_12: | |
280 | - pc->flags |= PC_FLAG_WRITING; | |
281 | - return 0; | |
282 | - default: | |
283 | - return 1; | |
284 | - } | |
285 | -} | |
286 | - | |
287 | -static int idescsi_map_sg(ide_drive_t *drive, struct ide_atapi_pc *pc) | |
288 | -{ | |
289 | - ide_hwif_t *hwif = drive->hwif; | |
290 | - struct scatterlist *sg, *scsi_sg; | |
291 | - int segments; | |
292 | - | |
293 | - if (!pc->req_xfer || pc->req_xfer % 1024) | |
294 | - return 1; | |
295 | - | |
296 | - if (idescsi_set_direction(pc)) | |
297 | - return 1; | |
298 | - | |
299 | - sg = hwif->sg_table; | |
300 | - scsi_sg = scsi_sglist(pc->scsi_cmd); | |
301 | - segments = scsi_sg_count(pc->scsi_cmd); | |
302 | - | |
303 | - if (segments > hwif->sg_max_nents) | |
304 | - return 1; | |
305 | - | |
306 | - hwif->sg_nents = segments; | |
307 | - memcpy(sg, scsi_sg, sizeof(*sg) * segments); | |
308 | - | |
309 | - return 0; | |
310 | -} | |
311 | - | |
312 | -static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, | |
313 | - struct ide_atapi_pc *pc) | |
314 | -{ | |
315 | - /* Set the current packet command */ | |
316 | - drive->pc = pc; | |
317 | - | |
318 | - return ide_issue_pc(drive, ide_scsi_get_timeout(pc), ide_scsi_expiry); | |
319 | -} | |
320 | - | |
321 | -/* | |
322 | - * idescsi_do_request is our request handling function. | |
323 | - */ | |
324 | -static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block) | |
325 | -{ | |
326 | - debug_log("dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name, | |
327 | - rq->cmd[0], rq->errors); | |
328 | - debug_log("sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n", | |
329 | - rq->sector, rq->nr_sectors, rq->current_nr_sectors); | |
330 | - | |
331 | - if (blk_sense_request(rq) || blk_special_request(rq)) { | |
332 | - struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special; | |
333 | - | |
334 | - if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && | |
335 | - idescsi_map_sg(drive, pc) == 0) | |
336 | - pc->flags |= PC_FLAG_DMA_OK; | |
337 | - | |
338 | - return idescsi_issue_pc(drive, pc); | |
339 | - } | |
340 | - blk_dump_rq_flags(rq, "ide-scsi: unsup command"); | |
341 | - idescsi_end_request (drive, 0, 0); | |
342 | - return ide_stopped; | |
343 | -} | |
344 | - | |
345 | -#ifdef CONFIG_IDE_PROC_FS | |
346 | -static ide_proc_entry_t idescsi_proc[] = { | |
347 | - { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL }, | |
348 | - { NULL, 0, NULL, NULL } | |
349 | -}; | |
350 | - | |
351 | -#define ide_scsi_devset_get(name, field) \ | |
352 | -static int get_##name(ide_drive_t *drive) \ | |
353 | -{ \ | |
354 | - idescsi_scsi_t *scsi = drive_to_idescsi(drive); \ | |
355 | - return scsi->field; \ | |
356 | -} | |
357 | - | |
358 | -#define ide_scsi_devset_set(name, field) \ | |
359 | -static int set_##name(ide_drive_t *drive, int arg) \ | |
360 | -{ \ | |
361 | - idescsi_scsi_t *scsi = drive_to_idescsi(drive); \ | |
362 | - scsi->field = arg; \ | |
363 | - return 0; \ | |
364 | -} | |
365 | - | |
366 | -#define ide_scsi_devset_rw_field(_name, _field) \ | |
367 | -ide_scsi_devset_get(_name, _field); \ | |
368 | -ide_scsi_devset_set(_name, _field); \ | |
369 | -IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name); | |
370 | - | |
371 | -ide_devset_rw_field(bios_cyl, bios_cyl); | |
372 | -ide_devset_rw_field(bios_head, bios_head); | |
373 | -ide_devset_rw_field(bios_sect, bios_sect); | |
374 | - | |
375 | -ide_scsi_devset_rw_field(transform, transform); | |
376 | -ide_scsi_devset_rw_field(log, log); | |
377 | - | |
378 | -static const struct ide_proc_devset idescsi_settings[] = { | |
379 | - IDE_PROC_DEVSET(bios_cyl, 0, 1023), | |
380 | - IDE_PROC_DEVSET(bios_head, 0, 255), | |
381 | - IDE_PROC_DEVSET(bios_sect, 0, 63), | |
382 | - IDE_PROC_DEVSET(log, 0, 1), | |
383 | - IDE_PROC_DEVSET(transform, 0, 3), | |
384 | - { 0 }, | |
385 | -}; | |
386 | - | |
387 | -static ide_proc_entry_t *ide_scsi_proc_entries(ide_drive_t *drive) | |
388 | -{ | |
389 | - return idescsi_proc; | |
390 | -} | |
391 | - | |
392 | -static const struct ide_proc_devset *ide_scsi_proc_devsets(ide_drive_t *drive) | |
393 | -{ | |
394 | - return idescsi_settings; | |
395 | -} | |
396 | -#endif | |
397 | - | |
398 | -/* | |
399 | - * Driver initialization. | |
400 | - */ | |
401 | -static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) | |
402 | -{ | |
403 | - clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); | |
404 | -#if IDESCSI_DEBUG_LOG | |
405 | - set_bit(IDESCSI_LOG_CMD, &scsi->log); | |
406 | -#endif /* IDESCSI_DEBUG_LOG */ | |
407 | - | |
408 | - drive->pc_callback = ide_scsi_callback; | |
409 | - drive->pc_update_buffers = NULL; | |
410 | - drive->pc_io_buffers = ide_io_buffers; | |
411 | - | |
412 | - ide_proc_register_driver(drive, scsi->driver); | |
413 | -} | |
414 | - | |
415 | -static void ide_scsi_remove(ide_drive_t *drive) | |
416 | -{ | |
417 | - struct Scsi_Host *scsihost = drive->driver_data; | |
418 | - struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); | |
419 | - struct gendisk *g = scsi->disk; | |
420 | - | |
421 | - scsi_remove_host(scsihost); | |
422 | - ide_proc_unregister_driver(drive, scsi->driver); | |
423 | - | |
424 | - ide_unregister_region(g); | |
425 | - | |
426 | - drive->driver_data = NULL; | |
427 | - g->private_data = NULL; | |
428 | - put_disk(g); | |
429 | - | |
430 | - ide_scsi_put(scsi); | |
431 | - | |
432 | - drive->dev_flags &= ~IDE_DFLAG_SCSI; | |
433 | -} | |
434 | - | |
435 | -static int ide_scsi_probe(ide_drive_t *); | |
436 | - | |
437 | -static ide_driver_t idescsi_driver = { | |
438 | - .gen_driver = { | |
439 | - .owner = THIS_MODULE, | |
440 | - .name = "ide-scsi", | |
441 | - .bus = &ide_bus_type, | |
442 | - }, | |
443 | - .probe = ide_scsi_probe, | |
444 | - .remove = ide_scsi_remove, | |
445 | - .version = IDESCSI_VERSION, | |
446 | - .do_request = idescsi_do_request, | |
447 | - .end_request = idescsi_end_request, | |
448 | - .error = idescsi_atapi_error, | |
449 | -#ifdef CONFIG_IDE_PROC_FS | |
450 | - .proc_entries = ide_scsi_proc_entries, | |
451 | - .proc_devsets = ide_scsi_proc_devsets, | |
452 | -#endif | |
453 | -}; | |
454 | - | |
455 | -static int idescsi_ide_open(struct block_device *bdev, fmode_t mode) | |
456 | -{ | |
457 | - struct ide_scsi_obj *scsi = ide_scsi_get(bdev->bd_disk); | |
458 | - | |
459 | - if (!scsi) | |
460 | - return -ENXIO; | |
461 | - | |
462 | - return 0; | |
463 | -} | |
464 | - | |
465 | -static int idescsi_ide_release(struct gendisk *disk, fmode_t mode) | |
466 | -{ | |
467 | - ide_scsi_put(ide_scsi_g(disk)); | |
468 | - return 0; | |
469 | -} | |
470 | - | |
471 | -static int idescsi_ide_ioctl(struct block_device *bdev, fmode_t mode, | |
472 | - unsigned int cmd, unsigned long arg) | |
473 | -{ | |
474 | - struct ide_scsi_obj *scsi = ide_scsi_g(bdev->bd_disk); | |
475 | - return generic_ide_ioctl(scsi->drive, bdev, cmd, arg); | |
476 | -} | |
477 | - | |
478 | -static struct block_device_operations idescsi_ops = { | |
479 | - .owner = THIS_MODULE, | |
480 | - .open = idescsi_ide_open, | |
481 | - .release = idescsi_ide_release, | |
482 | - .locked_ioctl = idescsi_ide_ioctl, | |
483 | -}; | |
484 | - | |
485 | -static int idescsi_slave_configure(struct scsi_device * sdp) | |
486 | -{ | |
487 | - /* Configure detected device */ | |
488 | - sdp->use_10_for_rw = 1; | |
489 | - sdp->use_10_for_ms = 1; | |
490 | - scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun); | |
491 | - return 0; | |
492 | -} | |
493 | - | |
494 | -static const char *idescsi_info (struct Scsi_Host *host) | |
495 | -{ | |
496 | - return "SCSI host adapter emulation for IDE ATAPI devices"; | |
497 | -} | |
498 | - | |
499 | -static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg) | |
500 | -{ | |
501 | - idescsi_scsi_t *scsi = scsihost_to_idescsi(dev->host); | |
502 | - | |
503 | - if (cmd == SG_SET_TRANSFORM) { | |
504 | - if (arg) | |
505 | - set_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); | |
506 | - else | |
507 | - clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); | |
508 | - return 0; | |
509 | - } else if (cmd == SG_GET_TRANSFORM) | |
510 | - return put_user(test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform), (int __user *) arg); | |
511 | - return -EINVAL; | |
512 | -} | |
513 | - | |
514 | -static int idescsi_queue (struct scsi_cmnd *cmd, | |
515 | - void (*done)(struct scsi_cmnd *)) | |
516 | -{ | |
517 | - struct Scsi_Host *host = cmd->device->host; | |
518 | - idescsi_scsi_t *scsi = scsihost_to_idescsi(host); | |
519 | - ide_drive_t *drive = scsi->drive; | |
520 | - struct request *rq = NULL; | |
521 | - struct ide_atapi_pc *pc = NULL; | |
522 | - int write = cmd->sc_data_direction == DMA_TO_DEVICE; | |
523 | - | |
524 | - if (!drive) { | |
525 | - scmd_printk (KERN_ERR, cmd, "drive not present\n"); | |
526 | - goto abort; | |
527 | - } | |
528 | - scsi = drive_to_idescsi(drive); | |
529 | - pc = kmalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC); | |
530 | - rq = blk_get_request(drive->queue, write, GFP_ATOMIC); | |
531 | - if (rq == NULL || pc == NULL) { | |
532 | - printk (KERN_ERR "ide-scsi: %s: out of memory\n", drive->name); | |
533 | - goto abort; | |
534 | - } | |
535 | - | |
536 | - memset (pc->c, 0, 12); | |
537 | - pc->flags = 0; | |
538 | - if (cmd->sc_data_direction == DMA_TO_DEVICE) | |
539 | - pc->flags |= PC_FLAG_WRITING; | |
540 | - pc->rq = rq; | |
541 | - memcpy (pc->c, cmd->cmnd, cmd->cmd_len); | |
542 | - pc->buf = NULL; | |
543 | - pc->sg = scsi_sglist(cmd); | |
544 | - pc->sg_cnt = scsi_sg_count(cmd); | |
545 | - pc->b_count = 0; | |
546 | - pc->req_xfer = pc->buf_size = scsi_bufflen(cmd); | |
547 | - pc->scsi_cmd = cmd; | |
548 | - pc->done = done; | |
549 | - pc->timeout = jiffies + cmd->request->timeout; | |
550 | - | |
551 | - if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { | |
552 | - printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number); | |
553 | - ide_scsi_hex_dump(cmd->cmnd, cmd->cmd_len); | |
554 | - if (memcmp(pc->c, cmd->cmnd, cmd->cmd_len)) { | |
555 | - printk ("ide-scsi: %s: que %lu, tsl = ", drive->name, cmd->serial_number); | |
556 | - ide_scsi_hex_dump(pc->c, 12); | |
557 | - } | |
558 | - } | |
559 | - | |
560 | - rq->special = (char *) pc; | |
561 | - rq->cmd_type = REQ_TYPE_SPECIAL; | |
562 | - spin_unlock_irq(host->host_lock); | |
563 | - rq->ref_count++; | |
564 | - memcpy(rq->cmd, pc->c, 12); | |
565 | - blk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL); | |
566 | - spin_lock_irq(host->host_lock); | |
567 | - return 0; | |
568 | -abort: | |
569 | - kfree (pc); | |
570 | - if (rq) | |
571 | - blk_put_request(rq); | |
572 | - cmd->result = DID_ERROR << 16; | |
573 | - done(cmd); | |
574 | - return 0; | |
575 | -} | |
576 | - | |
577 | -static int idescsi_eh_abort (struct scsi_cmnd *cmd) | |
578 | -{ | |
579 | - idescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host); | |
580 | - ide_drive_t *drive = scsi->drive; | |
581 | - ide_hwif_t *hwif; | |
582 | - ide_hwgroup_t *hwgroup; | |
583 | - int busy; | |
584 | - int ret = FAILED; | |
585 | - | |
586 | - struct ide_atapi_pc *pc; | |
587 | - | |
588 | - /* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */ | |
589 | - | |
590 | - if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | |
591 | - printk (KERN_WARNING "ide-scsi: abort called for %lu\n", cmd->serial_number); | |
592 | - | |
593 | - if (!drive) { | |
594 | - printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_abort\n"); | |
595 | - WARN_ON(1); | |
596 | - goto no_drive; | |
597 | - } | |
598 | - | |
599 | - hwif = drive->hwif; | |
600 | - hwgroup = hwif->hwgroup; | |
601 | - | |
602 | - /* First give it some more time, how much is "right" is hard to say :-( | |
603 | - FIXME - uses mdelay which causes latency? */ | |
604 | - busy = ide_wait_not_busy(hwif, 100); | |
605 | - if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | |
606 | - printk (KERN_WARNING "ide-scsi: drive did%s become ready\n", busy?" not":""); | |
607 | - | |
608 | - spin_lock_irq(&hwgroup->lock); | |
609 | - | |
610 | - /* If there is no pc running we're done (our interrupt took care of it) */ | |
611 | - pc = drive->pc; | |
612 | - if (pc == NULL) { | |
613 | - ret = SUCCESS; | |
614 | - goto ide_unlock; | |
615 | - } | |
616 | - | |
617 | - /* It's somewhere in flight. Does ide subsystem agree? */ | |
618 | - if (pc->scsi_cmd->serial_number == cmd->serial_number && !busy && | |
619 | - elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != pc->rq) { | |
620 | - /* | |
621 | - * FIXME - not sure this condition can ever occur | |
622 | - */ | |
623 | - printk (KERN_ERR "ide-scsi: cmd aborted!\n"); | |
624 | - | |
625 | - if (blk_sense_request(pc->rq)) | |
626 | - kfree(pc->buf); | |
627 | - /* we need to call blk_put_request twice. */ | |
628 | - blk_put_request(pc->rq); | |
629 | - blk_put_request(pc->rq); | |
630 | - kfree(pc); | |
631 | - drive->pc = NULL; | |
632 | - | |
633 | - ret = SUCCESS; | |
634 | - } | |
635 | - | |
636 | -ide_unlock: | |
637 | - spin_unlock_irq(&hwgroup->lock); | |
638 | -no_drive: | |
639 | - if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | |
640 | - printk (KERN_WARNING "ide-scsi: abort returns %s\n", ret == SUCCESS?"success":"failed"); | |
641 | - | |
642 | - return ret; | |
643 | -} | |
644 | - | |
645 | -static int idescsi_eh_reset (struct scsi_cmnd *cmd) | |
646 | -{ | |
647 | - struct request *req; | |
648 | - idescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host); | |
649 | - ide_drive_t *drive = scsi->drive; | |
650 | - ide_hwgroup_t *hwgroup; | |
651 | - int ready = 0; | |
652 | - int ret = SUCCESS; | |
653 | - | |
654 | - struct ide_atapi_pc *pc; | |
655 | - | |
656 | - /* In idescsi_eh_reset we forcefully remove the command from the ide subsystem and reset the device. */ | |
657 | - | |
658 | - if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | |
659 | - printk (KERN_WARNING "ide-scsi: reset called for %lu\n", cmd->serial_number); | |
660 | - | |
661 | - if (!drive) { | |
662 | - printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_reset\n"); | |
663 | - WARN_ON(1); | |
664 | - return FAILED; | |
665 | - } | |
666 | - | |
667 | - hwgroup = drive->hwif->hwgroup; | |
668 | - | |
669 | - spin_lock_irq(cmd->device->host->host_lock); | |
670 | - spin_lock(&hwgroup->lock); | |
671 | - | |
672 | - pc = drive->pc; | |
673 | - if (pc) | |
674 | - req = pc->rq; | |
675 | - | |
676 | - if (pc == NULL || req != hwgroup->rq || hwgroup->handler == NULL) { | |
677 | - printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n"); | |
678 | - spin_unlock(&hwgroup->lock); | |
679 | - spin_unlock_irq(cmd->device->host->host_lock); | |
680 | - return FAILED; | |
681 | - } | |
682 | - | |
683 | - /* kill current request */ | |
684 | - if (__blk_end_request(req, -EIO, 0)) | |
685 | - BUG(); | |
686 | - if (blk_sense_request(req)) | |
687 | - kfree(pc->buf); | |
688 | - kfree(pc); | |
689 | - drive->pc = NULL; | |
690 | - blk_put_request(req); | |
691 | - | |
692 | - /* now nuke the drive queue */ | |
693 | - while ((req = elv_next_request(drive->queue))) { | |
694 | - if (__blk_end_request(req, -EIO, 0)) | |
695 | - BUG(); | |
696 | - } | |
697 | - | |
698 | - hwgroup->rq = NULL; | |
699 | - hwgroup->handler = NULL; | |
700 | - hwgroup->busy = 1; /* will set this to zero when ide reset finished */ | |
701 | - spin_unlock(&hwgroup->lock); | |
702 | - | |
703 | - ide_do_reset(drive); | |
704 | - | |
705 | - /* ide_do_reset starts a polling handler which restarts itself every 50ms until the reset finishes */ | |
706 | - | |
707 | - do { | |
708 | - spin_unlock_irq(cmd->device->host->host_lock); | |
709 | - msleep(50); | |
710 | - spin_lock_irq(cmd->device->host->host_lock); | |
711 | - } while ( HWGROUP(drive)->handler ); | |
712 | - | |
713 | - ready = drive_is_ready(drive); | |
714 | - HWGROUP(drive)->busy--; | |
715 | - if (!ready) { | |
716 | - printk (KERN_ERR "ide-scsi: reset failed!\n"); | |
717 | - ret = FAILED; | |
718 | - } | |
719 | - | |
720 | - spin_unlock_irq(cmd->device->host->host_lock); | |
721 | - return ret; | |
722 | -} | |
723 | - | |
724 | -static int idescsi_bios(struct scsi_device *sdev, struct block_device *bdev, | |
725 | - sector_t capacity, int *parm) | |
726 | -{ | |
727 | - idescsi_scsi_t *idescsi = scsihost_to_idescsi(sdev->host); | |
728 | - ide_drive_t *drive = idescsi->drive; | |
729 | - | |
730 | - if (drive->bios_cyl && drive->bios_head && drive->bios_sect) { | |
731 | - parm[0] = drive->bios_head; | |
732 | - parm[1] = drive->bios_sect; | |
733 | - parm[2] = drive->bios_cyl; | |
734 | - } | |
735 | - return 0; | |
736 | -} | |
737 | - | |
738 | -static struct scsi_host_template idescsi_template = { | |
739 | - .module = THIS_MODULE, | |
740 | - .name = "idescsi", | |
741 | - .info = idescsi_info, | |
742 | - .slave_configure = idescsi_slave_configure, | |
743 | - .ioctl = idescsi_ioctl, | |
744 | - .queuecommand = idescsi_queue, | |
745 | - .eh_abort_handler = idescsi_eh_abort, | |
746 | - .eh_host_reset_handler = idescsi_eh_reset, | |
747 | - .bios_param = idescsi_bios, | |
748 | - .can_queue = 40, | |
749 | - .this_id = -1, | |
750 | - .sg_tablesize = 256, | |
751 | - .cmd_per_lun = 5, | |
752 | - .max_sectors = 128, | |
753 | - .use_clustering = DISABLE_CLUSTERING, | |
754 | - .emulated = 1, | |
755 | - .proc_name = "ide-scsi", | |
756 | -}; | |
757 | - | |
758 | -static int ide_scsi_probe(ide_drive_t *drive) | |
759 | -{ | |
760 | - idescsi_scsi_t *idescsi; | |
761 | - struct Scsi_Host *host; | |
762 | - struct gendisk *g; | |
763 | - static int warned; | |
764 | - int err = -ENOMEM; | |
765 | - u16 last_lun; | |
766 | - | |
767 | - if (!warned && drive->media == ide_cdrom) { | |
768 | - printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n"); | |
769 | - warned = 1; | |
770 | - } | |
771 | - | |
772 | - if (idescsi_nocd && drive->media == ide_cdrom) | |
773 | - return -ENODEV; | |
774 | - | |
775 | - if (!strstr("ide-scsi", drive->driver_req) || | |
776 | - drive->media == ide_disk || | |
777 | - !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) | |
778 | - return -ENODEV; | |
779 | - | |
780 | - drive->dev_flags |= IDE_DFLAG_SCSI; | |
781 | - | |
782 | - g = alloc_disk(1 << PARTN_BITS); | |
783 | - if (!g) | |
784 | - goto out_host_put; | |
785 | - | |
786 | - ide_init_disk(g, drive); | |
787 | - | |
788 | - host->max_id = 1; | |
789 | - | |
790 | - last_lun = drive->id[ATA_ID_LAST_LUN]; | |
791 | - if (last_lun) | |
792 | - debug_log("%s: last_lun=%u\n", drive->name, last_lun); | |
793 | - | |
794 | - if ((last_lun & 7) != 7) | |
795 | - host->max_lun = (last_lun & 7) + 1; | |
796 | - else | |
797 | - host->max_lun = 1; | |
798 | - | |
799 | - drive->driver_data = host; | |
800 | - idescsi = scsihost_to_idescsi(host); | |
801 | - idescsi->drive = drive; | |
802 | - idescsi->driver = &idescsi_driver; | |
803 | - idescsi->host = host; | |
804 | - idescsi->disk = g; | |
805 | - g->private_data = &idescsi->driver; | |
806 | - err = 0; | |
807 | - idescsi_setup(drive, idescsi); | |
808 | - g->fops = &idescsi_ops; | |
809 | - ide_register_region(g); | |
810 | - err = scsi_add_host(host, &drive->gendev); | |
811 | - if (!err) { | |
812 | - scsi_scan_host(host); | |
813 | - return 0; | |
814 | - } | |
815 | - /* fall through on error */ | |
816 | - ide_unregister_region(g); | |
817 | - ide_proc_unregister_driver(drive, &idescsi_driver); | |
818 | - | |
819 | - put_disk(g); | |
820 | -out_host_put: | |
821 | - drive->dev_flags &= ~IDE_DFLAG_SCSI; | |
822 | - scsi_host_put(host); | |
823 | - return err; | |
824 | -} | |
825 | - | |
826 | -static int __init init_idescsi_module(void) | |
827 | -{ | |
828 | - return driver_register(&idescsi_driver.gen_driver); | |
829 | -} | |
830 | - | |
831 | -static void __exit exit_idescsi_module(void) | |
832 | -{ | |
833 | - driver_unregister(&idescsi_driver.gen_driver); | |
834 | -} | |
835 | - | |
836 | -module_param(idescsi_nocd, int, 0600); | |
837 | -MODULE_PARM_DESC(idescsi_nocd, "Disable handling of CD-ROMs so they may be driven by ide-cd"); | |
838 | -module_init(init_idescsi_module); | |
839 | -module_exit(exit_idescsi_module); | |
840 | -MODULE_LICENSE("GPL"); |