Blame view
drivers/ide/ide-floppy.c
26.6 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
d3f208488 ide-floppy: clean... |
2 3 |
* IDE ATAPI floppy driver. * |
59bca8cc9 ide: update/add m... |
4 5 6 |
* Copyright (C) 1996-1999 Gadi Oxman <gadio@netvision.net.il> * Copyright (C) 2000-2002 Paul Bristow <paul@paulbristow.net> * Copyright (C) 2005 Bartlomiej Zolnierkiewicz |
0571c7a4f ide-floppy: fix m... |
7 |
* |
1da177e4c Linux-2.6.12-rc2 |
8 9 10 11 12 13 |
* This driver supports the following IDE floppy drives: * * LS-120/240 SuperDisk * Iomega Zip 100/250 * Iomega PC Card Clik!/PocketZip * |
d3f208488 ide-floppy: clean... |
14 15 |
* For a historical changelog see * Documentation/ide/ChangeLog.ide-floppy.1996-2002 |
1da177e4c Linux-2.6.12-rc2 |
16 |
*/ |
51509eec3 ide: add ide_chec... |
17 |
#define DRV_NAME "ide-floppy" |
fc6c5bc7c ide-floppy: bump ... |
18 |
#define IDEFLOPPY_VERSION "1.00" |
1da177e4c Linux-2.6.12-rc2 |
19 |
|
1da177e4c Linux-2.6.12-rc2 |
20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <linux/module.h> #include <linux/types.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/timer.h> #include <linux/mm.h> #include <linux/interrupt.h> #include <linux/major.h> #include <linux/errno.h> #include <linux/genhd.h> #include <linux/slab.h> #include <linux/cdrom.h> #include <linux/ide.h> |
3ceca727f ide: include <lin... |
34 |
#include <linux/hdreg.h> |
1da177e4c Linux-2.6.12-rc2 |
35 |
#include <linux/bitops.h> |
cf8b8975c [PATCH] sem2mutex... |
36 |
#include <linux/mutex.h> |
b98b3409a ide-floppy: use s... |
37 |
#include <linux/scatterlist.h> |
1da177e4c Linux-2.6.12-rc2 |
38 |
|
89636af25 ide: add support ... |
39 |
#include <scsi/scsi_ioctl.h> |
1da177e4c Linux-2.6.12-rc2 |
40 |
#include <asm/byteorder.h> |
7e8b163b2 ide-floppy: inclu... |
41 42 43 |
#include <linux/irq.h> #include <linux/uaccess.h> #include <linux/io.h> |
1da177e4c Linux-2.6.12-rc2 |
44 |
#include <asm/unaligned.h> |
0127854d7 ide-floppy: move ... |
45 |
#include "ide-floppy.h" |
f373bd820 ide-floppy: remov... |
46 |
/* define to see debug info */ |
1da177e4c Linux-2.6.12-rc2 |
47 |
#define IDEFLOPPY_DEBUG_LOG 0 |
1da177e4c Linux-2.6.12-rc2 |
48 49 |
/* #define IDEFLOPPY_DEBUG(fmt, args...) printk(KERN_INFO fmt, ## args) */ |
0571c7a4f ide-floppy: fix m... |
50 |
#define IDEFLOPPY_DEBUG(fmt, args...) |
1da177e4c Linux-2.6.12-rc2 |
51 52 |
#if IDEFLOPPY_DEBUG_LOG |
bcc77d9cc ide-floppy: clean... |
53 54 |
#define debug_log(fmt, args...) \ printk(KERN_INFO "ide-floppy: " fmt, ## args) |
1da177e4c Linux-2.6.12-rc2 |
55 |
#else |
0571c7a4f ide-floppy: fix m... |
56 |
#define debug_log(fmt, args...) do {} while (0) |
1da177e4c Linux-2.6.12-rc2 |
57 |
#endif |
0571c7a4f ide-floppy: fix m... |
58 |
/* Some drives require a longer irq timeout. */ |
1da177e4c Linux-2.6.12-rc2 |
59 60 61 |
#define IDEFLOPPY_WAIT_CMD (5 * WAIT_CMD) /* |
0571c7a4f ide-floppy: fix m... |
62 63 |
* After each failed packet command we issue a request sense command and retry * the packet command IDEFLOPPY_MAX_PC_RETRIES times. |
1da177e4c Linux-2.6.12-rc2 |
64 65 |
*/ #define IDEFLOPPY_MAX_PC_RETRIES 3 |
194ec0c07 ide-floppy: remov... |
66 |
/* format capacities descriptor codes */ |
1da177e4c Linux-2.6.12-rc2 |
67 68 69 70 |
#define CAPACITY_INVALID 0x00 #define CAPACITY_UNFORMATTED 0x01 #define CAPACITY_CURRENT 0x02 #define CAPACITY_NO_CARTRIDGE 0x03 |
c40d3d38a [PATCH] ide-flopp... |
71 |
#define IDEFLOPPY_TICKS_DELAY HZ/20 /* default delay for ZIP 100 (50ms) */ |
1da177e4c Linux-2.6.12-rc2 |
72 |
|
0571c7a4f ide-floppy: fix m... |
73 |
/* Error code returned in rq->errors to the higher part of the driver. */ |
1da177e4c Linux-2.6.12-rc2 |
74 |
#define IDEFLOPPY_ERROR_GENERAL 101 |
cf8b8975c [PATCH] sem2mutex... |
75 |
static DEFINE_MUTEX(idefloppy_ref_mutex); |
1da177e4c Linux-2.6.12-rc2 |
76 77 78 79 80 |
#define to_ide_floppy(obj) container_of(obj, struct ide_floppy_obj, kref) #define ide_floppy_g(disk) \ container_of((disk)->private_data, struct ide_floppy_obj, driver) |
08da591e1 ide: add ide_devi... |
81 |
static void idefloppy_cleanup_obj(struct kref *); |
1da177e4c Linux-2.6.12-rc2 |
82 83 84 |
static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) { struct ide_floppy_obj *floppy = NULL; |
cf8b8975c [PATCH] sem2mutex... |
85 |
mutex_lock(&idefloppy_ref_mutex); |
1da177e4c Linux-2.6.12-rc2 |
86 |
floppy = ide_floppy_g(disk); |
08da591e1 ide: add ide_devi... |
87 |
if (floppy) { |
d3e33ff59 ide: fix regressi... |
88 |
if (ide_device_get(floppy->drive)) |
08da591e1 ide: add ide_devi... |
89 |
floppy = NULL; |
d3e33ff59 ide: fix regressi... |
90 91 |
else kref_get(&floppy->kref); |
08da591e1 ide: add ide_devi... |
92 |
} |
cf8b8975c [PATCH] sem2mutex... |
93 |
mutex_unlock(&idefloppy_ref_mutex); |
1da177e4c Linux-2.6.12-rc2 |
94 95 |
return floppy; } |
1da177e4c Linux-2.6.12-rc2 |
96 97 |
static void ide_floppy_put(struct ide_floppy_obj *floppy) { |
d3e33ff59 ide: fix regressi... |
98 |
ide_drive_t *drive = floppy->drive; |
cf8b8975c [PATCH] sem2mutex... |
99 |
mutex_lock(&idefloppy_ref_mutex); |
9a24b63db ide-floppy: disam... |
100 |
kref_put(&floppy->kref, idefloppy_cleanup_obj); |
d3e33ff59 ide: fix regressi... |
101 |
ide_device_put(drive); |
cf8b8975c [PATCH] sem2mutex... |
102 |
mutex_unlock(&idefloppy_ref_mutex); |
1da177e4c Linux-2.6.12-rc2 |
103 104 105 |
} /* |
0571c7a4f ide-floppy: fix m... |
106 107 |
* Used to finish servicing a request. For read/write requests, we will call * ide_end_request to pass to the next buffer. |
1da177e4c Linux-2.6.12-rc2 |
108 |
*/ |
c2b2b2936 ide-floppy: renam... |
109 |
static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) |
1da177e4c Linux-2.6.12-rc2 |
110 111 112 113 |
{ idefloppy_floppy_t *floppy = drive->driver_data; struct request *rq = HWGROUP(drive)->rq; int error; |
bcc77d9cc ide-floppy: clean... |
114 115 |
debug_log("Reached %s ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
116 117 |
switch (uptodate) { |
0571c7a4f ide-floppy: fix m... |
118 119 120 |
case 0: error = IDEFLOPPY_ERROR_GENERAL; break; case 1: error = 0; break; default: error = uptodate; |
1da177e4c Linux-2.6.12-rc2 |
121 122 123 124 125 126 |
} if (error) floppy->failed_pc = NULL; /* Why does this happen? */ if (!rq) return 0; |
4aff5e233 [PATCH] Split str... |
127 |
if (!blk_special_request(rq)) { |
1da177e4c Linux-2.6.12-rc2 |
128 129 130 131 132 133 134 135 136 |
/* our real local end request function */ ide_end_request(drive, uptodate, nsecs); return 0; } rq->errors = error; /* fixme: need to move this local also */ ide_end_drive_cmd(drive, 0, 0); return 0; } |
8e5551239 ide-floppy: conve... |
137 138 |
static void idefloppy_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) |
1da177e4c Linux-2.6.12-rc2 |
139 140 141 142 143 |
{ struct request *rq = pc->rq; struct bio *bio = rq->bio; while ((bio = rq->bio) != NULL) |
c2b2b2936 ide-floppy: renam... |
144 |
idefloppy_end_request(drive, 1, 0); |
1da177e4c Linux-2.6.12-rc2 |
145 |
} |
81f493823 ide-floppy: merge... |
146 |
static void ide_floppy_callback(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
147 148 |
{ idefloppy_floppy_t *floppy = drive->driver_data; |
81f493823 ide-floppy: merge... |
149 150 |
struct ide_atapi_pc *pc = floppy->pc; int uptodate = pc->error ? 0 : 1; |
1da177e4c Linux-2.6.12-rc2 |
151 |
|
bcc77d9cc ide-floppy: clean... |
152 153 |
debug_log("Reached %s ", __func__); |
dd2e9a032 ide-{floppy,tape}... |
154 155 |
if (floppy->failed_pc == pc) floppy->failed_pc = NULL; |
81f493823 ide-floppy: merge... |
156 157 158 159 160 |
if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || (pc->rq && blk_pc_request(pc->rq))) uptodate = 1; /* FIXME */ else if (pc->c[0] == GPCMD_REQUEST_SENSE) { u8 *buf = floppy->pc->buf; |
a6ff2d3b0 ide-floppy: remov... |
161 |
|
81f493823 ide-floppy: merge... |
162 163 164 165 166 167 |
if (!pc->error) { floppy->sense_key = buf[2] & 0x0F; floppy->asc = buf[12]; floppy->ascq = buf[13]; floppy->progress_indication = buf[15] & 0x80 ? (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; |
a6ff2d3b0 ide-floppy: remov... |
168 |
|
81f493823 ide-floppy: merge... |
169 170 |
if (floppy->failed_pc) debug_log("pc = %x, ", floppy->failed_pc->c[0]); |
bcc77d9cc ide-floppy: clean... |
171 |
|
81f493823 ide-floppy: merge... |
172 173 174 175 176 177 178 179 |
debug_log("sense key = %x, asc = %x, ascq = %x ", floppy->sense_key, floppy->asc, floppy->ascq); } else printk(KERN_ERR "Error in REQUEST SENSE itself - " "Aborting request! "); } |
1da177e4c Linux-2.6.12-rc2 |
180 |
|
81f493823 ide-floppy: merge... |
181 |
idefloppy_end_request(drive, uptodate, 0); |
1da177e4c Linux-2.6.12-rc2 |
182 |
} |
0127854d7 ide-floppy: move ... |
183 |
void ide_floppy_create_request_sense_cmd(struct ide_atapi_pc *pc) |
1da177e4c Linux-2.6.12-rc2 |
184 |
{ |
7bf7420a3 ide: add ide_init... |
185 |
ide_init_pc(pc); |
30d670993 ide-floppy: conve... |
186 |
pc->c[0] = GPCMD_REQUEST_SENSE; |
1da177e4c Linux-2.6.12-rc2 |
187 |
pc->c[4] = 255; |
8e5551239 ide-floppy: conve... |
188 |
pc->req_xfer = 18; |
1da177e4c Linux-2.6.12-rc2 |
189 190 191 |
} /* |
0571c7a4f ide-floppy: fix m... |
192 193 |
* Called when an error was detected during the last packet command. We queue a * request sense packet command in the head of the request list. |
1da177e4c Linux-2.6.12-rc2 |
194 |
*/ |
0571c7a4f ide-floppy: fix m... |
195 |
static void idefloppy_retry_pc(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
196 |
{ |
394a4c210 ide-{floppy,tape}... |
197 198 |
struct ide_floppy_obj *floppy = drive->driver_data; struct request *rq = &floppy->request_sense_rq; |
2e8a6f89d ide-{floppy,tape}... |
199 |
struct ide_atapi_pc *pc = &floppy->request_sense_pc; |
1da177e4c Linux-2.6.12-rc2 |
200 |
|
64a57fe43 ide: add ide_read... |
201 |
(void)ide_read_error(drive); |
0127854d7 ide-floppy: move ... |
202 |
ide_floppy_create_request_sense_cmd(pc); |
7645c1514 ide: add ide_queu... |
203 |
ide_queue_pc_head(drive, floppy->disk, pc, rq); |
1da177e4c Linux-2.6.12-rc2 |
204 |
} |
0eea6458c ide-floppy: use a... |
205 |
/* The usual interrupt handler called during a packet command. */ |
52d3ccf76 IDE: Coding Style... |
206 |
static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
207 208 |
{ idefloppy_floppy_t *floppy = drive->driver_data; |
1da177e4c Linux-2.6.12-rc2 |
209 |
|
646c0cb6c ide: add ide_pc_i... |
210 211 |
return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL, idefloppy_update_buffers, |
acaa0f5f6 ide: add ide_io_b... |
212 |
idefloppy_retry_pc, NULL, ide_io_buffers); |
1da177e4c Linux-2.6.12-rc2 |
213 214 215 |
} /* |
0571c7a4f ide-floppy: fix m... |
216 217 218 219 |
* What we have here is a classic case of a top half / bottom half interrupt * service routine. In interrupt mode, the device sends an interrupt to signal * that it is ready to receive a packet. However, we need to delay about 2-3 * ticks before issuing the packet or we gets in trouble. |
1da177e4c Linux-2.6.12-rc2 |
220 |
*/ |
cbbc4e818 ide-floppy: fix u... |
221 |
static int idefloppy_transfer_pc(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
222 223 224 225 |
{ idefloppy_floppy_t *floppy = drive->driver_data; /* Send the actual packet */ |
374e042c3 ide: add struct i... |
226 |
drive->hwif->tp_ops->output_data(drive, NULL, floppy->pc->c, 12); |
9567b349f ide: merge ->atap... |
227 |
|
1da177e4c Linux-2.6.12-rc2 |
228 229 230 |
/* Timeout for the packet command */ return IDEFLOPPY_WAIT_CMD; } |
cbbc4e818 ide-floppy: fix u... |
231 232 233 234 235 236 237 |
/* * Called as an interrupt (or directly). When the device says it's ready for a * packet, we schedule the packet transfer to occur about 2-3 ticks later in * transfer_pc. */ static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
238 239 |
{ idefloppy_floppy_t *floppy = drive->driver_data; |
6ffb66410 ide-floppy: start... |
240 |
struct ide_atapi_pc *pc = floppy->pc; |
0b2eea4c5 ide-floppy: merge... |
241 242 |
ide_expiry_t *expiry; unsigned int timeout; |
1da177e4c Linux-2.6.12-rc2 |
243 |
|
0571c7a4f ide-floppy: fix m... |
244 |
/* |
1da177e4c Linux-2.6.12-rc2 |
245 246 247 248 249 250 251 |
* The following delay solves a problem with ATAPI Zip 100 drives * where the Busy flag was apparently being deasserted before the * unit was ready to receive data. This was happening on a * 1200 MHz Athlon system. 10/26/01 25msec is too short, * 40 and 50msec work well. idefloppy_pc_intr will not be actually * used until after the packet is moved in about 50 msec. */ |
ea68d270f ide-floppy: conve... |
252 |
if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { |
0b2eea4c5 ide-floppy: merge... |
253 |
timeout = floppy->ticks; |
cbbc4e818 ide-floppy: fix u... |
254 |
expiry = &idefloppy_transfer_pc; |
0b2eea4c5 ide-floppy: merge... |
255 256 257 258 |
} else { timeout = IDEFLOPPY_WAIT_CMD; expiry = NULL; } |
594c16d8d ide: add ide_tran... |
259 |
return ide_transfer_pc(drive, pc, idefloppy_pc_intr, timeout, expiry); |
1da177e4c Linux-2.6.12-rc2 |
260 |
} |
d652c1380 ide-floppy: mv id... |
261 |
static void ide_floppy_report_error(idefloppy_floppy_t *floppy, |
8e5551239 ide-floppy: conve... |
262 |
struct ide_atapi_pc *pc) |
1da177e4c Linux-2.6.12-rc2 |
263 |
{ |
d652c1380 ide-floppy: mv id... |
264 |
/* supress error messages resulting from Medium not present */ |
1da177e4c Linux-2.6.12-rc2 |
265 266 267 |
if (floppy->sense_key == 0x02 && floppy->asc == 0x3a && floppy->ascq == 0x00) |
d652c1380 ide-floppy: mv id... |
268 269 270 271 272 273 274 |
return; printk(KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, " "asc = %2x, ascq = %2x ", floppy->drive->name, pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq); |
1da177e4c Linux-2.6.12-rc2 |
275 |
} |
0571c7a4f ide-floppy: fix m... |
276 |
static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, |
8e5551239 ide-floppy: conve... |
277 |
struct ide_atapi_pc *pc) |
1da177e4c Linux-2.6.12-rc2 |
278 279 |
{ idefloppy_floppy_t *floppy = drive->driver_data; |
1da177e4c Linux-2.6.12-rc2 |
280 |
|
1da177e4c Linux-2.6.12-rc2 |
281 |
if (floppy->failed_pc == NULL && |
30d670993 ide-floppy: conve... |
282 |
pc->c[0] != GPCMD_REQUEST_SENSE) |
1da177e4c Linux-2.6.12-rc2 |
283 284 285 |
floppy->failed_pc = pc; /* Set the current packet command */ floppy->pc = pc; |
757ced898 ide-floppy: remov... |
286 |
if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { |
6e5fa7b88 ide-floppy: remov... |
287 |
if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) |
757ced898 ide-floppy: remov... |
288 289 290 |
ide_floppy_report_error(floppy, pc); /* Giving up */ pc->error = IDEFLOPPY_ERROR_GENERAL; |
1da177e4c Linux-2.6.12-rc2 |
291 |
floppy->failed_pc = NULL; |
2207fa5af ide-floppy: use d... |
292 |
drive->pc_callback(drive); |
1da177e4c Linux-2.6.12-rc2 |
293 294 |
return ide_stopped; } |
bcc77d9cc ide-floppy: clean... |
295 296 |
debug_log("Retry number - %d ", pc->retries); |
1da177e4c Linux-2.6.12-rc2 |
297 298 |
pc->retries++; |
1da177e4c Linux-2.6.12-rc2 |
299 |
|
cbbc4e818 ide-floppy: fix u... |
300 |
return ide_issue_pc(drive, pc, idefloppy_start_pc_transfer, |
6bf1641ca ide: add ide_issu... |
301 |
IDEFLOPPY_WAIT_CMD, NULL); |
1da177e4c Linux-2.6.12-rc2 |
302 |
} |
0127854d7 ide-floppy: move ... |
303 |
void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) |
1da177e4c Linux-2.6.12-rc2 |
304 |
{ |
7bf7420a3 ide: add ide_init... |
305 |
ide_init_pc(pc); |
30d670993 ide-floppy: conve... |
306 |
pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES; |
1da177e4c Linux-2.6.12-rc2 |
307 308 |
pc->c[7] = 255; pc->c[8] = 255; |
8e5551239 ide-floppy: conve... |
309 |
pc->req_xfer = 255; |
1da177e4c Linux-2.6.12-rc2 |
310 |
} |
0571c7a4f ide-floppy: fix m... |
311 |
/* A mode sense command is used to "sense" floppy parameters. */ |
0127854d7 ide-floppy: move ... |
312 |
void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) |
1da177e4c Linux-2.6.12-rc2 |
313 |
{ |
24a5d7033 ide-floppy: remov... |
314 |
u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */ |
0571c7a4f ide-floppy: fix m... |
315 |
|
7bf7420a3 ide: add ide_init... |
316 |
ide_init_pc(pc); |
30d670993 ide-floppy: conve... |
317 |
pc->c[0] = GPCMD_MODE_SENSE_10; |
1da177e4c Linux-2.6.12-rc2 |
318 |
pc->c[1] = 0; |
4de4b9e14 ide-floppy: remov... |
319 |
pc->c[2] = page_code; |
1da177e4c Linux-2.6.12-rc2 |
320 321 |
switch (page_code) { |
0571c7a4f ide-floppy: fix m... |
322 323 324 325 326 327 328 329 |
case IDEFLOPPY_CAPABILITIES_PAGE: length += 12; break; case IDEFLOPPY_FLEXIBLE_DISK_PAGE: length += 32; break; default: printk(KERN_ERR "ide-floppy: unsupported page code " |
1da177e4c Linux-2.6.12-rc2 |
330 331 332 |
"in create_mode_sense_cmd "); } |
8f6224308 ide-floppy: repla... |
333 |
put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]); |
8e5551239 ide-floppy: conve... |
334 |
pc->req_xfer = length; |
1da177e4c Linux-2.6.12-rc2 |
335 |
} |
8e5551239 ide-floppy: conve... |
336 |
static void idefloppy_create_start_stop_cmd(struct ide_atapi_pc *pc, int start) |
1da177e4c Linux-2.6.12-rc2 |
337 |
{ |
7bf7420a3 ide: add ide_init... |
338 |
ide_init_pc(pc); |
30d670993 ide-floppy: conve... |
339 |
pc->c[0] = GPCMD_START_STOP_UNIT; |
1da177e4c Linux-2.6.12-rc2 |
340 341 |
pc->c[4] = start; } |
ae7e8ddc3 ide-floppy: remov... |
342 |
static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, |
8e5551239 ide-floppy: conve... |
343 |
struct ide_atapi_pc *pc, struct request *rq, |
ae7e8ddc3 ide-floppy: remov... |
344 |
unsigned long sector) |
1da177e4c Linux-2.6.12-rc2 |
345 346 347 348 |
{ int block = sector / floppy->bs_factor; int blocks = rq->nr_sectors / floppy->bs_factor; int cmd = rq_data_dir(rq); |
ae7e8ddc3 ide-floppy: remov... |
349 350 |
debug_log("create_rw10_cmd: block == %d, blocks == %d ", |
1da177e4c Linux-2.6.12-rc2 |
351 |
block, blocks); |
7bf7420a3 ide: add ide_init... |
352 |
ide_init_pc(pc); |
ae7e8ddc3 ide-floppy: remov... |
353 354 |
pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); |
8f6224308 ide-floppy: repla... |
355 |
put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); |
ae7e8ddc3 ide-floppy: remov... |
356 |
|
20cd93be6 ide-floppy: pass ... |
357 |
memcpy(rq->cmd, pc->c, 12); |
1da177e4c Linux-2.6.12-rc2 |
358 |
pc->rq = rq; |
b98b3409a ide-floppy: use s... |
359 |
pc->b_count = 0; |
4aff5e233 [PATCH] Split str... |
360 |
if (rq->cmd_flags & REQ_RW) |
6e5fa7b88 ide-floppy: remov... |
361 |
pc->flags |= PC_FLAG_WRITING; |
8e5551239 ide-floppy: conve... |
362 363 |
pc->buf = NULL; pc->req_xfer = pc->buf_size = blocks * floppy->block_size; |
5e3310958 ide-{floppy,tape}... |
364 |
pc->flags |= PC_FLAG_DMA_OK; |
1da177e4c Linux-2.6.12-rc2 |
365 |
} |
0571c7a4f ide-floppy: fix m... |
366 |
static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, |
8e5551239 ide-floppy: conve... |
367 |
struct ide_atapi_pc *pc, struct request *rq) |
1da177e4c Linux-2.6.12-rc2 |
368 |
{ |
7bf7420a3 ide: add ide_init... |
369 |
ide_init_pc(pc); |
1da177e4c Linux-2.6.12-rc2 |
370 |
memcpy(pc->c, rq->cmd, sizeof(pc->c)); |
3d6392cfb bsg: support for ... |
371 |
pc->rq = rq; |
b98b3409a ide-floppy: use s... |
372 |
pc->b_count = 0; |
3d6392cfb bsg: support for ... |
373 |
if (rq->data_len && rq_data_dir(rq) == WRITE) |
6e5fa7b88 ide-floppy: remov... |
374 |
pc->flags |= PC_FLAG_WRITING; |
8e5551239 ide-floppy: conve... |
375 |
pc->buf = rq->data; |
3d6392cfb bsg: support for ... |
376 |
if (rq->bio) |
5e3310958 ide-{floppy,tape}... |
377 |
pc->flags |= PC_FLAG_DMA_OK; |
3d6392cfb bsg: support for ... |
378 379 380 381 |
/* * possibly problematic, doesn't look like ide-floppy correctly * handled scattered requests if dma fails... */ |
8e5551239 ide-floppy: conve... |
382 |
pc->req_xfer = pc->buf_size = rq->data_len; |
1da177e4c Linux-2.6.12-rc2 |
383 |
} |
0571c7a4f ide-floppy: fix m... |
384 385 |
static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, struct request *rq, sector_t block_s) |
1da177e4c Linux-2.6.12-rc2 |
386 387 |
{ idefloppy_floppy_t *floppy = drive->driver_data; |
b98b3409a ide-floppy: use s... |
388 |
ide_hwif_t *hwif = drive->hwif; |
8e5551239 ide-floppy: conve... |
389 |
struct ide_atapi_pc *pc; |
1da177e4c Linux-2.6.12-rc2 |
390 |
unsigned long block = (unsigned long)block_s; |
b98b3409a ide-floppy: use s... |
391 392 393 394 395 396 397 398 399 |
debug_log("%s: dev: %s, cmd: 0x%x, cmd_type: %x, errors: %d ", __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd[0], rq->cmd_type, rq->errors); debug_log("%s: sector: %ld, nr_sectors: %ld, current_nr_sectors: %d ", __func__, (long)rq->sector, rq->nr_sectors, rq->current_nr_sectors); |
1da177e4c Linux-2.6.12-rc2 |
400 401 |
if (rq->errors >= ERROR_MAX) { |
d652c1380 ide-floppy: mv id... |
402 403 |
if (floppy->failed_pc) ide_floppy_report_error(floppy, floppy->failed_pc); |
1da177e4c Linux-2.6.12-rc2 |
404 405 406 407 |
else printk(KERN_ERR "ide-floppy: %s: I/O error ", drive->name); |
c2b2b2936 ide-floppy: renam... |
408 |
idefloppy_end_request(drive, 0, 0); |
1da177e4c Linux-2.6.12-rc2 |
409 410 |
return ide_stopped; } |
4aff5e233 [PATCH] Split str... |
411 |
if (blk_fs_request(rq)) { |
1da177e4c Linux-2.6.12-rc2 |
412 413 |
if (((long)rq->sector % floppy->bs_factor) || (rq->nr_sectors % floppy->bs_factor)) { |
0571c7a4f ide-floppy: fix m... |
414 415 416 |
printk(KERN_ERR "%s: unsupported r/w request size ", drive->name); |
c2b2b2936 ide-floppy: renam... |
417 |
idefloppy_end_request(drive, 0, 0); |
1da177e4c Linux-2.6.12-rc2 |
418 419 |
return ide_stopped; } |
2e8a6f89d ide-{floppy,tape}... |
420 |
pc = &floppy->queued_pc; |
1da177e4c Linux-2.6.12-rc2 |
421 |
idefloppy_create_rw_cmd(floppy, pc, rq, block); |
4aff5e233 [PATCH] Split str... |
422 |
} else if (blk_special_request(rq)) { |
8e5551239 ide-floppy: conve... |
423 |
pc = (struct ide_atapi_pc *) rq->buffer; |
4aff5e233 [PATCH] Split str... |
424 |
} else if (blk_pc_request(rq)) { |
2e8a6f89d ide-{floppy,tape}... |
425 |
pc = &floppy->queued_pc; |
3d6392cfb bsg: support for ... |
426 |
idefloppy_blockpc_cmd(floppy, pc, rq); |
1da177e4c Linux-2.6.12-rc2 |
427 428 429 |
} else { blk_dump_rq_flags(rq, "ide-floppy: unsupported command in queue"); |
c2b2b2936 ide-floppy: renam... |
430 |
idefloppy_end_request(drive, 0, 0); |
1da177e4c Linux-2.6.12-rc2 |
431 432 |
return ide_stopped; } |
b98b3409a ide-floppy: use s... |
433 434 435 436 437 |
ide_init_sg_cmd(drive, rq); ide_map_sg(drive, rq); pc->sg = hwif->sg_table; pc->sg_cnt = hwif->sg_nents; |
1da177e4c Linux-2.6.12-rc2 |
438 |
pc->rq = rq; |
5d41893c0 ide: add PC_FLAG_... |
439 |
|
1da177e4c Linux-2.6.12-rc2 |
440 441 442 443 |
return idefloppy_issue_pc(drive, pc); } /* |
8e81bbba7 ide-floppy: remov... |
444 445 |
* Look at the flexible disk page parameters. We ignore the CHS capacity * parameters and use the LBA parameters instead. |
1da177e4c Linux-2.6.12-rc2 |
446 |
*/ |
8e81bbba7 ide-floppy: remov... |
447 |
static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
448 449 |
{ idefloppy_floppy_t *floppy = drive->driver_data; |
2ac07d920 ide: add ide_queu... |
450 |
struct gendisk *disk = floppy->disk; |
8e5551239 ide-floppy: conve... |
451 |
struct ide_atapi_pc pc; |
8e81bbba7 ide-floppy: remov... |
452 |
u8 *page; |
1da177e4c Linux-2.6.12-rc2 |
453 |
int capacity, lba_capacity; |
8e81bbba7 ide-floppy: remov... |
454 455 |
u16 transfer_rate, sector_size, cyls, rpm; u8 heads, sectors; |
1da177e4c Linux-2.6.12-rc2 |
456 |
|
0127854d7 ide-floppy: move ... |
457 |
ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); |
8e81bbba7 ide-floppy: remov... |
458 |
|
2ac07d920 ide: add ide_queu... |
459 |
if (ide_queue_pc_tail(drive, disk, &pc)) { |
8e81bbba7 ide-floppy: remov... |
460 461 462 |
printk(KERN_ERR "ide-floppy: Can't get flexible disk page" " parameters "); |
1da177e4c Linux-2.6.12-rc2 |
463 464 |
return 1; } |
49cac39e7 ide-floppy: ->{sr... |
465 466 467 468 469 470 471 |
if (pc.buf[3] & 0x80) drive->atapi_flags |= IDE_AFLAG_WP; else drive->atapi_flags &= ~IDE_AFLAG_WP; set_disk_ro(disk, !!(drive->atapi_flags & IDE_AFLAG_WP)); |
8e5551239 ide-floppy: conve... |
472 |
page = &pc.buf[8]; |
8e81bbba7 ide-floppy: remov... |
473 |
|
85ae98a3d ide: endian annot... |
474 475 476 477 |
transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]); sector_size = be16_to_cpup((__be16 *)&pc.buf[8 + 6]); cyls = be16_to_cpup((__be16 *)&pc.buf[8 + 8]); rpm = be16_to_cpup((__be16 *)&pc.buf[8 + 28]); |
8e5551239 ide-floppy: conve... |
478 479 |
heads = pc.buf[8 + 4]; sectors = pc.buf[8 + 5]; |
8e81bbba7 ide-floppy: remov... |
480 481 482 483 |
capacity = cyls * heads * sectors * sector_size; if (memcmp(page, &floppy->flexible_disk_page, 32)) |
1da177e4c Linux-2.6.12-rc2 |
484 485 486 |
printk(KERN_INFO "%s: %dkB, %d/%d/%d CHS, %d kBps, " "%d sector size, %d rpm ", |
8e81bbba7 ide-floppy: remov... |
487 488 489 490 491 492 493 |
drive->name, capacity / 1024, cyls, heads, sectors, transfer_rate / 8, sector_size, rpm); memcpy(&floppy->flexible_disk_page, page, 32); drive->bios_cyl = cyls; drive->bios_head = heads; drive->bios_sect = sectors; |
1da177e4c Linux-2.6.12-rc2 |
494 |
lba_capacity = floppy->blocks * floppy->block_size; |
8e81bbba7 ide-floppy: remov... |
495 |
|
1da177e4c Linux-2.6.12-rc2 |
496 497 498 499 500 |
if (capacity < lba_capacity) { printk(KERN_NOTICE "%s: The disk reports a capacity of %d " "bytes, but the drive only handles %d ", drive->name, lba_capacity, capacity); |
8e81bbba7 ide-floppy: remov... |
501 502 |
floppy->blocks = floppy->block_size ? capacity / floppy->block_size : 0; |
1da177e4c Linux-2.6.12-rc2 |
503 504 505 |
} return 0; } |
1da177e4c Linux-2.6.12-rc2 |
506 |
/* |
194ec0c07 ide-floppy: remov... |
507 508 |
* Determine if a media is present in the floppy drive, and if so, its LBA * capacity. |
1da177e4c Linux-2.6.12-rc2 |
509 |
*/ |
194ec0c07 ide-floppy: remov... |
510 |
static int ide_floppy_get_capacity(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
511 512 |
{ idefloppy_floppy_t *floppy = drive->driver_data; |
2ac07d920 ide: add ide_queu... |
513 |
struct gendisk *disk = floppy->disk; |
8e5551239 ide-floppy: conve... |
514 |
struct ide_atapi_pc pc; |
194ec0c07 ide-floppy: remov... |
515 516 517 |
u8 *cap_desc; u8 header_len, desc_cnt; int i, rc = 1, blocks, length; |
1da177e4c Linux-2.6.12-rc2 |
518 519 |
drive->bios_cyl = 0; drive->bios_head = drive->bios_sect = 0; |
fdb77da4c ide-floppy: Fix u... |
520 521 |
floppy->blocks = 0; floppy->bs_factor = 1; |
1da177e4c Linux-2.6.12-rc2 |
522 |
set_capacity(floppy->disk, 0); |
0127854d7 ide-floppy: move ... |
523 |
ide_floppy_create_read_capacity_cmd(&pc); |
2ac07d920 ide: add ide_queu... |
524 |
if (ide_queue_pc_tail(drive, disk, &pc)) { |
1da177e4c Linux-2.6.12-rc2 |
525 526 527 528 |
printk(KERN_ERR "ide-floppy: Can't get floppy parameters "); return 1; } |
8e5551239 ide-floppy: conve... |
529 530 |
header_len = pc.buf[3]; cap_desc = &pc.buf[4]; |
194ec0c07 ide-floppy: remov... |
531 532 533 534 |
desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ for (i = 0; i < desc_cnt; i++) { unsigned int desc_start = 4 + i*8; |
85ae98a3d ide: endian annot... |
535 536 |
blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); |
194ec0c07 ide-floppy: remov... |
537 538 539 540 |
debug_log("Descriptor %d: %dkB, %d blocks, %d sector size ", i, blocks * length / 1024, blocks, length); |
1da177e4c Linux-2.6.12-rc2 |
541 |
|
194ec0c07 ide-floppy: remov... |
542 543 544 545 546 |
if (i) continue; /* * the code below is valid only for the 1st descriptor, ie i=0 */ |
1da177e4c Linux-2.6.12-rc2 |
547 |
|
8e5551239 ide-floppy: conve... |
548 |
switch (pc.buf[desc_start + 4] & 0x03) { |
1da177e4c Linux-2.6.12-rc2 |
549 550 |
/* Clik! drive returns this instead of CAPACITY_CURRENT */ case CAPACITY_UNFORMATTED: |
ea68d270f ide-floppy: conve... |
551 |
if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
0571c7a4f ide-floppy: fix m... |
552 |
/* |
1da177e4c Linux-2.6.12-rc2 |
553 554 555 556 557 558 |
* If it is not a clik drive, break out * (maintains previous driver behaviour) */ break; case CAPACITY_CURRENT: /* Normal Zip/LS-120 disks */ |
194ec0c07 ide-floppy: remov... |
559 |
if (memcmp(cap_desc, &floppy->cap_desc, 8)) |
1da177e4c Linux-2.6.12-rc2 |
560 561 562 563 |
printk(KERN_INFO "%s: %dkB, %d blocks, %d " "sector size ", drive->name, blocks * length / 1024, blocks, length); |
194ec0c07 ide-floppy: remov... |
564 |
memcpy(&floppy->cap_desc, cap_desc, 8); |
1da177e4c Linux-2.6.12-rc2 |
565 566 567 568 569 |
if (!length || length % 512) { printk(KERN_NOTICE "%s: %d bytes block size " "not supported ", drive->name, length); } else { |
194ec0c07 ide-floppy: remov... |
570 571 572 573 574 |
floppy->blocks = blocks; floppy->block_size = length; floppy->bs_factor = length / 512; if (floppy->bs_factor != 1) printk(KERN_NOTICE "%s: warning: non " |
1da177e4c Linux-2.6.12-rc2 |
575 576 577 578 |
"512 bytes block size not " "fully supported ", drive->name); |
194ec0c07 ide-floppy: remov... |
579 |
rc = 0; |
1da177e4c Linux-2.6.12-rc2 |
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 |
} break; case CAPACITY_NO_CARTRIDGE: /* * This is a KERN_ERR so it appears on screen * for the user to see */ printk(KERN_ERR "%s: No disk in drive ", drive->name); break; case CAPACITY_INVALID: printk(KERN_ERR "%s: Invalid capacity for disk " "in drive ", drive->name); break; } |
194ec0c07 ide-floppy: remov... |
596 597 |
debug_log("Descriptor 0 Code: %d ", |
8e5551239 ide-floppy: conve... |
598 |
pc.buf[desc_start + 4] & 0x03); |
1da177e4c Linux-2.6.12-rc2 |
599 600 601 |
} /* Clik! disk does not support get_flexible_disk_page */ |
ea68d270f ide-floppy: conve... |
602 |
if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
8e81bbba7 ide-floppy: remov... |
603 |
(void) ide_floppy_get_flexible_disk_page(drive); |
1da177e4c Linux-2.6.12-rc2 |
604 |
|
2ac07d920 ide: add ide_queu... |
605 |
set_capacity(disk, floppy->blocks * floppy->bs_factor); |
1da177e4c Linux-2.6.12-rc2 |
606 607 |
return rc; } |
0571c7a4f ide-floppy: fix m... |
608 |
static sector_t idefloppy_capacity(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
609 610 611 612 613 614 |
{ idefloppy_floppy_t *floppy = drive->driver_data; unsigned long capacity = floppy->blocks * floppy->bs_factor; return capacity; } |
7662d046d ide: move IDE set... |
615 |
#ifdef CONFIG_IDE_PROC_FS |
8185d5aa9 ide: /proc/ide/hd... |
616 617 618 619 620 |
ide_devset_rw(bios_cyl, 0, 1023, bios_cyl); ide_devset_rw(bios_head, 0, 255, bios_head); ide_devset_rw(bios_sect, 0, 63, bios_sect); static int get_ticks(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
621 622 |
{ idefloppy_floppy_t *floppy = drive->driver_data; |
8185d5aa9 ide: /proc/ide/hd... |
623 624 |
return floppy->ticks; } |
1da177e4c Linux-2.6.12-rc2 |
625 |
|
8185d5aa9 ide: /proc/ide/hd... |
626 627 628 629 630 |
static int set_ticks(ide_drive_t *drive, int arg) { idefloppy_floppy_t *floppy = drive->driver_data; floppy->ticks = arg; return 0; |
1da177e4c Linux-2.6.12-rc2 |
631 |
} |
8185d5aa9 ide: /proc/ide/hd... |
632 633 634 635 636 637 638 639 640 641 |
IDE_DEVSET(ticks, S_RW, 0, 255, get_ticks, set_ticks); static const struct ide_devset *idefloppy_settings[] = { &ide_devset_bios_cyl, &ide_devset_bios_head, &ide_devset_bios_sect, &ide_devset_ticks, NULL }; |
7662d046d ide: move IDE set... |
642 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
643 |
|
0571c7a4f ide-floppy: fix m... |
644 |
static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) |
1da177e4c Linux-2.6.12-rc2 |
645 |
{ |
4dde4492d ide: make drive->... |
646 |
u16 *id = drive->id; |
3ad6776cc ide-floppy: remov... |
647 |
u8 gcw[2]; |
1da177e4c Linux-2.6.12-rc2 |
648 |
|
4dde4492d ide: make drive->... |
649 |
*((u16 *)&gcw) = id[ATA_ID_CONFIG]; |
2e8a6f89d ide-{floppy,tape}... |
650 |
|
2207fa5af ide-floppy: use d... |
651 |
drive->pc_callback = ide_floppy_callback; |
3ad6776cc ide-floppy: remov... |
652 653 |
if (((gcw[0] & 0x60) >> 5) == 1) |
ea68d270f ide-floppy: conve... |
654 |
drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; |
1da177e4c Linux-2.6.12-rc2 |
655 |
/* |
0571c7a4f ide-floppy: fix m... |
656 657 |
* We used to check revisions here. At this point however I'm giving up. * Just assume they are all broken, its easier. |
1da177e4c Linux-2.6.12-rc2 |
658 |
* |
0571c7a4f ide-floppy: fix m... |
659 660 661 662 |
* The actual reason for the workarounds was likely a driver bug after * all rather than a firmware bug, and the workaround below used to hide * it. It should be fixed as of version 1.9, but to be on the safe side * we'll leave the limitation below for the 2.2.x tree. |
1da177e4c Linux-2.6.12-rc2 |
663 |
*/ |
4dde4492d ide: make drive->... |
664 |
if (!strncmp((char *)&id[ATA_ID_PROD], "IOMEGA ZIP 100 ATAPI", 20)) { |
ea68d270f ide-floppy: conve... |
665 |
drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE; |
1da177e4c Linux-2.6.12-rc2 |
666 667 668 669 670 671 |
/* This value will be visible in the /proc/ide/hdx/settings */ floppy->ticks = IDEFLOPPY_TICKS_DELAY; blk_queue_max_sectors(drive->queue, 64); } /* |
0571c7a4f ide-floppy: fix m... |
672 673 674 |
* Guess what? The IOMEGA Clik! drive also needs the above fix. It makes * nasty clicking noises without it, so please don't remove this. */ |
4dde4492d ide: make drive->... |
675 |
if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) { |
1da177e4c Linux-2.6.12-rc2 |
676 |
blk_queue_max_sectors(drive->queue, 64); |
ea68d270f ide-floppy: conve... |
677 |
drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; |
0578042db ide: add ide_set_... |
678 679 |
/* IOMEGA Clik! drives do not support lock/unlock commands */ drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; |
1da177e4c Linux-2.6.12-rc2 |
680 |
} |
194ec0c07 ide-floppy: remov... |
681 |
(void) ide_floppy_get_capacity(drive); |
1e874f448 ide: call ide_pro... |
682 683 |
ide_proc_register_driver(drive, floppy->driver); |
1da177e4c Linux-2.6.12-rc2 |
684 |
} |
4031bbe4b [PATCH] Add ide_b... |
685 |
static void ide_floppy_remove(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
686 687 688 |
{ idefloppy_floppy_t *floppy = drive->driver_data; struct gendisk *g = floppy->disk; |
7662d046d ide: move IDE set... |
689 |
ide_proc_unregister_driver(drive, floppy->driver); |
1da177e4c Linux-2.6.12-rc2 |
690 691 692 693 |
del_gendisk(g); ide_floppy_put(floppy); |
1da177e4c Linux-2.6.12-rc2 |
694 |
} |
9a24b63db ide-floppy: disam... |
695 |
static void idefloppy_cleanup_obj(struct kref *kref) |
1da177e4c Linux-2.6.12-rc2 |
696 697 698 699 700 701 702 703 704 705 |
{ struct ide_floppy_obj *floppy = to_ide_floppy(kref); ide_drive_t *drive = floppy->drive; struct gendisk *g = floppy->disk; drive->driver_data = NULL; g->private_data = NULL; put_disk(g); kfree(floppy); } |
ecfd80e4a ide: make /proc/i... |
706 |
#ifdef CONFIG_IDE_PROC_FS |
0571c7a4f ide-floppy: fix m... |
707 708 |
static int proc_idefloppy_read_capacity(char *page, char **start, off_t off, int count, int *eof, void *data) |
1da177e4c Linux-2.6.12-rc2 |
709 710 711 |
{ ide_drive_t*drive = (ide_drive_t *)data; int len; |
0571c7a4f ide-floppy: fix m... |
712 713 714 |
len = sprintf(page, "%llu ", (long long)idefloppy_capacity(drive)); PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
1da177e4c Linux-2.6.12-rc2 |
715 716 717 |
} static ide_proc_entry_t idefloppy_proc[] = { |
0571c7a4f ide-floppy: fix m... |
718 719 |
{ "capacity", S_IFREG|S_IRUGO, proc_idefloppy_read_capacity, NULL }, { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, |
1da177e4c Linux-2.6.12-rc2 |
720 721 |
{ NULL, 0, NULL, NULL } }; |
ecfd80e4a ide: make /proc/i... |
722 |
#endif /* CONFIG_IDE_PROC_FS */ |
1da177e4c Linux-2.6.12-rc2 |
723 |
|
4031bbe4b [PATCH] Add ide_b... |
724 |
static int ide_floppy_probe(ide_drive_t *); |
1da177e4c Linux-2.6.12-rc2 |
725 |
|
1da177e4c Linux-2.6.12-rc2 |
726 |
static ide_driver_t idefloppy_driver = { |
8604affde [PATCH] convert I... |
727 |
.gen_driver = { |
4ef3b8f4a [PATCH] ide: remo... |
728 |
.owner = THIS_MODULE, |
8604affde [PATCH] convert I... |
729 730 |
.name = "ide-floppy", .bus = &ide_bus_type, |
8604affde [PATCH] convert I... |
731 |
}, |
4031bbe4b [PATCH] Add ide_b... |
732 733 |
.probe = ide_floppy_probe, .remove = ide_floppy_remove, |
1da177e4c Linux-2.6.12-rc2 |
734 735 |
.version = IDEFLOPPY_VERSION, .media = ide_floppy, |
1da177e4c Linux-2.6.12-rc2 |
736 |
.do_request = idefloppy_do_request, |
c2b2b2936 ide-floppy: renam... |
737 |
.end_request = idefloppy_end_request, |
1da177e4c Linux-2.6.12-rc2 |
738 |
.error = __ide_error, |
7662d046d ide: move IDE set... |
739 |
#ifdef CONFIG_IDE_PROC_FS |
1da177e4c Linux-2.6.12-rc2 |
740 |
.proc = idefloppy_proc, |
8185d5aa9 ide: /proc/ide/hd... |
741 |
.settings = idefloppy_settings, |
7662d046d ide: move IDE set... |
742 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
743 744 745 746 747 748 749 |
}; static int idefloppy_open(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; struct ide_floppy_obj *floppy; ide_drive_t *drive; |
8e5551239 ide-floppy: conve... |
750 |
struct ide_atapi_pc pc; |
1da177e4c Linux-2.6.12-rc2 |
751 |
int ret = 0; |
bcc77d9cc ide-floppy: clean... |
752 753 |
debug_log("Reached %s ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
754 |
|
0571c7a4f ide-floppy: fix m... |
755 756 |
floppy = ide_floppy_get(disk); if (!floppy) |
1da177e4c Linux-2.6.12-rc2 |
757 758 759 |
return -ENXIO; drive = floppy->drive; |
c94964a45 ide: remove ide_d... |
760 |
floppy->openers++; |
1da177e4c Linux-2.6.12-rc2 |
761 |
|
c94964a45 ide: remove ide_d... |
762 |
if (floppy->openers == 1) { |
ea68d270f ide-floppy: conve... |
763 |
drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; |
1da177e4c Linux-2.6.12-rc2 |
764 |
/* Just in case */ |
7bf7420a3 ide: add ide_init... |
765 |
ide_init_pc(&pc); |
c96a7df8d ide-floppy: fold ... |
766 |
pc.c[0] = GPCMD_TEST_UNIT_READY; |
2ac07d920 ide: add ide_queu... |
767 |
if (ide_queue_pc_tail(drive, disk, &pc)) { |
1da177e4c Linux-2.6.12-rc2 |
768 |
idefloppy_create_start_stop_cmd(&pc, 1); |
2ac07d920 ide: add ide_queu... |
769 |
(void)ide_queue_pc_tail(drive, disk, &pc); |
1da177e4c Linux-2.6.12-rc2 |
770 |
} |
194ec0c07 ide-floppy: remov... |
771 |
if (ide_floppy_get_capacity(drive) |
1da177e4c Linux-2.6.12-rc2 |
772 773 |
&& (filp->f_flags & O_NDELAY) == 0 /* |
0571c7a4f ide-floppy: fix m... |
774 775 776 777 |
* Allow O_NDELAY to open a drive without a disk, or with an * unreadable disk, so that we can get the format capacity * of the drive or begin the format - Sam */ |
1da177e4c Linux-2.6.12-rc2 |
778 |
) { |
1da177e4c Linux-2.6.12-rc2 |
779 780 781 |
ret = -EIO; goto out_put_floppy; } |
49cac39e7 ide-floppy: ->{sr... |
782 |
if ((drive->atapi_flags & IDE_AFLAG_WP) && (filp->f_mode & 2)) { |
1da177e4c Linux-2.6.12-rc2 |
783 784 785 |
ret = -EROFS; goto out_put_floppy; } |
e996fc8ae ide-floppy: add i... |
786 |
|
ea68d270f ide-floppy: conve... |
787 |
drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED; |
0578042db ide: add ide_set_... |
788 |
ide_set_media_lock(drive, disk, 1); |
1da177e4c Linux-2.6.12-rc2 |
789 |
check_disk_change(inode->i_bdev); |
ea68d270f ide-floppy: conve... |
790 |
} else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) { |
1da177e4c Linux-2.6.12-rc2 |
791 792 793 794 795 796 |
ret = -EBUSY; goto out_put_floppy; } return 0; out_put_floppy: |
c94964a45 ide: remove ide_d... |
797 |
floppy->openers--; |
1da177e4c Linux-2.6.12-rc2 |
798 799 800 801 802 803 804 805 806 |
ide_floppy_put(floppy); return ret; } static int idefloppy_release(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; struct ide_floppy_obj *floppy = ide_floppy_g(disk); ide_drive_t *drive = floppy->drive; |
bcc77d9cc ide-floppy: clean... |
807 808 809 |
debug_log("Reached %s ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
810 |
|
c94964a45 ide: remove ide_d... |
811 |
if (floppy->openers == 1) { |
0578042db ide: add ide_set_... |
812 |
ide_set_media_lock(drive, disk, 0); |
ea68d270f ide-floppy: conve... |
813 |
drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; |
1da177e4c Linux-2.6.12-rc2 |
814 |
} |
c94964a45 ide: remove ide_d... |
815 816 |
floppy->openers--; |
1da177e4c Linux-2.6.12-rc2 |
817 818 819 820 821 |
ide_floppy_put(floppy); return 0; } |
a885c8c43 [PATCH] Add block... |
822 823 824 825 826 827 828 829 830 831 |
static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) { struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); ide_drive_t *drive = floppy->drive; geo->heads = drive->bios_head; geo->sectors = drive->bios_sect; geo->cylinders = (u16)drive->bios_cyl; /* truncate */ return 0; } |
ea68d270f ide-floppy: conve... |
832 833 |
static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, unsigned long arg, unsigned int cmd) |
20bf7bdad ide-floppy: facto... |
834 |
{ |
ea68d270f ide-floppy: conve... |
835 |
idefloppy_floppy_t *floppy = drive->driver_data; |
0578042db ide: add ide_set_... |
836 |
struct gendisk *disk = floppy->disk; |
e996fc8ae ide-floppy: add i... |
837 |
int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0; |
ea68d270f ide-floppy: conve... |
838 |
|
20bf7bdad ide-floppy: facto... |
839 840 |
if (floppy->openers > 1) return -EBUSY; |
0578042db ide: add ide_set_... |
841 |
ide_set_media_lock(drive, disk, prevent); |
20bf7bdad ide-floppy: facto... |
842 843 844 |
if (cmd == CDROMEJECT) { idefloppy_create_start_stop_cmd(pc, 2); |
0578042db ide: add ide_set_... |
845 |
(void)ide_queue_pc_tail(drive, disk, pc); |
20bf7bdad ide-floppy: facto... |
846 847 848 849 |
} return 0; } |
1da177e4c Linux-2.6.12-rc2 |
850 851 852 853 854 855 |
static int idefloppy_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct block_device *bdev = inode->i_bdev; struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); ide_drive_t *drive = floppy->drive; |
8e5551239 ide-floppy: conve... |
856 |
struct ide_atapi_pc pc; |
1da177e4c Linux-2.6.12-rc2 |
857 |
void __user *argp = (void __user *)arg; |
07203f647 [PATCH] ide-flopp... |
858 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
859 |
|
d56c99e26 ide-floppy: add i... |
860 |
if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) |
ea68d270f ide-floppy: conve... |
861 |
return ide_floppy_lockdoor(drive, &pc, arg, cmd); |
1da177e4c Linux-2.6.12-rc2 |
862 |
|
d56c99e26 ide-floppy: add i... |
863 864 865 |
err = ide_floppy_format_ioctl(drive, file, cmd, argp); if (err != -ENOTTY) return err; |
89636af25 ide: add support ... |
866 867 868 869 870 871 872 873 |
/* * skip SCSI_IOCTL_SEND_COMMAND (deprecated) * and CDROM_SEND_PACKET (legacy) ioctls */ if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND) err = scsi_cmd_ioctl(file, bdev->bd_disk->queue, bdev->bd_disk, cmd, argp); |
89636af25 ide: add support ... |
874 875 876 877 878 |
if (err == -ENOTTY) err = generic_ide_ioctl(drive, file, bdev, cmd, arg); return err; |
1da177e4c Linux-2.6.12-rc2 |
879 880 881 882 883 884 |
} static int idefloppy_media_changed(struct gendisk *disk) { struct ide_floppy_obj *floppy = ide_floppy_g(disk); ide_drive_t *drive = floppy->drive; |
6e5fa7b88 ide-floppy: remov... |
885 |
int ret; |
1da177e4c Linux-2.6.12-rc2 |
886 887 888 889 890 891 |
/* do not scan partitions twice if this is a removable device */ if (drive->attach) { drive->attach = 0; return 0; } |
ea68d270f ide-floppy: conve... |
892 893 |
ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED); drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED; |
6e5fa7b88 ide-floppy: remov... |
894 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
895 896 897 898 899 900 901 902 903 904 |
} static int idefloppy_revalidate_disk(struct gendisk *disk) { struct ide_floppy_obj *floppy = ide_floppy_g(disk); set_capacity(disk, idefloppy_capacity(floppy->drive)); return 0; } static struct block_device_operations idefloppy_ops = { |
52d3ccf76 IDE: Coding Style... |
905 906 907 908 909 910 911 |
.owner = THIS_MODULE, .open = idefloppy_open, .release = idefloppy_release, .ioctl = idefloppy_ioctl, .getgeo = idefloppy_getgeo, .media_changed = idefloppy_media_changed, .revalidate_disk = idefloppy_revalidate_disk |
1da177e4c Linux-2.6.12-rc2 |
912 |
}; |
4031bbe4b [PATCH] Add ide_b... |
913 |
static int ide_floppy_probe(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
914 915 916 917 918 919 |
{ idefloppy_floppy_t *floppy; struct gendisk *g; if (!strstr("ide-floppy", drive->driver_req)) goto failed; |
2a924662b ide: remove needl... |
920 |
|
1da177e4c Linux-2.6.12-rc2 |
921 922 |
if (drive->media != ide_floppy) goto failed; |
2a924662b ide: remove needl... |
923 |
|
51509eec3 ide: add ide_chec... |
924 |
if (!ide_check_atapi_device(drive, DRV_NAME)) { |
0571c7a4f ide-floppy: fix m... |
925 926 927 |
printk(KERN_ERR "ide-floppy: %s: not supported by this version" " of ide-floppy ", drive->name); |
1da177e4c Linux-2.6.12-rc2 |
928 929 |
goto failed; } |
0571c7a4f ide-floppy: fix m... |
930 931 932 933 934 |
floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); if (!floppy) { printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy" " structure ", drive->name); |
1da177e4c Linux-2.6.12-rc2 |
935 936 937 938 939 940 941 942 |
goto failed; } g = alloc_disk(1 << PARTN_BITS); if (!g) goto out_free_floppy; ide_init_disk(g, drive); |
1da177e4c Linux-2.6.12-rc2 |
943 944 945 946 947 948 949 950 951 |
kref_init(&floppy->kref); floppy->drive = drive; floppy->driver = &idefloppy_driver; floppy->disk = g; g->private_data = &floppy->driver; drive->driver_data = floppy; |
0571c7a4f ide-floppy: fix m... |
952 |
idefloppy_setup(drive, floppy); |
8604affde [PATCH] convert I... |
953 |
|
1da177e4c Linux-2.6.12-rc2 |
954 955 |
g->minors = 1 << PARTN_BITS; g->driverfs_dev = &drive->gendev; |
1da177e4c Linux-2.6.12-rc2 |
956 957 958 959 960 |
g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; g->fops = &idefloppy_ops; drive->attach = 1; add_disk(g); return 0; |
1da177e4c Linux-2.6.12-rc2 |
961 962 963 |
out_free_floppy: kfree(floppy); failed: |
8604affde [PATCH] convert I... |
964 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
965 |
} |
0571c7a4f ide-floppy: fix m... |
966 |
static void __exit idefloppy_exit(void) |
1da177e4c Linux-2.6.12-rc2 |
967 |
{ |
8604affde [PATCH] convert I... |
968 |
driver_unregister(&idefloppy_driver.gen_driver); |
1da177e4c Linux-2.6.12-rc2 |
969 |
} |
17514e8a6 [PATCH] ide: add ... |
970 |
static int __init idefloppy_init(void) |
1da177e4c Linux-2.6.12-rc2 |
971 972 973 |
{ printk("ide-floppy driver " IDEFLOPPY_VERSION " "); |
8604affde [PATCH] convert I... |
974 |
return driver_register(&idefloppy_driver.gen_driver); |
1da177e4c Linux-2.6.12-rc2 |
975 |
} |
263756ec2 [PATCH] ide: MODA... |
976 |
MODULE_ALIAS("ide:*m-floppy*"); |
0127854d7 ide-floppy: move ... |
977 |
MODULE_ALIAS("ide-floppy"); |
1da177e4c Linux-2.6.12-rc2 |
978 979 980 |
module_init(idefloppy_init); module_exit(idefloppy_exit); MODULE_LICENSE("GPL"); |
0571c7a4f ide-floppy: fix m... |
981 |
MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); |