diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-12-20 17:39:47 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-12-20 17:39:47 -0500 |
commit | 55fa518867978e1f5fd8353098f80d125ac734d7 (patch) | |
tree | 3502b331c1f9ec4cac25dc8ba30b6a0a324e350c /drivers/ide/ide-floppy.c | |
parent | bb1f24bf00a85f666b56a09b7cdbfd221af16c2c (diff) | |
parent | eea0579fc85e64e9f05361d5aacf496fe7a151aa (diff) |
Merge branch 'topic/pcsp-fix' into topic/misc
Diffstat (limited to 'drivers/ide/ide-floppy.c')
-rw-r--r-- | drivers/ide/ide-floppy.c | 1197 |
1 files changed, 159 insertions, 1038 deletions
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index e9034c0125f3..aeb1ad782f54 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -15,9 +15,6 @@ | |||
15 | * Documentation/ide/ChangeLog.ide-floppy.1996-2002 | 15 | * Documentation/ide/ChangeLog.ide-floppy.1996-2002 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #define IDEFLOPPY_VERSION "1.00" | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/types.h> | 18 | #include <linux/types.h> |
22 | #include <linux/string.h> | 19 | #include <linux/string.h> |
23 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
@@ -31,8 +28,10 @@ | |||
31 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
32 | #include <linux/cdrom.h> | 29 | #include <linux/cdrom.h> |
33 | #include <linux/ide.h> | 30 | #include <linux/ide.h> |
31 | #include <linux/hdreg.h> | ||
34 | #include <linux/bitops.h> | 32 | #include <linux/bitops.h> |
35 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
34 | #include <linux/scatterlist.h> | ||
36 | 35 | ||
37 | #include <scsi/scsi_ioctl.h> | 36 | #include <scsi/scsi_ioctl.h> |
38 | 37 | ||
@@ -42,22 +41,7 @@ | |||
42 | #include <linux/io.h> | 41 | #include <linux/io.h> |
43 | #include <asm/unaligned.h> | 42 | #include <asm/unaligned.h> |
44 | 43 | ||
45 | /* define to see debug info */ | 44 | #include "ide-floppy.h" |
46 | #define IDEFLOPPY_DEBUG_LOG 0 | ||
47 | |||
48 | /* #define IDEFLOPPY_DEBUG(fmt, args...) printk(KERN_INFO fmt, ## args) */ | ||
49 | #define IDEFLOPPY_DEBUG(fmt, args...) | ||
50 | |||
51 | #if IDEFLOPPY_DEBUG_LOG | ||
52 | #define debug_log(fmt, args...) \ | ||
53 | printk(KERN_INFO "ide-floppy: " fmt, ## args) | ||
54 | #else | ||
55 | #define debug_log(fmt, args...) do {} while (0) | ||
56 | #endif | ||
57 | |||
58 | |||
59 | /* Some drives require a longer irq timeout. */ | ||
60 | #define IDEFLOPPY_WAIT_CMD (5 * WAIT_CMD) | ||
61 | 45 | ||
62 | /* | 46 | /* |
63 | * After each failed packet command we issue a request sense command and retry | 47 | * After each failed packet command we issue a request sense command and retry |
@@ -65,19 +49,6 @@ | |||
65 | */ | 49 | */ |
66 | #define IDEFLOPPY_MAX_PC_RETRIES 3 | 50 | #define IDEFLOPPY_MAX_PC_RETRIES 3 |
67 | 51 | ||
68 | /* | ||
69 | * With each packet command, we allocate a buffer of IDEFLOPPY_PC_BUFFER_SIZE | ||
70 | * bytes. | ||
71 | */ | ||
72 | #define IDEFLOPPY_PC_BUFFER_SIZE 256 | ||
73 | |||
74 | /* | ||
75 | * In various places in the driver, we need to allocate storage for packet | ||
76 | * commands and requests, which will remain valid while we leave the driver to | ||
77 | * wait for an interrupt or a timeout event. | ||
78 | */ | ||
79 | #define IDEFLOPPY_PC_STACK (10 + IDEFLOPPY_MAX_PC_RETRIES) | ||
80 | |||
81 | /* format capacities descriptor codes */ | 52 | /* format capacities descriptor codes */ |
82 | #define CAPACITY_INVALID 0x00 | 53 | #define CAPACITY_INVALID 0x00 |
83 | #define CAPACITY_UNFORMATTED 0x01 | 54 | #define CAPACITY_UNFORMATTED 0x01 |
@@ -85,124 +56,39 @@ | |||
85 | #define CAPACITY_NO_CARTRIDGE 0x03 | 56 | #define CAPACITY_NO_CARTRIDGE 0x03 |
86 | 57 | ||
87 | /* | 58 | /* |
88 | * Most of our global data which we need to save even as we leave the driver | 59 | * The following delay solves a problem with ATAPI Zip 100 drive where BSY bit |
89 | * due to an interrupt or a timer event is stored in a variable of type | 60 | * was apparently being deasserted before the unit was ready to receive data. |
90 | * idefloppy_floppy_t, defined below. | ||
91 | */ | 61 | */ |
92 | typedef struct ide_floppy_obj { | 62 | #define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */ |
93 | ide_drive_t *drive; | ||
94 | ide_driver_t *driver; | ||
95 | struct gendisk *disk; | ||
96 | struct kref kref; | ||
97 | unsigned int openers; /* protected by BKL for now */ | ||
98 | |||
99 | /* Current packet command */ | ||
100 | struct ide_atapi_pc *pc; | ||
101 | /* Last failed packet command */ | ||
102 | struct ide_atapi_pc *failed_pc; | ||
103 | /* Packet command stack */ | ||
104 | struct ide_atapi_pc pc_stack[IDEFLOPPY_PC_STACK]; | ||
105 | /* Next free packet command storage space */ | ||
106 | int pc_stack_index; | ||
107 | struct request rq_stack[IDEFLOPPY_PC_STACK]; | ||
108 | /* We implement a circular array */ | ||
109 | int rq_stack_index; | ||
110 | |||
111 | /* Last error information */ | ||
112 | u8 sense_key, asc, ascq; | ||
113 | /* delay this long before sending packet command */ | ||
114 | u8 ticks; | ||
115 | int progress_indication; | ||
116 | |||
117 | /* Device information */ | ||
118 | /* Current format */ | ||
119 | int blocks, block_size, bs_factor; | ||
120 | /* Last format capacity descriptor */ | ||
121 | u8 cap_desc[8]; | ||
122 | /* Copy of the flexible disk page */ | ||
123 | u8 flexible_disk_page[32]; | ||
124 | /* Write protect */ | ||
125 | int wp; | ||
126 | /* Supports format progress report */ | ||
127 | int srfp; | ||
128 | } idefloppy_floppy_t; | ||
129 | |||
130 | #define IDEFLOPPY_TICKS_DELAY HZ/20 /* default delay for ZIP 100 (50ms) */ | ||
131 | |||
132 | /* Defines for the MODE SENSE command */ | ||
133 | #define MODE_SENSE_CURRENT 0x00 | ||
134 | #define MODE_SENSE_CHANGEABLE 0x01 | ||
135 | #define MODE_SENSE_DEFAULT 0x02 | ||
136 | #define MODE_SENSE_SAVED 0x03 | ||
137 | |||
138 | /* IOCTLs used in low-level formatting. */ | ||
139 | #define IDEFLOPPY_IOCTL_FORMAT_SUPPORTED 0x4600 | ||
140 | #define IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY 0x4601 | ||
141 | #define IDEFLOPPY_IOCTL_FORMAT_START 0x4602 | ||
142 | #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 | ||
143 | 63 | ||
144 | /* Error code returned in rq->errors to the higher part of the driver. */ | 64 | /* Error code returned in rq->errors to the higher part of the driver. */ |
145 | #define IDEFLOPPY_ERROR_GENERAL 101 | 65 | #define IDEFLOPPY_ERROR_GENERAL 101 |
146 | 66 | ||
147 | /* | 67 | /* |
148 | * Pages of the SELECT SENSE / MODE SENSE packet commands. | ||
149 | * See SFF-8070i spec. | ||
150 | */ | ||
151 | #define IDEFLOPPY_CAPABILITIES_PAGE 0x1b | ||
152 | #define IDEFLOPPY_FLEXIBLE_DISK_PAGE 0x05 | ||
153 | |||
154 | static DEFINE_MUTEX(idefloppy_ref_mutex); | ||
155 | |||
156 | #define to_ide_floppy(obj) container_of(obj, struct ide_floppy_obj, kref) | ||
157 | |||
158 | #define ide_floppy_g(disk) \ | ||
159 | container_of((disk)->private_data, struct ide_floppy_obj, driver) | ||
160 | |||
161 | static void idefloppy_cleanup_obj(struct kref *); | ||
162 | |||
163 | static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) | ||
164 | { | ||
165 | struct ide_floppy_obj *floppy = NULL; | ||
166 | |||
167 | mutex_lock(&idefloppy_ref_mutex); | ||
168 | floppy = ide_floppy_g(disk); | ||
169 | if (floppy) { | ||
170 | if (ide_device_get(floppy->drive)) | ||
171 | floppy = NULL; | ||
172 | else | ||
173 | kref_get(&floppy->kref); | ||
174 | } | ||
175 | mutex_unlock(&idefloppy_ref_mutex); | ||
176 | return floppy; | ||
177 | } | ||
178 | |||
179 | static void ide_floppy_put(struct ide_floppy_obj *floppy) | ||
180 | { | ||
181 | ide_drive_t *drive = floppy->drive; | ||
182 | |||
183 | mutex_lock(&idefloppy_ref_mutex); | ||
184 | kref_put(&floppy->kref, idefloppy_cleanup_obj); | ||
185 | ide_device_put(drive); | ||
186 | mutex_unlock(&idefloppy_ref_mutex); | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | * Used to finish servicing a request. For read/write requests, we will call | 68 | * Used to finish servicing a request. For read/write requests, we will call |
191 | * ide_end_request to pass to the next buffer. | 69 | * ide_end_request to pass to the next buffer. |
192 | */ | 70 | */ |
193 | static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) | 71 | static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) |
194 | { | 72 | { |
195 | idefloppy_floppy_t *floppy = drive->driver_data; | 73 | struct ide_disk_obj *floppy = drive->driver_data; |
196 | struct request *rq = HWGROUP(drive)->rq; | 74 | struct request *rq = HWGROUP(drive)->rq; |
197 | int error; | 75 | int error; |
198 | 76 | ||
199 | debug_log("Reached %s\n", __func__); | 77 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); |
200 | 78 | ||
201 | switch (uptodate) { | 79 | switch (uptodate) { |
202 | case 0: error = IDEFLOPPY_ERROR_GENERAL; break; | 80 | case 0: |
203 | case 1: error = 0; break; | 81 | error = IDEFLOPPY_ERROR_GENERAL; |
204 | default: error = uptodate; | 82 | break; |
83 | |||
84 | case 1: | ||
85 | error = 0; | ||
86 | break; | ||
87 | |||
88 | default: | ||
89 | error = uptodate; | ||
205 | } | 90 | } |
91 | |||
206 | if (error) | 92 | if (error) |
207 | floppy->failed_pc = NULL; | 93 | floppy->failed_pc = NULL; |
208 | /* Why does this happen? */ | 94 | /* Why does this happen? */ |
@@ -219,44 +105,6 @@ static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) | |||
219 | return 0; | 105 | return 0; |
220 | } | 106 | } |
221 | 107 | ||
222 | static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, | ||
223 | unsigned int bcount, int direction) | ||
224 | { | ||
225 | ide_hwif_t *hwif = drive->hwif; | ||
226 | struct request *rq = pc->rq; | ||
227 | struct req_iterator iter; | ||
228 | struct bio_vec *bvec; | ||
229 | unsigned long flags; | ||
230 | int count, done = 0; | ||
231 | char *data; | ||
232 | |||
233 | rq_for_each_segment(bvec, rq, iter) { | ||
234 | if (!bcount) | ||
235 | break; | ||
236 | |||
237 | count = min(bvec->bv_len, bcount); | ||
238 | |||
239 | data = bvec_kmap_irq(bvec, &flags); | ||
240 | if (direction) | ||
241 | hwif->tp_ops->output_data(drive, NULL, data, count); | ||
242 | else | ||
243 | hwif->tp_ops->input_data(drive, NULL, data, count); | ||
244 | bvec_kunmap_irq(data, &flags); | ||
245 | |||
246 | bcount -= count; | ||
247 | pc->b_count += count; | ||
248 | done += count; | ||
249 | } | ||
250 | |||
251 | idefloppy_end_request(drive, 1, done >> 9); | ||
252 | |||
253 | if (bcount) { | ||
254 | printk(KERN_ERR "%s: leftover data in %s, bcount == %d\n", | ||
255 | drive->name, __func__, bcount); | ||
256 | ide_pad_transfer(drive, direction, bcount); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | static void idefloppy_update_buffers(ide_drive_t *drive, | 108 | static void idefloppy_update_buffers(ide_drive_t *drive, |
261 | struct ide_atapi_pc *pc) | 109 | struct ide_atapi_pc *pc) |
262 | { | 110 | { |
@@ -264,53 +112,16 @@ static void idefloppy_update_buffers(ide_drive_t *drive, | |||
264 | struct bio *bio = rq->bio; | 112 | struct bio *bio = rq->bio; |
265 | 113 | ||
266 | while ((bio = rq->bio) != NULL) | 114 | while ((bio = rq->bio) != NULL) |
267 | idefloppy_end_request(drive, 1, 0); | 115 | ide_floppy_end_request(drive, 1, 0); |
268 | } | 116 | } |
269 | 117 | ||
270 | /* | 118 | static void ide_floppy_callback(ide_drive_t *drive, int dsc) |
271 | * Generate a new packet command request in front of the request queue, before | ||
272 | * the current request so that it will be processed immediately, on the next | ||
273 | * pass through the driver. | ||
274 | */ | ||
275 | static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, | ||
276 | struct request *rq) | ||
277 | { | 119 | { |
278 | struct ide_floppy_obj *floppy = drive->driver_data; | 120 | struct ide_disk_obj *floppy = drive->driver_data; |
279 | 121 | struct ide_atapi_pc *pc = drive->pc; | |
280 | blk_rq_init(NULL, rq); | ||
281 | rq->buffer = (char *) pc; | ||
282 | rq->cmd_type = REQ_TYPE_SPECIAL; | ||
283 | rq->cmd_flags |= REQ_PREEMPT; | ||
284 | rq->rq_disk = floppy->disk; | ||
285 | memcpy(rq->cmd, pc->c, 12); | ||
286 | ide_do_drive_cmd(drive, rq); | ||
287 | } | ||
288 | |||
289 | static struct ide_atapi_pc *idefloppy_next_pc_storage(ide_drive_t *drive) | ||
290 | { | ||
291 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
292 | |||
293 | if (floppy->pc_stack_index == IDEFLOPPY_PC_STACK) | ||
294 | floppy->pc_stack_index = 0; | ||
295 | return (&floppy->pc_stack[floppy->pc_stack_index++]); | ||
296 | } | ||
297 | |||
298 | static struct request *idefloppy_next_rq_storage(ide_drive_t *drive) | ||
299 | { | ||
300 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
301 | |||
302 | if (floppy->rq_stack_index == IDEFLOPPY_PC_STACK) | ||
303 | floppy->rq_stack_index = 0; | ||
304 | return (&floppy->rq_stack[floppy->rq_stack_index++]); | ||
305 | } | ||
306 | |||
307 | static void ide_floppy_callback(ide_drive_t *drive) | ||
308 | { | ||
309 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
310 | struct ide_atapi_pc *pc = floppy->pc; | ||
311 | int uptodate = pc->error ? 0 : 1; | 122 | int uptodate = pc->error ? 0 : 1; |
312 | 123 | ||
313 | debug_log("Reached %s\n", __func__); | 124 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); |
314 | 125 | ||
315 | if (floppy->failed_pc == pc) | 126 | if (floppy->failed_pc == pc) |
316 | floppy->failed_pc = NULL; | 127 | floppy->failed_pc = NULL; |
@@ -319,7 +130,7 @@ static void ide_floppy_callback(ide_drive_t *drive) | |||
319 | (pc->rq && blk_pc_request(pc->rq))) | 130 | (pc->rq && blk_pc_request(pc->rq))) |
320 | uptodate = 1; /* FIXME */ | 131 | uptodate = 1; /* FIXME */ |
321 | else if (pc->c[0] == GPCMD_REQUEST_SENSE) { | 132 | else if (pc->c[0] == GPCMD_REQUEST_SENSE) { |
322 | u8 *buf = floppy->pc->buf; | 133 | u8 *buf = pc->buf; |
323 | 134 | ||
324 | if (!pc->error) { | 135 | if (!pc->error) { |
325 | floppy->sense_key = buf[2] & 0x0F; | 136 | floppy->sense_key = buf[2] & 0x0F; |
@@ -329,109 +140,21 @@ static void ide_floppy_callback(ide_drive_t *drive) | |||
329 | (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; | 140 | (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; |
330 | 141 | ||
331 | if (floppy->failed_pc) | 142 | if (floppy->failed_pc) |
332 | debug_log("pc = %x, ", floppy->failed_pc->c[0]); | 143 | ide_debug_log(IDE_DBG_PC, "pc = %x, ", |
144 | floppy->failed_pc->c[0]); | ||
333 | 145 | ||
334 | debug_log("sense key = %x, asc = %x, ascq = %x\n", | 146 | ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x," |
335 | floppy->sense_key, floppy->asc, floppy->ascq); | 147 | "ascq = %x\n", floppy->sense_key, |
148 | floppy->asc, floppy->ascq); | ||
336 | } else | 149 | } else |
337 | printk(KERN_ERR "Error in REQUEST SENSE itself - " | 150 | printk(KERN_ERR PFX "Error in REQUEST SENSE itself - " |
338 | "Aborting request!\n"); | 151 | "Aborting request!\n"); |
339 | } | 152 | } |
340 | 153 | ||
341 | idefloppy_end_request(drive, uptodate, 0); | 154 | ide_floppy_end_request(drive, uptodate, 0); |
342 | } | ||
343 | |||
344 | static void idefloppy_init_pc(struct ide_atapi_pc *pc) | ||
345 | { | ||
346 | memset(pc, 0, sizeof(*pc)); | ||
347 | pc->buf = pc->pc_buf; | ||
348 | pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE; | ||
349 | } | ||
350 | |||
351 | static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc) | ||
352 | { | ||
353 | idefloppy_init_pc(pc); | ||
354 | pc->c[0] = GPCMD_REQUEST_SENSE; | ||
355 | pc->c[4] = 255; | ||
356 | pc->req_xfer = 18; | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | * Called when an error was detected during the last packet command. We queue a | ||
361 | * request sense packet command in the head of the request list. | ||
362 | */ | ||
363 | static void idefloppy_retry_pc(ide_drive_t *drive) | ||
364 | { | ||
365 | struct ide_atapi_pc *pc; | ||
366 | struct request *rq; | ||
367 | |||
368 | (void)ide_read_error(drive); | ||
369 | pc = idefloppy_next_pc_storage(drive); | ||
370 | rq = idefloppy_next_rq_storage(drive); | ||
371 | idefloppy_create_request_sense_cmd(pc); | ||
372 | idefloppy_queue_pc_head(drive, pc, rq); | ||
373 | } | 155 | } |
374 | 156 | ||
375 | /* The usual interrupt handler called during a packet command. */ | 157 | static void ide_floppy_report_error(struct ide_disk_obj *floppy, |
376 | static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) | ||
377 | { | ||
378 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
379 | |||
380 | return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr, | ||
381 | IDEFLOPPY_WAIT_CMD, NULL, idefloppy_update_buffers, | ||
382 | idefloppy_retry_pc, NULL, ide_floppy_io_buffers); | ||
383 | } | ||
384 | |||
385 | /* | ||
386 | * What we have here is a classic case of a top half / bottom half interrupt | ||
387 | * service routine. In interrupt mode, the device sends an interrupt to signal | ||
388 | * that it is ready to receive a packet. However, we need to delay about 2-3 | ||
389 | * ticks before issuing the packet or we gets in trouble. | ||
390 | */ | ||
391 | static int idefloppy_transfer_pc(ide_drive_t *drive) | ||
392 | { | ||
393 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
394 | |||
395 | /* Send the actual packet */ | ||
396 | drive->hwif->tp_ops->output_data(drive, NULL, floppy->pc->c, 12); | ||
397 | |||
398 | /* Timeout for the packet command */ | ||
399 | return IDEFLOPPY_WAIT_CMD; | ||
400 | } | ||
401 | |||
402 | |||
403 | /* | ||
404 | * Called as an interrupt (or directly). When the device says it's ready for a | ||
405 | * packet, we schedule the packet transfer to occur about 2-3 ticks later in | ||
406 | * transfer_pc. | ||
407 | */ | ||
408 | static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive) | ||
409 | { | ||
410 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
411 | struct ide_atapi_pc *pc = floppy->pc; | ||
412 | ide_expiry_t *expiry; | ||
413 | unsigned int timeout; | ||
414 | |||
415 | /* | ||
416 | * The following delay solves a problem with ATAPI Zip 100 drives | ||
417 | * where the Busy flag was apparently being deasserted before the | ||
418 | * unit was ready to receive data. This was happening on a | ||
419 | * 1200 MHz Athlon system. 10/26/01 25msec is too short, | ||
420 | * 40 and 50msec work well. idefloppy_pc_intr will not be actually | ||
421 | * used until after the packet is moved in about 50 msec. | ||
422 | */ | ||
423 | if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { | ||
424 | timeout = floppy->ticks; | ||
425 | expiry = &idefloppy_transfer_pc; | ||
426 | } else { | ||
427 | timeout = IDEFLOPPY_WAIT_CMD; | ||
428 | expiry = NULL; | ||
429 | } | ||
430 | |||
431 | return ide_transfer_pc(drive, pc, idefloppy_pc_intr, timeout, expiry); | ||
432 | } | ||
433 | |||
434 | static void ide_floppy_report_error(idefloppy_floppy_t *floppy, | ||
435 | struct ide_atapi_pc *pc) | 158 | struct ide_atapi_pc *pc) |
436 | { | 159 | { |
437 | /* supress error messages resulting from Medium not present */ | 160 | /* supress error messages resulting from Medium not present */ |
@@ -440,7 +163,7 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy, | |||
440 | floppy->ascq == 0x00) | 163 | floppy->ascq == 0x00) |
441 | return; | 164 | return; |
442 | 165 | ||
443 | printk(KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, " | 166 | printk(KERN_ERR PFX "%s: I/O error, pc = %2x, key = %2x, " |
444 | "asc = %2x, ascq = %2x\n", | 167 | "asc = %2x, ascq = %2x\n", |
445 | floppy->drive->name, pc->c[0], floppy->sense_key, | 168 | floppy->drive->name, pc->c[0], floppy->sense_key, |
446 | floppy->asc, floppy->ascq); | 169 | floppy->asc, floppy->ascq); |
@@ -450,13 +173,14 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy, | |||
450 | static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, | 173 | static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, |
451 | struct ide_atapi_pc *pc) | 174 | struct ide_atapi_pc *pc) |
452 | { | 175 | { |
453 | idefloppy_floppy_t *floppy = drive->driver_data; | 176 | struct ide_disk_obj *floppy = drive->driver_data; |
454 | 177 | ||
455 | if (floppy->failed_pc == NULL && | 178 | if (floppy->failed_pc == NULL && |
456 | pc->c[0] != GPCMD_REQUEST_SENSE) | 179 | pc->c[0] != GPCMD_REQUEST_SENSE) |
457 | floppy->failed_pc = pc; | 180 | floppy->failed_pc = pc; |
181 | |||
458 | /* Set the current packet command */ | 182 | /* Set the current packet command */ |
459 | floppy->pc = pc; | 183 | drive->pc = pc; |
460 | 184 | ||
461 | if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { | 185 | if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { |
462 | if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) | 186 | if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) |
@@ -465,67 +189,35 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, | |||
465 | pc->error = IDEFLOPPY_ERROR_GENERAL; | 189 | pc->error = IDEFLOPPY_ERROR_GENERAL; |
466 | 190 | ||
467 | floppy->failed_pc = NULL; | 191 | floppy->failed_pc = NULL; |
468 | drive->pc_callback(drive); | 192 | drive->pc_callback(drive, 0); |
469 | return ide_stopped; | 193 | return ide_stopped; |
470 | } | 194 | } |
471 | 195 | ||
472 | debug_log("Retry number - %d\n", pc->retries); | 196 | ide_debug_log(IDE_DBG_FUNC, "%s: Retry #%d\n", __func__, pc->retries); |
473 | 197 | ||
474 | pc->retries++; | 198 | pc->retries++; |
475 | 199 | ||
476 | return ide_issue_pc(drive, pc, idefloppy_start_pc_transfer, | 200 | return ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL); |
477 | IDEFLOPPY_WAIT_CMD, NULL); | ||
478 | } | 201 | } |
479 | 202 | ||
480 | static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent) | 203 | void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) |
481 | { | 204 | { |
482 | debug_log("creating prevent removal command, prevent = %d\n", prevent); | 205 | ide_init_pc(pc); |
483 | |||
484 | idefloppy_init_pc(pc); | ||
485 | pc->c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; | ||
486 | pc->c[4] = prevent; | ||
487 | } | ||
488 | |||
489 | static void idefloppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) | ||
490 | { | ||
491 | idefloppy_init_pc(pc); | ||
492 | pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES; | 206 | pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES; |
493 | pc->c[7] = 255; | 207 | pc->c[7] = 255; |
494 | pc->c[8] = 255; | 208 | pc->c[8] = 255; |
495 | pc->req_xfer = 255; | 209 | pc->req_xfer = 255; |
496 | } | 210 | } |
497 | 211 | ||
498 | static void idefloppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, | ||
499 | int l, int flags) | ||
500 | { | ||
501 | idefloppy_init_pc(pc); | ||
502 | pc->c[0] = GPCMD_FORMAT_UNIT; | ||
503 | pc->c[1] = 0x17; | ||
504 | |||
505 | memset(pc->buf, 0, 12); | ||
506 | pc->buf[1] = 0xA2; | ||
507 | /* Default format list header, u8 1: FOV/DCRT/IMM bits set */ | ||
508 | |||
509 | if (flags & 1) /* Verify bit on... */ | ||
510 | pc->buf[1] ^= 0x20; /* ... turn off DCRT bit */ | ||
511 | pc->buf[3] = 8; | ||
512 | |||
513 | put_unaligned(cpu_to_be32(b), (unsigned int *)(&pc->buf[4])); | ||
514 | put_unaligned(cpu_to_be32(l), (unsigned int *)(&pc->buf[8])); | ||
515 | pc->buf_size = 12; | ||
516 | pc->flags |= PC_FLAG_WRITING; | ||
517 | } | ||
518 | |||
519 | /* A mode sense command is used to "sense" floppy parameters. */ | 212 | /* A mode sense command is used to "sense" floppy parameters. */ |
520 | static void idefloppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, | 213 | void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) |
521 | u8 page_code, u8 type) | ||
522 | { | 214 | { |
523 | u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */ | 215 | u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */ |
524 | 216 | ||
525 | idefloppy_init_pc(pc); | 217 | ide_init_pc(pc); |
526 | pc->c[0] = GPCMD_MODE_SENSE_10; | 218 | pc->c[0] = GPCMD_MODE_SENSE_10; |
527 | pc->c[1] = 0; | 219 | pc->c[1] = 0; |
528 | pc->c[2] = page_code + (type << 6); | 220 | pc->c[2] = page_code; |
529 | 221 | ||
530 | switch (page_code) { | 222 | switch (page_code) { |
531 | case IDEFLOPPY_CAPABILITIES_PAGE: | 223 | case IDEFLOPPY_CAPABILITIES_PAGE: |
@@ -535,32 +227,25 @@ static void idefloppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, | |||
535 | length += 32; | 227 | length += 32; |
536 | break; | 228 | break; |
537 | default: | 229 | default: |
538 | printk(KERN_ERR "ide-floppy: unsupported page code " | 230 | printk(KERN_ERR PFX "unsupported page code in %s\n", __func__); |
539 | "in create_mode_sense_cmd\n"); | ||
540 | } | 231 | } |
541 | put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]); | 232 | put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]); |
542 | pc->req_xfer = length; | 233 | pc->req_xfer = length; |
543 | } | 234 | } |
544 | 235 | ||
545 | static void idefloppy_create_start_stop_cmd(struct ide_atapi_pc *pc, int start) | 236 | static void idefloppy_create_rw_cmd(ide_drive_t *drive, |
546 | { | ||
547 | idefloppy_init_pc(pc); | ||
548 | pc->c[0] = GPCMD_START_STOP_UNIT; | ||
549 | pc->c[4] = start; | ||
550 | } | ||
551 | |||
552 | static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, | ||
553 | struct ide_atapi_pc *pc, struct request *rq, | 237 | struct ide_atapi_pc *pc, struct request *rq, |
554 | unsigned long sector) | 238 | unsigned long sector) |
555 | { | 239 | { |
240 | struct ide_disk_obj *floppy = drive->driver_data; | ||
556 | int block = sector / floppy->bs_factor; | 241 | int block = sector / floppy->bs_factor; |
557 | int blocks = rq->nr_sectors / floppy->bs_factor; | 242 | int blocks = rq->nr_sectors / floppy->bs_factor; |
558 | int cmd = rq_data_dir(rq); | 243 | int cmd = rq_data_dir(rq); |
559 | 244 | ||
560 | debug_log("create_rw10_cmd: block == %d, blocks == %d\n", | 245 | ide_debug_log(IDE_DBG_FUNC, "%s: block: %d, blocks: %d\n", __func__, |
561 | block, blocks); | 246 | block, blocks); |
562 | 247 | ||
563 | idefloppy_init_pc(pc); | 248 | ide_init_pc(pc); |
564 | pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; | 249 | pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; |
565 | put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); | 250 | put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); |
566 | put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); | 251 | put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); |
@@ -568,7 +253,7 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, | |||
568 | memcpy(rq->cmd, pc->c, 12); | 253 | memcpy(rq->cmd, pc->c, 12); |
569 | 254 | ||
570 | pc->rq = rq; | 255 | pc->rq = rq; |
571 | pc->b_count = cmd == READ ? 0 : rq->bio->bi_size; | 256 | pc->b_count = 0; |
572 | if (rq->cmd_flags & REQ_RW) | 257 | if (rq->cmd_flags & REQ_RW) |
573 | pc->flags |= PC_FLAG_WRITING; | 258 | pc->flags |= PC_FLAG_WRITING; |
574 | pc->buf = NULL; | 259 | pc->buf = NULL; |
@@ -576,13 +261,13 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, | |||
576 | pc->flags |= PC_FLAG_DMA_OK; | 261 | pc->flags |= PC_FLAG_DMA_OK; |
577 | } | 262 | } |
578 | 263 | ||
579 | static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, | 264 | static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, |
580 | struct ide_atapi_pc *pc, struct request *rq) | 265 | struct ide_atapi_pc *pc, struct request *rq) |
581 | { | 266 | { |
582 | idefloppy_init_pc(pc); | 267 | ide_init_pc(pc); |
583 | memcpy(pc->c, rq->cmd, sizeof(pc->c)); | 268 | memcpy(pc->c, rq->cmd, sizeof(pc->c)); |
584 | pc->rq = rq; | 269 | pc->rq = rq; |
585 | pc->b_count = rq->data_len; | 270 | pc->b_count = 0; |
586 | if (rq->data_len && rq_data_dir(rq) == WRITE) | 271 | if (rq->data_len && rq_data_dir(rq) == WRITE) |
587 | pc->flags |= PC_FLAG_WRITING; | 272 | pc->flags |= PC_FLAG_WRITING; |
588 | pc->buf = rq->data; | 273 | pc->buf = rq->data; |
@@ -595,74 +280,62 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, | |||
595 | pc->req_xfer = pc->buf_size = rq->data_len; | 280 | pc->req_xfer = pc->buf_size = rq->data_len; |
596 | } | 281 | } |
597 | 282 | ||
598 | static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | 283 | static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, |
599 | struct request *rq, sector_t block_s) | 284 | struct request *rq, sector_t block) |
600 | { | 285 | { |
601 | idefloppy_floppy_t *floppy = drive->driver_data; | 286 | struct ide_disk_obj *floppy = drive->driver_data; |
287 | ide_hwif_t *hwif = drive->hwif; | ||
602 | struct ide_atapi_pc *pc; | 288 | struct ide_atapi_pc *pc; |
603 | unsigned long block = (unsigned long)block_s; | ||
604 | 289 | ||
605 | debug_log("dev: %s, cmd_type: %x, errors: %d\n", | 290 | ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " |
606 | rq->rq_disk ? rq->rq_disk->disk_name : "?", | 291 | "errors: %d\n", |
607 | rq->cmd_type, rq->errors); | 292 | __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?", |
608 | debug_log("sector: %ld, nr_sectors: %ld, " | 293 | rq->cmd[0], rq->cmd_type, rq->errors); |
609 | "current_nr_sectors: %d\n", (long)rq->sector, | 294 | |
610 | rq->nr_sectors, rq->current_nr_sectors); | 295 | ide_debug_log(IDE_DBG_FUNC, "%s: sector: %ld, nr_sectors: %ld, " |
296 | "current_nr_sectors: %d\n", | ||
297 | __func__, (long)rq->sector, rq->nr_sectors, | ||
298 | rq->current_nr_sectors); | ||
611 | 299 | ||
612 | if (rq->errors >= ERROR_MAX) { | 300 | if (rq->errors >= ERROR_MAX) { |
613 | if (floppy->failed_pc) | 301 | if (floppy->failed_pc) |
614 | ide_floppy_report_error(floppy, floppy->failed_pc); | 302 | ide_floppy_report_error(floppy, floppy->failed_pc); |
615 | else | 303 | else |
616 | printk(KERN_ERR "ide-floppy: %s: I/O error\n", | 304 | printk(KERN_ERR PFX "%s: I/O error\n", drive->name); |
617 | drive->name); | 305 | |
618 | idefloppy_end_request(drive, 0, 0); | 306 | ide_floppy_end_request(drive, 0, 0); |
619 | return ide_stopped; | 307 | return ide_stopped; |
620 | } | 308 | } |
621 | if (blk_fs_request(rq)) { | 309 | if (blk_fs_request(rq)) { |
622 | if (((long)rq->sector % floppy->bs_factor) || | 310 | if (((long)rq->sector % floppy->bs_factor) || |
623 | (rq->nr_sectors % floppy->bs_factor)) { | 311 | (rq->nr_sectors % floppy->bs_factor)) { |
624 | printk(KERN_ERR "%s: unsupported r/w request size\n", | 312 | printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", |
625 | drive->name); | 313 | drive->name); |
626 | idefloppy_end_request(drive, 0, 0); | 314 | ide_floppy_end_request(drive, 0, 0); |
627 | return ide_stopped; | 315 | return ide_stopped; |
628 | } | 316 | } |
629 | pc = idefloppy_next_pc_storage(drive); | 317 | pc = &floppy->queued_pc; |
630 | idefloppy_create_rw_cmd(floppy, pc, rq, block); | 318 | idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); |
631 | } else if (blk_special_request(rq)) { | 319 | } else if (blk_special_request(rq)) { |
632 | pc = (struct ide_atapi_pc *) rq->buffer; | 320 | pc = (struct ide_atapi_pc *) rq->buffer; |
633 | } else if (blk_pc_request(rq)) { | 321 | } else if (blk_pc_request(rq)) { |
634 | pc = idefloppy_next_pc_storage(drive); | 322 | pc = &floppy->queued_pc; |
635 | idefloppy_blockpc_cmd(floppy, pc, rq); | 323 | idefloppy_blockpc_cmd(floppy, pc, rq); |
636 | } else { | 324 | } else { |
637 | blk_dump_rq_flags(rq, | 325 | blk_dump_rq_flags(rq, PFX "unsupported command in queue"); |
638 | "ide-floppy: unsupported command in queue"); | 326 | ide_floppy_end_request(drive, 0, 0); |
639 | idefloppy_end_request(drive, 0, 0); | ||
640 | return ide_stopped; | 327 | return ide_stopped; |
641 | } | 328 | } |
642 | 329 | ||
643 | pc->rq = rq; | 330 | ide_init_sg_cmd(drive, rq); |
331 | ide_map_sg(drive, rq); | ||
644 | 332 | ||
645 | return idefloppy_issue_pc(drive, pc); | 333 | pc->sg = hwif->sg_table; |
646 | } | 334 | pc->sg_cnt = hwif->sg_nents; |
647 | 335 | ||
648 | /* | 336 | pc->rq = rq; |
649 | * Add a special packet command request to the tail of the request queue, | ||
650 | * and wait for it to be serviced. | ||
651 | */ | ||
652 | static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc) | ||
653 | { | ||
654 | struct ide_floppy_obj *floppy = drive->driver_data; | ||
655 | struct request *rq; | ||
656 | int error; | ||
657 | |||
658 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | ||
659 | rq->buffer = (char *) pc; | ||
660 | rq->cmd_type = REQ_TYPE_SPECIAL; | ||
661 | memcpy(rq->cmd, pc->c, 12); | ||
662 | error = blk_execute_rq(drive->queue, floppy->disk, rq, 0); | ||
663 | blk_put_request(rq); | ||
664 | 337 | ||
665 | return error; | 338 | return idefloppy_issue_pc(drive, pc); |
666 | } | 339 | } |
667 | 340 | ||
668 | /* | 341 | /* |
@@ -671,23 +344,28 @@ static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc) | |||
671 | */ | 344 | */ |
672 | static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | 345 | static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) |
673 | { | 346 | { |
674 | idefloppy_floppy_t *floppy = drive->driver_data; | 347 | struct ide_disk_obj *floppy = drive->driver_data; |
348 | struct gendisk *disk = floppy->disk; | ||
675 | struct ide_atapi_pc pc; | 349 | struct ide_atapi_pc pc; |
676 | u8 *page; | 350 | u8 *page; |
677 | int capacity, lba_capacity; | 351 | int capacity, lba_capacity; |
678 | u16 transfer_rate, sector_size, cyls, rpm; | 352 | u16 transfer_rate, sector_size, cyls, rpm; |
679 | u8 heads, sectors; | 353 | u8 heads, sectors; |
680 | 354 | ||
681 | idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE, | 355 | ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); |
682 | MODE_SENSE_CURRENT); | ||
683 | 356 | ||
684 | if (idefloppy_queue_pc_tail(drive, &pc)) { | 357 | if (ide_queue_pc_tail(drive, disk, &pc)) { |
685 | printk(KERN_ERR "ide-floppy: Can't get flexible disk page" | 358 | printk(KERN_ERR PFX "Can't get flexible disk page params\n"); |
686 | " parameters\n"); | ||
687 | return 1; | 359 | return 1; |
688 | } | 360 | } |
689 | floppy->wp = !!(pc.buf[3] & 0x80); | 361 | |
690 | set_disk_ro(floppy->disk, floppy->wp); | 362 | if (pc.buf[3] & 0x80) |
363 | drive->dev_flags |= IDE_DFLAG_WP; | ||
364 | else | ||
365 | drive->dev_flags &= ~IDE_DFLAG_WP; | ||
366 | |||
367 | set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); | ||
368 | |||
691 | page = &pc.buf[8]; | 369 | page = &pc.buf[8]; |
692 | 370 | ||
693 | transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]); | 371 | transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]); |
@@ -700,7 +378,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | |||
700 | capacity = cyls * heads * sectors * sector_size; | 378 | capacity = cyls * heads * sectors * sector_size; |
701 | 379 | ||
702 | if (memcmp(page, &floppy->flexible_disk_page, 32)) | 380 | if (memcmp(page, &floppy->flexible_disk_page, 32)) |
703 | printk(KERN_INFO "%s: %dkB, %d/%d/%d CHS, %d kBps, " | 381 | printk(KERN_INFO PFX "%s: %dkB, %d/%d/%d CHS, %d kBps, " |
704 | "%d sector size, %d rpm\n", | 382 | "%d sector size, %d rpm\n", |
705 | drive->name, capacity / 1024, cyls, heads, | 383 | drive->name, capacity / 1024, cyls, heads, |
706 | sectors, transfer_rate / 8, sector_size, rpm); | 384 | sectors, transfer_rate / 8, sector_size, rpm); |
@@ -712,30 +390,15 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | |||
712 | lba_capacity = floppy->blocks * floppy->block_size; | 390 | lba_capacity = floppy->blocks * floppy->block_size; |
713 | 391 | ||
714 | if (capacity < lba_capacity) { | 392 | if (capacity < lba_capacity) { |
715 | printk(KERN_NOTICE "%s: The disk reports a capacity of %d " | 393 | printk(KERN_NOTICE PFX "%s: The disk reports a capacity of %d " |
716 | "bytes, but the drive only handles %d\n", | 394 | "bytes, but the drive only handles %d\n", |
717 | drive->name, lba_capacity, capacity); | 395 | drive->name, lba_capacity, capacity); |
718 | floppy->blocks = floppy->block_size ? | 396 | floppy->blocks = floppy->block_size ? |
719 | capacity / floppy->block_size : 0; | 397 | capacity / floppy->block_size : 0; |
398 | drive->capacity64 = floppy->blocks * floppy->bs_factor; | ||
720 | } | 399 | } |
721 | return 0; | ||
722 | } | ||
723 | 400 | ||
724 | static int idefloppy_get_sfrp_bit(ide_drive_t *drive) | 401 | return 0; |
725 | { | ||
726 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
727 | struct ide_atapi_pc pc; | ||
728 | |||
729 | floppy->srfp = 0; | ||
730 | idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE, | ||
731 | MODE_SENSE_CURRENT); | ||
732 | |||
733 | pc.flags |= PC_FLAG_SUPPRESS_ERROR; | ||
734 | if (idefloppy_queue_pc_tail(drive, &pc)) | ||
735 | return 1; | ||
736 | |||
737 | floppy->srfp = pc.buf[8 + 2] & 0x40; | ||
738 | return (0); | ||
739 | } | 402 | } |
740 | 403 | ||
741 | /* | 404 | /* |
@@ -744,7 +407,8 @@ static int idefloppy_get_sfrp_bit(ide_drive_t *drive) | |||
744 | */ | 407 | */ |
745 | static int ide_floppy_get_capacity(ide_drive_t *drive) | 408 | static int ide_floppy_get_capacity(ide_drive_t *drive) |
746 | { | 409 | { |
747 | idefloppy_floppy_t *floppy = drive->driver_data; | 410 | struct ide_disk_obj *floppy = drive->driver_data; |
411 | struct gendisk *disk = floppy->disk; | ||
748 | struct ide_atapi_pc pc; | 412 | struct ide_atapi_pc pc; |
749 | u8 *cap_desc; | 413 | u8 *cap_desc; |
750 | u8 header_len, desc_cnt; | 414 | u8 header_len, desc_cnt; |
@@ -754,11 +418,11 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
754 | drive->bios_head = drive->bios_sect = 0; | 418 | drive->bios_head = drive->bios_sect = 0; |
755 | floppy->blocks = 0; | 419 | floppy->blocks = 0; |
756 | floppy->bs_factor = 1; | 420 | floppy->bs_factor = 1; |
757 | set_capacity(floppy->disk, 0); | 421 | drive->capacity64 = 0; |
758 | 422 | ||
759 | idefloppy_create_read_capacity_cmd(&pc); | 423 | ide_floppy_create_read_capacity_cmd(&pc); |
760 | if (idefloppy_queue_pc_tail(drive, &pc)) { | 424 | if (ide_queue_pc_tail(drive, disk, &pc)) { |
761 | printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); | 425 | printk(KERN_ERR PFX "Can't get floppy parameters\n"); |
762 | return 1; | 426 | return 1; |
763 | } | 427 | } |
764 | header_len = pc.buf[3]; | 428 | header_len = pc.buf[3]; |
@@ -771,8 +435,9 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
771 | blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); | 435 | blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); |
772 | length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); | 436 | length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); |
773 | 437 | ||
774 | debug_log("Descriptor %d: %dkB, %d blocks, %d sector size\n", | 438 | ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, " |
775 | i, blocks * length / 1024, blocks, length); | 439 | "%d sector size\n", |
440 | i, blocks * length / 1024, blocks, length); | ||
776 | 441 | ||
777 | if (i) | 442 | if (i) |
778 | continue; | 443 | continue; |
@@ -792,23 +457,26 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
792 | case CAPACITY_CURRENT: | 457 | case CAPACITY_CURRENT: |
793 | /* Normal Zip/LS-120 disks */ | 458 | /* Normal Zip/LS-120 disks */ |
794 | if (memcmp(cap_desc, &floppy->cap_desc, 8)) | 459 | if (memcmp(cap_desc, &floppy->cap_desc, 8)) |
795 | printk(KERN_INFO "%s: %dkB, %d blocks, %d " | 460 | printk(KERN_INFO PFX "%s: %dkB, %d blocks, %d " |
796 | "sector size\n", drive->name, | 461 | "sector size\n", |
797 | blocks * length / 1024, blocks, length); | 462 | drive->name, blocks * length / 1024, |
463 | blocks, length); | ||
798 | memcpy(&floppy->cap_desc, cap_desc, 8); | 464 | memcpy(&floppy->cap_desc, cap_desc, 8); |
799 | 465 | ||
800 | if (!length || length % 512) { | 466 | if (!length || length % 512) { |
801 | printk(KERN_NOTICE "%s: %d bytes block size " | 467 | printk(KERN_NOTICE PFX "%s: %d bytes block size" |
802 | "not supported\n", drive->name, length); | 468 | " not supported\n", drive->name, length); |
803 | } else { | 469 | } else { |
804 | floppy->blocks = blocks; | 470 | floppy->blocks = blocks; |
805 | floppy->block_size = length; | 471 | floppy->block_size = length; |
806 | floppy->bs_factor = length / 512; | 472 | floppy->bs_factor = length / 512; |
807 | if (floppy->bs_factor != 1) | 473 | if (floppy->bs_factor != 1) |
808 | printk(KERN_NOTICE "%s: warning: non " | 474 | printk(KERN_NOTICE PFX "%s: Warning: " |
809 | "512 bytes block size not " | 475 | "non 512 bytes block size not " |
810 | "fully supported\n", | 476 | "fully supported\n", |
811 | drive->name); | 477 | drive->name); |
478 | drive->capacity64 = | ||
479 | floppy->blocks * floppy->bs_factor; | ||
812 | rc = 0; | 480 | rc = 0; |
813 | } | 481 | } |
814 | break; | 482 | break; |
@@ -817,221 +485,34 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
817 | * This is a KERN_ERR so it appears on screen | 485 | * This is a KERN_ERR so it appears on screen |
818 | * for the user to see | 486 | * for the user to see |
819 | */ | 487 | */ |
820 | printk(KERN_ERR "%s: No disk in drive\n", drive->name); | 488 | printk(KERN_ERR PFX "%s: No disk in drive\n", |
489 | drive->name); | ||
821 | break; | 490 | break; |
822 | case CAPACITY_INVALID: | 491 | case CAPACITY_INVALID: |
823 | printk(KERN_ERR "%s: Invalid capacity for disk " | 492 | printk(KERN_ERR PFX "%s: Invalid capacity for disk " |
824 | "in drive\n", drive->name); | 493 | "in drive\n", drive->name); |
825 | break; | 494 | break; |
826 | } | 495 | } |
827 | debug_log("Descriptor 0 Code: %d\n", | 496 | ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d\n", |
828 | pc.buf[desc_start + 4] & 0x03); | 497 | pc.buf[desc_start + 4] & 0x03); |
829 | } | 498 | } |
830 | 499 | ||
831 | /* Clik! disk does not support get_flexible_disk_page */ | 500 | /* Clik! disk does not support get_flexible_disk_page */ |
832 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) | 501 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
833 | (void) ide_floppy_get_flexible_disk_page(drive); | 502 | (void) ide_floppy_get_flexible_disk_page(drive); |
834 | 503 | ||
835 | set_capacity(floppy->disk, floppy->blocks * floppy->bs_factor); | ||
836 | return rc; | 504 | return rc; |
837 | } | 505 | } |
838 | 506 | ||
839 | /* | 507 | static void ide_floppy_setup(ide_drive_t *drive) |
840 | * Obtain the list of formattable capacities. | ||
841 | * Very similar to ide_floppy_get_capacity, except that we push the capacity | ||
842 | * descriptors to userland, instead of our own structures. | ||
843 | * | ||
844 | * Userland gives us the following structure: | ||
845 | * | ||
846 | * struct idefloppy_format_capacities { | ||
847 | * int nformats; | ||
848 | * struct { | ||
849 | * int nblocks; | ||
850 | * int blocksize; | ||
851 | * } formats[]; | ||
852 | * }; | ||
853 | * | ||
854 | * userland initializes nformats to the number of allocated formats[] records. | ||
855 | * On exit we set nformats to the number of records we've actually initialized. | ||
856 | */ | ||
857 | |||
858 | static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) | ||
859 | { | ||
860 | struct ide_atapi_pc pc; | ||
861 | u8 header_len, desc_cnt; | ||
862 | int i, blocks, length, u_array_size, u_index; | ||
863 | int __user *argp; | ||
864 | |||
865 | if (get_user(u_array_size, arg)) | ||
866 | return (-EFAULT); | ||
867 | |||
868 | if (u_array_size <= 0) | ||
869 | return (-EINVAL); | ||
870 | |||
871 | idefloppy_create_read_capacity_cmd(&pc); | ||
872 | if (idefloppy_queue_pc_tail(drive, &pc)) { | ||
873 | printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); | ||
874 | return (-EIO); | ||
875 | } | ||
876 | header_len = pc.buf[3]; | ||
877 | desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ | ||
878 | |||
879 | u_index = 0; | ||
880 | argp = arg + 1; | ||
881 | |||
882 | /* | ||
883 | * We always skip the first capacity descriptor. That's the current | ||
884 | * capacity. We are interested in the remaining descriptors, the | ||
885 | * formattable capacities. | ||
886 | */ | ||
887 | for (i = 1; i < desc_cnt; i++) { | ||
888 | unsigned int desc_start = 4 + i*8; | ||
889 | |||
890 | if (u_index >= u_array_size) | ||
891 | break; /* User-supplied buffer too small */ | ||
892 | |||
893 | blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); | ||
894 | length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); | ||
895 | |||
896 | if (put_user(blocks, argp)) | ||
897 | return(-EFAULT); | ||
898 | ++argp; | ||
899 | |||
900 | if (put_user(length, argp)) | ||
901 | return (-EFAULT); | ||
902 | ++argp; | ||
903 | |||
904 | ++u_index; | ||
905 | } | ||
906 | |||
907 | if (put_user(u_index, arg)) | ||
908 | return (-EFAULT); | ||
909 | return (0); | ||
910 | } | ||
911 | |||
912 | /* | ||
913 | * Get ATAPI_FORMAT_UNIT progress indication. | ||
914 | * | ||
915 | * Userland gives a pointer to an int. The int is set to a progress | ||
916 | * indicator 0-65536, with 65536=100%. | ||
917 | * | ||
918 | * If the drive does not support format progress indication, we just check | ||
919 | * the dsc bit, and return either 0 or 65536. | ||
920 | */ | ||
921 | |||
922 | static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg) | ||
923 | { | 508 | { |
924 | idefloppy_floppy_t *floppy = drive->driver_data; | 509 | struct ide_disk_obj *floppy = drive->driver_data; |
925 | struct ide_atapi_pc pc; | 510 | u16 *id = drive->id; |
926 | int progress_indication = 0x10000; | ||
927 | |||
928 | if (floppy->srfp) { | ||
929 | idefloppy_create_request_sense_cmd(&pc); | ||
930 | if (idefloppy_queue_pc_tail(drive, &pc)) | ||
931 | return (-EIO); | ||
932 | |||
933 | if (floppy->sense_key == 2 && | ||
934 | floppy->asc == 4 && | ||
935 | floppy->ascq == 4) | ||
936 | progress_indication = floppy->progress_indication; | ||
937 | 511 | ||
938 | /* Else assume format_unit has finished, and we're at 0x10000 */ | 512 | drive->pc_callback = ide_floppy_callback; |
939 | } else { | 513 | drive->pc_update_buffers = idefloppy_update_buffers; |
940 | ide_hwif_t *hwif = drive->hwif; | 514 | drive->pc_io_buffers = ide_io_buffers; |
941 | unsigned long flags; | ||
942 | u8 stat; | ||
943 | |||
944 | local_irq_save(flags); | ||
945 | stat = hwif->tp_ops->read_status(hwif); | ||
946 | local_irq_restore(flags); | ||
947 | 515 | ||
948 | progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000; | ||
949 | } | ||
950 | if (put_user(progress_indication, arg)) | ||
951 | return (-EFAULT); | ||
952 | |||
953 | return (0); | ||
954 | } | ||
955 | |||
956 | static sector_t idefloppy_capacity(ide_drive_t *drive) | ||
957 | { | ||
958 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
959 | unsigned long capacity = floppy->blocks * floppy->bs_factor; | ||
960 | |||
961 | return capacity; | ||
962 | } | ||
963 | |||
964 | /* | ||
965 | * Check whether we can support a drive, based on the ATAPI IDENTIFY command | ||
966 | * results. | ||
967 | */ | ||
968 | static int idefloppy_identify_device(ide_drive_t *drive, struct hd_driveid *id) | ||
969 | { | ||
970 | u8 gcw[2]; | ||
971 | u8 device_type, protocol, removable, drq_type, packet_size; | ||
972 | |||
973 | *((u16 *) &gcw) = id->config; | ||
974 | |||
975 | device_type = gcw[1] & 0x1F; | ||
976 | removable = (gcw[0] & 0x80) >> 7; | ||
977 | protocol = (gcw[1] & 0xC0) >> 6; | ||
978 | drq_type = (gcw[0] & 0x60) >> 5; | ||
979 | packet_size = gcw[0] & 0x03; | ||
980 | |||
981 | #ifdef CONFIG_PPC | ||
982 | /* kludge for Apple PowerBook internal zip */ | ||
983 | if (device_type == 5 && | ||
984 | !strstr(id->model, "CD-ROM") && strstr(id->model, "ZIP")) | ||
985 | device_type = 0; | ||
986 | #endif | ||
987 | |||
988 | if (protocol != 2) | ||
989 | printk(KERN_ERR "ide-floppy: Protocol (0x%02x) is not ATAPI\n", | ||
990 | protocol); | ||
991 | else if (device_type != 0) | ||
992 | printk(KERN_ERR "ide-floppy: Device type (0x%02x) is not set " | ||
993 | "to floppy\n", device_type); | ||
994 | else if (!removable) | ||
995 | printk(KERN_ERR "ide-floppy: The removable flag is not set\n"); | ||
996 | else if (drq_type == 3) | ||
997 | printk(KERN_ERR "ide-floppy: Sorry, DRQ type (0x%02x) not " | ||
998 | "supported\n", drq_type); | ||
999 | else if (packet_size != 0) | ||
1000 | printk(KERN_ERR "ide-floppy: Packet size (0x%02x) is not 12 " | ||
1001 | "bytes\n", packet_size); | ||
1002 | else | ||
1003 | return 1; | ||
1004 | return 0; | ||
1005 | } | ||
1006 | |||
1007 | #ifdef CONFIG_IDE_PROC_FS | ||
1008 | static void idefloppy_add_settings(ide_drive_t *drive) | ||
1009 | { | ||
1010 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
1011 | |||
1012 | ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 1023, 1, 1, | ||
1013 | &drive->bios_cyl, NULL); | ||
1014 | ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, | ||
1015 | &drive->bios_head, NULL); | ||
1016 | ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, | ||
1017 | &drive->bios_sect, NULL); | ||
1018 | ide_add_setting(drive, "ticks", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, | ||
1019 | &floppy->ticks, NULL); | ||
1020 | } | ||
1021 | #else | ||
1022 | static inline void idefloppy_add_settings(ide_drive_t *drive) { ; } | ||
1023 | #endif | ||
1024 | |||
1025 | static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) | ||
1026 | { | ||
1027 | u8 gcw[2]; | ||
1028 | |||
1029 | *((u16 *) &gcw) = drive->id->config; | ||
1030 | floppy->pc = floppy->pc_stack; | ||
1031 | drive->pc_callback = ide_floppy_callback; | ||
1032 | |||
1033 | if (((gcw[0] & 0x60) >> 5) == 1) | ||
1034 | drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; | ||
1035 | /* | 516 | /* |
1036 | * We used to check revisions here. At this point however I'm giving up. | 517 | * We used to check revisions here. At this point however I'm giving up. |
1037 | * Just assume they are all broken, its easier. | 518 | * Just assume they are all broken, its easier. |
@@ -1041,10 +522,10 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) | |||
1041 | * it. It should be fixed as of version 1.9, but to be on the safe side | 522 | * it. It should be fixed as of version 1.9, but to be on the safe side |
1042 | * we'll leave the limitation below for the 2.2.x tree. | 523 | * we'll leave the limitation below for the 2.2.x tree. |
1043 | */ | 524 | */ |
1044 | if (!strncmp(drive->id->model, "IOMEGA ZIP 100 ATAPI", 20)) { | 525 | if (!strncmp((char *)&id[ATA_ID_PROD], "IOMEGA ZIP 100 ATAPI", 20)) { |
1045 | drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE; | 526 | drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE; |
1046 | /* This value will be visible in the /proc/ide/hdx/settings */ | 527 | /* This value will be visible in the /proc/ide/hdx/settings */ |
1047 | floppy->ticks = IDEFLOPPY_TICKS_DELAY; | 528 | drive->pc_delay = IDEFLOPPY_PC_DELAY; |
1048 | blk_queue_max_sectors(drive->queue, 64); | 529 | blk_queue_max_sectors(drive->queue, 64); |
1049 | } | 530 | } |
1050 | 531 | ||
@@ -1052,406 +533,46 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) | |||
1052 | * Guess what? The IOMEGA Clik! drive also needs the above fix. It makes | 533 | * Guess what? The IOMEGA Clik! drive also needs the above fix. It makes |
1053 | * nasty clicking noises without it, so please don't remove this. | 534 | * nasty clicking noises without it, so please don't remove this. |
1054 | */ | 535 | */ |
1055 | if (strncmp(drive->id->model, "IOMEGA Clik!", 11) == 0) { | 536 | if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) { |
1056 | blk_queue_max_sectors(drive->queue, 64); | 537 | blk_queue_max_sectors(drive->queue, 64); |
1057 | drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; | 538 | drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; |
539 | /* IOMEGA Clik! drives do not support lock/unlock commands */ | ||
540 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; | ||
1058 | } | 541 | } |
1059 | 542 | ||
1060 | (void) ide_floppy_get_capacity(drive); | 543 | (void) ide_floppy_get_capacity(drive); |
1061 | idefloppy_add_settings(drive); | ||
1062 | } | ||
1063 | |||
1064 | static void ide_floppy_remove(ide_drive_t *drive) | ||
1065 | { | ||
1066 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
1067 | struct gendisk *g = floppy->disk; | ||
1068 | 544 | ||
1069 | ide_proc_unregister_driver(drive, floppy->driver); | 545 | ide_proc_register_driver(drive, floppy->driver); |
1070 | 546 | ||
1071 | del_gendisk(g); | 547 | drive->dev_flags |= IDE_DFLAG_ATTACH; |
1072 | |||
1073 | ide_floppy_put(floppy); | ||
1074 | } | 548 | } |
1075 | 549 | ||
1076 | static void idefloppy_cleanup_obj(struct kref *kref) | 550 | static void ide_floppy_flush(ide_drive_t *drive) |
1077 | { | 551 | { |
1078 | struct ide_floppy_obj *floppy = to_ide_floppy(kref); | ||
1079 | ide_drive_t *drive = floppy->drive; | ||
1080 | struct gendisk *g = floppy->disk; | ||
1081 | |||
1082 | drive->driver_data = NULL; | ||
1083 | g->private_data = NULL; | ||
1084 | put_disk(g); | ||
1085 | kfree(floppy); | ||
1086 | } | 552 | } |
1087 | 553 | ||
1088 | #ifdef CONFIG_IDE_PROC_FS | 554 | static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk) |
1089 | static int proc_idefloppy_read_capacity(char *page, char **start, off_t off, | ||
1090 | int count, int *eof, void *data) | ||
1091 | { | ||
1092 | ide_drive_t*drive = (ide_drive_t *)data; | ||
1093 | int len; | ||
1094 | |||
1095 | len = sprintf(page, "%llu\n", (long long)idefloppy_capacity(drive)); | ||
1096 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); | ||
1097 | } | ||
1098 | |||
1099 | static ide_proc_entry_t idefloppy_proc[] = { | ||
1100 | { "capacity", S_IFREG|S_IRUGO, proc_idefloppy_read_capacity, NULL }, | ||
1101 | { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, | ||
1102 | { NULL, 0, NULL, NULL } | ||
1103 | }; | ||
1104 | #endif /* CONFIG_IDE_PROC_FS */ | ||
1105 | |||
1106 | static int ide_floppy_probe(ide_drive_t *); | ||
1107 | |||
1108 | static ide_driver_t idefloppy_driver = { | ||
1109 | .gen_driver = { | ||
1110 | .owner = THIS_MODULE, | ||
1111 | .name = "ide-floppy", | ||
1112 | .bus = &ide_bus_type, | ||
1113 | }, | ||
1114 | .probe = ide_floppy_probe, | ||
1115 | .remove = ide_floppy_remove, | ||
1116 | .version = IDEFLOPPY_VERSION, | ||
1117 | .media = ide_floppy, | ||
1118 | .supports_dsc_overlap = 0, | ||
1119 | .do_request = idefloppy_do_request, | ||
1120 | .end_request = idefloppy_end_request, | ||
1121 | .error = __ide_error, | ||
1122 | #ifdef CONFIG_IDE_PROC_FS | ||
1123 | .proc = idefloppy_proc, | ||
1124 | #endif | ||
1125 | }; | ||
1126 | |||
1127 | static int idefloppy_open(struct inode *inode, struct file *filp) | ||
1128 | { | 555 | { |
1129 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
1130 | struct ide_floppy_obj *floppy; | ||
1131 | ide_drive_t *drive; | ||
1132 | struct ide_atapi_pc pc; | ||
1133 | int ret = 0; | 556 | int ret = 0; |
1134 | 557 | ||
1135 | debug_log("Reached %s\n", __func__); | 558 | if (ide_do_test_unit_ready(drive, disk)) |
1136 | 559 | ide_do_start_stop(drive, disk, 1); | |
1137 | floppy = ide_floppy_get(disk); | ||
1138 | if (!floppy) | ||
1139 | return -ENXIO; | ||
1140 | |||
1141 | drive = floppy->drive; | ||
1142 | |||
1143 | floppy->openers++; | ||
1144 | |||
1145 | if (floppy->openers == 1) { | ||
1146 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | ||
1147 | /* Just in case */ | ||
1148 | 560 | ||
1149 | idefloppy_init_pc(&pc); | 561 | ret = ide_floppy_get_capacity(drive); |
1150 | pc.c[0] = GPCMD_TEST_UNIT_READY; | ||
1151 | 562 | ||
1152 | if (idefloppy_queue_pc_tail(drive, &pc)) { | 563 | set_capacity(disk, ide_gd_capacity(drive)); |
1153 | idefloppy_create_start_stop_cmd(&pc, 1); | ||
1154 | (void) idefloppy_queue_pc_tail(drive, &pc); | ||
1155 | } | ||
1156 | |||
1157 | if (ide_floppy_get_capacity(drive) | ||
1158 | && (filp->f_flags & O_NDELAY) == 0 | ||
1159 | /* | ||
1160 | * Allow O_NDELAY to open a drive without a disk, or with an | ||
1161 | * unreadable disk, so that we can get the format capacity | ||
1162 | * of the drive or begin the format - Sam | ||
1163 | */ | ||
1164 | ) { | ||
1165 | ret = -EIO; | ||
1166 | goto out_put_floppy; | ||
1167 | } | ||
1168 | 564 | ||
1169 | if (floppy->wp && (filp->f_mode & 2)) { | ||
1170 | ret = -EROFS; | ||
1171 | goto out_put_floppy; | ||
1172 | } | ||
1173 | drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED; | ||
1174 | /* IOMEGA Clik! drives do not support lock/unlock commands */ | ||
1175 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) { | ||
1176 | idefloppy_create_prevent_cmd(&pc, 1); | ||
1177 | (void) idefloppy_queue_pc_tail(drive, &pc); | ||
1178 | } | ||
1179 | check_disk_change(inode->i_bdev); | ||
1180 | } else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) { | ||
1181 | ret = -EBUSY; | ||
1182 | goto out_put_floppy; | ||
1183 | } | ||
1184 | return 0; | ||
1185 | |||
1186 | out_put_floppy: | ||
1187 | floppy->openers--; | ||
1188 | ide_floppy_put(floppy); | ||
1189 | return ret; | 565 | return ret; |
1190 | } | 566 | } |
1191 | 567 | ||
1192 | static int idefloppy_release(struct inode *inode, struct file *filp) | 568 | const struct ide_disk_ops ide_atapi_disk_ops = { |
1193 | { | 569 | .check = ide_check_atapi_device, |
1194 | struct gendisk *disk = inode->i_bdev->bd_disk; | 570 | .get_capacity = ide_floppy_get_capacity, |
1195 | struct ide_floppy_obj *floppy = ide_floppy_g(disk); | 571 | .setup = ide_floppy_setup, |
1196 | ide_drive_t *drive = floppy->drive; | 572 | .flush = ide_floppy_flush, |
1197 | struct ide_atapi_pc pc; | 573 | .init_media = ide_floppy_init_media, |
1198 | 574 | .set_doorlock = ide_set_media_lock, | |
1199 | debug_log("Reached %s\n", __func__); | 575 | .do_request = ide_floppy_do_request, |
1200 | 576 | .end_request = ide_floppy_end_request, | |
1201 | if (floppy->openers == 1) { | 577 | .ioctl = ide_floppy_ioctl, |
1202 | /* IOMEGA Clik! drives do not support lock/unlock commands */ | ||
1203 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) { | ||
1204 | idefloppy_create_prevent_cmd(&pc, 0); | ||
1205 | (void) idefloppy_queue_pc_tail(drive, &pc); | ||
1206 | } | ||
1207 | |||
1208 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | ||
1209 | } | ||
1210 | |||
1211 | floppy->openers--; | ||
1212 | |||
1213 | ide_floppy_put(floppy); | ||
1214 | |||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
1219 | { | ||
1220 | struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); | ||
1221 | ide_drive_t *drive = floppy->drive; | ||
1222 | |||
1223 | geo->heads = drive->bios_head; | ||
1224 | geo->sectors = drive->bios_sect; | ||
1225 | geo->cylinders = (u16)drive->bios_cyl; /* truncate */ | ||
1226 | return 0; | ||
1227 | } | ||
1228 | |||
1229 | static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, | ||
1230 | unsigned long arg, unsigned int cmd) | ||
1231 | { | ||
1232 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
1233 | |||
1234 | if (floppy->openers > 1) | ||
1235 | return -EBUSY; | ||
1236 | |||
1237 | /* The IOMEGA Clik! Drive doesn't support this command - | ||
1238 | * no room for an eject mechanism */ | ||
1239 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) { | ||
1240 | int prevent = arg ? 1 : 0; | ||
1241 | |||
1242 | if (cmd == CDROMEJECT) | ||
1243 | prevent = 0; | ||
1244 | |||
1245 | idefloppy_create_prevent_cmd(pc, prevent); | ||
1246 | (void) idefloppy_queue_pc_tail(floppy->drive, pc); | ||
1247 | } | ||
1248 | |||
1249 | if (cmd == CDROMEJECT) { | ||
1250 | idefloppy_create_start_stop_cmd(pc, 2); | ||
1251 | (void) idefloppy_queue_pc_tail(floppy->drive, pc); | ||
1252 | } | ||
1253 | |||
1254 | return 0; | ||
1255 | } | ||
1256 | |||
1257 | static int ide_floppy_format_unit(idefloppy_floppy_t *floppy, | ||
1258 | int __user *arg) | ||
1259 | { | ||
1260 | struct ide_atapi_pc pc; | ||
1261 | ide_drive_t *drive = floppy->drive; | ||
1262 | int blocks, length, flags, err = 0; | ||
1263 | |||
1264 | if (floppy->openers > 1) { | ||
1265 | /* Don't format if someone is using the disk */ | ||
1266 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | ||
1267 | return -EBUSY; | ||
1268 | } | ||
1269 | |||
1270 | drive->atapi_flags |= IDE_AFLAG_FORMAT_IN_PROGRESS; | ||
1271 | |||
1272 | /* | ||
1273 | * Send ATAPI_FORMAT_UNIT to the drive. | ||
1274 | * | ||
1275 | * Userland gives us the following structure: | ||
1276 | * | ||
1277 | * struct idefloppy_format_command { | ||
1278 | * int nblocks; | ||
1279 | * int blocksize; | ||
1280 | * int flags; | ||
1281 | * } ; | ||
1282 | * | ||
1283 | * flags is a bitmask, currently, the only defined flag is: | ||
1284 | * | ||
1285 | * 0x01 - verify media after format. | ||
1286 | */ | ||
1287 | if (get_user(blocks, arg) || | ||
1288 | get_user(length, arg+1) || | ||
1289 | get_user(flags, arg+2)) { | ||
1290 | err = -EFAULT; | ||
1291 | goto out; | ||
1292 | } | ||
1293 | |||
1294 | (void) idefloppy_get_sfrp_bit(drive); | ||
1295 | idefloppy_create_format_unit_cmd(&pc, blocks, length, flags); | ||
1296 | |||
1297 | if (idefloppy_queue_pc_tail(drive, &pc)) | ||
1298 | err = -EIO; | ||
1299 | |||
1300 | out: | ||
1301 | if (err) | ||
1302 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | ||
1303 | return err; | ||
1304 | } | ||
1305 | |||
1306 | |||
1307 | static int idefloppy_ioctl(struct inode *inode, struct file *file, | ||
1308 | unsigned int cmd, unsigned long arg) | ||
1309 | { | ||
1310 | struct block_device *bdev = inode->i_bdev; | ||
1311 | struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); | ||
1312 | ide_drive_t *drive = floppy->drive; | ||
1313 | struct ide_atapi_pc pc; | ||
1314 | void __user *argp = (void __user *)arg; | ||
1315 | int err; | ||
1316 | |||
1317 | switch (cmd) { | ||
1318 | case CDROMEJECT: | ||
1319 | /* fall through */ | ||
1320 | case CDROM_LOCKDOOR: | ||
1321 | return ide_floppy_lockdoor(drive, &pc, arg, cmd); | ||
1322 | case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED: | ||
1323 | return 0; | ||
1324 | case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY: | ||
1325 | return ide_floppy_get_format_capacities(drive, argp); | ||
1326 | case IDEFLOPPY_IOCTL_FORMAT_START: | ||
1327 | if (!(file->f_mode & 2)) | ||
1328 | return -EPERM; | ||
1329 | |||
1330 | return ide_floppy_format_unit(floppy, (int __user *)arg); | ||
1331 | case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: | ||
1332 | return idefloppy_get_format_progress(drive, argp); | ||
1333 | } | ||
1334 | |||
1335 | /* | ||
1336 | * skip SCSI_IOCTL_SEND_COMMAND (deprecated) | ||
1337 | * and CDROM_SEND_PACKET (legacy) ioctls | ||
1338 | */ | ||
1339 | if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND) | ||
1340 | err = scsi_cmd_ioctl(file, bdev->bd_disk->queue, | ||
1341 | bdev->bd_disk, cmd, argp); | ||
1342 | else | ||
1343 | err = -ENOTTY; | ||
1344 | |||
1345 | if (err == -ENOTTY) | ||
1346 | err = generic_ide_ioctl(drive, file, bdev, cmd, arg); | ||
1347 | |||
1348 | return err; | ||
1349 | } | ||
1350 | |||
1351 | static int idefloppy_media_changed(struct gendisk *disk) | ||
1352 | { | ||
1353 | struct ide_floppy_obj *floppy = ide_floppy_g(disk); | ||
1354 | ide_drive_t *drive = floppy->drive; | ||
1355 | int ret; | ||
1356 | |||
1357 | /* do not scan partitions twice if this is a removable device */ | ||
1358 | if (drive->attach) { | ||
1359 | drive->attach = 0; | ||
1360 | return 0; | ||
1361 | } | ||
1362 | ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED); | ||
1363 | drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED; | ||
1364 | return ret; | ||
1365 | } | ||
1366 | |||
1367 | static int idefloppy_revalidate_disk(struct gendisk *disk) | ||
1368 | { | ||
1369 | struct ide_floppy_obj *floppy = ide_floppy_g(disk); | ||
1370 | set_capacity(disk, idefloppy_capacity(floppy->drive)); | ||
1371 | return 0; | ||
1372 | } | ||
1373 | |||
1374 | static struct block_device_operations idefloppy_ops = { | ||
1375 | .owner = THIS_MODULE, | ||
1376 | .open = idefloppy_open, | ||
1377 | .release = idefloppy_release, | ||
1378 | .ioctl = idefloppy_ioctl, | ||
1379 | .getgeo = idefloppy_getgeo, | ||
1380 | .media_changed = idefloppy_media_changed, | ||
1381 | .revalidate_disk = idefloppy_revalidate_disk | ||
1382 | }; | 578 | }; |
1383 | |||
1384 | static int ide_floppy_probe(ide_drive_t *drive) | ||
1385 | { | ||
1386 | idefloppy_floppy_t *floppy; | ||
1387 | struct gendisk *g; | ||
1388 | |||
1389 | if (!strstr("ide-floppy", drive->driver_req)) | ||
1390 | goto failed; | ||
1391 | if (!drive->present) | ||
1392 | goto failed; | ||
1393 | if (drive->media != ide_floppy) | ||
1394 | goto failed; | ||
1395 | if (!idefloppy_identify_device(drive, drive->id)) { | ||
1396 | printk(KERN_ERR "ide-floppy: %s: not supported by this version" | ||
1397 | " of ide-floppy\n", drive->name); | ||
1398 | goto failed; | ||
1399 | } | ||
1400 | floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); | ||
1401 | if (!floppy) { | ||
1402 | printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy" | ||
1403 | " structure\n", drive->name); | ||
1404 | goto failed; | ||
1405 | } | ||
1406 | |||
1407 | g = alloc_disk(1 << PARTN_BITS); | ||
1408 | if (!g) | ||
1409 | goto out_free_floppy; | ||
1410 | |||
1411 | ide_init_disk(g, drive); | ||
1412 | |||
1413 | ide_proc_register_driver(drive, &idefloppy_driver); | ||
1414 | |||
1415 | kref_init(&floppy->kref); | ||
1416 | |||
1417 | floppy->drive = drive; | ||
1418 | floppy->driver = &idefloppy_driver; | ||
1419 | floppy->disk = g; | ||
1420 | |||
1421 | g->private_data = &floppy->driver; | ||
1422 | |||
1423 | drive->driver_data = floppy; | ||
1424 | |||
1425 | idefloppy_setup(drive, floppy); | ||
1426 | |||
1427 | g->minors = 1 << PARTN_BITS; | ||
1428 | g->driverfs_dev = &drive->gendev; | ||
1429 | g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; | ||
1430 | g->fops = &idefloppy_ops; | ||
1431 | drive->attach = 1; | ||
1432 | add_disk(g); | ||
1433 | return 0; | ||
1434 | |||
1435 | out_free_floppy: | ||
1436 | kfree(floppy); | ||
1437 | failed: | ||
1438 | return -ENODEV; | ||
1439 | } | ||
1440 | |||
1441 | static void __exit idefloppy_exit(void) | ||
1442 | { | ||
1443 | driver_unregister(&idefloppy_driver.gen_driver); | ||
1444 | } | ||
1445 | |||
1446 | static int __init idefloppy_init(void) | ||
1447 | { | ||
1448 | printk("ide-floppy driver " IDEFLOPPY_VERSION "\n"); | ||
1449 | return driver_register(&idefloppy_driver.gen_driver); | ||
1450 | } | ||
1451 | |||
1452 | MODULE_ALIAS("ide:*m-floppy*"); | ||
1453 | module_init(idefloppy_init); | ||
1454 | module_exit(idefloppy_exit); | ||
1455 | MODULE_LICENSE("GPL"); | ||
1456 | MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); | ||
1457 | |||