Blame view
drivers/ide/ide-floppy.c
14.4 KB
1da177e4c
|
1 |
/* |
d3f208488
|
2 3 |
* IDE ATAPI floppy driver. * |
59bca8cc9
|
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
|
7 |
* |
1da177e4c
|
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
|
14 15 |
* For a historical changelog see * Documentation/ide/ChangeLog.ide-floppy.1996-2002 |
1da177e4c
|
16 |
*/ |
1da177e4c
|
17 18 19 20 21 22 23 24 25 26 |
#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> |
1da177e4c
|
27 28 |
#include <linux/cdrom.h> #include <linux/ide.h> |
3ceca727f
|
29 |
#include <linux/hdreg.h> |
1da177e4c
|
30 |
#include <linux/bitops.h> |
cf8b8975c
|
31 |
#include <linux/mutex.h> |
b98b3409a
|
32 |
#include <linux/scatterlist.h> |
1da177e4c
|
33 |
|
89636af25
|
34 |
#include <scsi/scsi_ioctl.h> |
1da177e4c
|
35 |
#include <asm/byteorder.h> |
7e8b163b2
|
36 37 |
#include <linux/uaccess.h> #include <linux/io.h> |
1da177e4c
|
38 |
#include <asm/unaligned.h> |
0127854d7
|
39 |
#include "ide-floppy.h" |
1da177e4c
|
40 |
/* |
0571c7a4f
|
41 42 |
* After each failed packet command we issue a request sense command and retry * the packet command IDEFLOPPY_MAX_PC_RETRIES times. |
1da177e4c
|
43 44 |
*/ #define IDEFLOPPY_MAX_PC_RETRIES 3 |
194ec0c07
|
45 |
/* format capacities descriptor codes */ |
1da177e4c
|
46 47 48 49 |
#define CAPACITY_INVALID 0x00 #define CAPACITY_UNFORMATTED 0x01 #define CAPACITY_CURRENT 0x02 #define CAPACITY_NO_CARTRIDGE 0x03 |
baf08f0be
|
50 51 52 53 54 |
/* * The following delay solves a problem with ATAPI Zip 100 drive where BSY bit * was apparently being deasserted before the unit was ready to receive data. */ #define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */ |
1da177e4c
|
55 |
|
03a2faaea
|
56 |
static int ide_floppy_callback(ide_drive_t *drive, int dsc) |
1da177e4c
|
57 |
{ |
0df962777
|
58 |
struct ide_disk_obj *floppy = drive->driver_data; |
2b9efba48
|
59 |
struct ide_atapi_pc *pc = drive->pc; |
313afea7f
|
60 |
struct request *rq = pc->rq; |
81f493823
|
61 |
int uptodate = pc->error ? 0 : 1; |
1da177e4c
|
62 |
|
088b1b886
|
63 |
ide_debug_log(IDE_DBG_FUNC, "enter"); |
bcc77d9cc
|
64 |
|
5e2040fd0
|
65 66 |
if (drive->failed_pc == pc) drive->failed_pc = NULL; |
dd2e9a032
|
67 |
|
81f493823
|
68 |
if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || |
f17bfe79e
|
69 |
rq->cmd_type == REQ_TYPE_BLOCK_PC) |
81f493823
|
70 71 |
uptodate = 1; /* FIXME */ else if (pc->c[0] == GPCMD_REQUEST_SENSE) { |
ae3a8387b
|
72 73 |
u8 *buf = bio_data(rq->bio); |
a6ff2d3b0
|
74 |
|
81f493823
|
75 76 77 78 79 80 |
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
|
81 |
|
5e2040fd0
|
82 |
if (drive->failed_pc) |
088b1b886
|
83 |
ide_debug_log(IDE_DBG_PC, "pc = %x", |
5e2040fd0
|
84 |
drive->failed_pc->c[0]); |
bcc77d9cc
|
85 |
|
7b3557262
|
86 |
ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x," |
088b1b886
|
87 |
"ascq = %x", floppy->sense_key, |
7b3557262
|
88 |
floppy->asc, floppy->ascq); |
81f493823
|
89 |
} else |
7b3557262
|
90 91 92 |
printk(KERN_ERR PFX "Error in REQUEST SENSE itself - " "Aborting request! "); |
81f493823
|
93 |
} |
1da177e4c
|
94 |
|
33659ebba
|
95 |
if (rq->cmd_type == REQ_TYPE_SPECIAL) |
313afea7f
|
96 |
rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; |
03a2faaea
|
97 98 |
return uptodate; |
1da177e4c
|
99 |
} |
0df962777
|
100 |
static void ide_floppy_report_error(struct ide_disk_obj *floppy, |
8e5551239
|
101 |
struct ide_atapi_pc *pc) |
1da177e4c
|
102 |
{ |
25985edce
|
103 |
/* suppress error messages resulting from Medium not present */ |
1da177e4c
|
104 105 106 |
if (floppy->sense_key == 0x02 && floppy->asc == 0x3a && floppy->ascq == 0x00) |
d652c1380
|
107 |
return; |
7b3557262
|
108 |
printk(KERN_ERR PFX "%s: I/O error, pc = %2x, key = %2x, " |
d652c1380
|
109 110 111 112 |
"asc = %2x, ascq = %2x ", floppy->drive->name, pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq); |
1da177e4c
|
113 |
} |
b788ee9c6
|
114 115 116 |
static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd, struct ide_atapi_pc *pc) |
1da177e4c
|
117 |
{ |
0df962777
|
118 |
struct ide_disk_obj *floppy = drive->driver_data; |
1da177e4c
|
119 |
|
5e2040fd0
|
120 |
if (drive->failed_pc == NULL && |
30d670993
|
121 |
pc->c[0] != GPCMD_REQUEST_SENSE) |
5e2040fd0
|
122 |
drive->failed_pc = pc; |
2b9efba48
|
123 |
|
1da177e4c
|
124 |
/* Set the current packet command */ |
2b9efba48
|
125 |
drive->pc = pc; |
1da177e4c
|
126 |
|
757ced898
|
127 |
if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { |
eb6a61bb9
|
128 |
unsigned int done = blk_rq_bytes(drive->hwif->rq); |
6e5fa7b88
|
129 |
if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) |
757ced898
|
130 |
ide_floppy_report_error(floppy, pc); |
eb6a61bb9
|
131 |
|
757ced898
|
132 |
/* Giving up */ |
c152cc1a9
|
133 |
pc->error = IDE_DRV_ERROR_GENERAL; |
757ced898
|
134 |
|
5e2040fd0
|
135 |
drive->failed_pc = NULL; |
b14c72127
|
136 |
drive->pc_callback(drive, 0); |
eb6a61bb9
|
137 |
ide_complete_rq(drive, -EIO, done); |
1da177e4c
|
138 139 |
return ide_stopped; } |
088b1b886
|
140 |
ide_debug_log(IDE_DBG_FUNC, "retry #%d", pc->retries); |
1da177e4c
|
141 142 |
pc->retries++; |
1da177e4c
|
143 |
|
b788ee9c6
|
144 |
return ide_issue_pc(drive, cmd); |
1da177e4c
|
145 |
} |
0127854d7
|
146 |
void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) |
1da177e4c
|
147 |
{ |
7bf7420a3
|
148 |
ide_init_pc(pc); |
30d670993
|
149 |
pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES; |
1da177e4c
|
150 151 |
pc->c[7] = 255; pc->c[8] = 255; |
8e5551239
|
152 |
pc->req_xfer = 255; |
1da177e4c
|
153 |
} |
0571c7a4f
|
154 |
/* A mode sense command is used to "sense" floppy parameters. */ |
0127854d7
|
155 |
void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) |
1da177e4c
|
156 |
{ |
24a5d7033
|
157 |
u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */ |
0571c7a4f
|
158 |
|
7bf7420a3
|
159 |
ide_init_pc(pc); |
30d670993
|
160 |
pc->c[0] = GPCMD_MODE_SENSE_10; |
1da177e4c
|
161 |
pc->c[1] = 0; |
4de4b9e14
|
162 |
pc->c[2] = page_code; |
1da177e4c
|
163 164 |
switch (page_code) { |
0571c7a4f
|
165 166 167 168 169 170 171 |
case IDEFLOPPY_CAPABILITIES_PAGE: length += 12; break; case IDEFLOPPY_FLEXIBLE_DISK_PAGE: length += 32; break; default: |
7b3557262
|
172 173 |
printk(KERN_ERR PFX "unsupported page code in %s ", __func__); |
1da177e4c
|
174 |
} |
8f6224308
|
175 |
put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]); |
8e5551239
|
176 |
pc->req_xfer = length; |
1da177e4c
|
177 |
} |
7b3557262
|
178 |
static void idefloppy_create_rw_cmd(ide_drive_t *drive, |
8e5551239
|
179 |
struct ide_atapi_pc *pc, struct request *rq, |
ae7e8ddc3
|
180 |
unsigned long sector) |
1da177e4c
|
181 |
{ |
0df962777
|
182 |
struct ide_disk_obj *floppy = drive->driver_data; |
1da177e4c
|
183 |
int block = sector / floppy->bs_factor; |
9780e2dd8
|
184 |
int blocks = blk_rq_sectors(rq) / floppy->bs_factor; |
1da177e4c
|
185 |
int cmd = rq_data_dir(rq); |
088b1b886
|
186 |
ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks); |
1da177e4c
|
187 |
|
7bf7420a3
|
188 |
ide_init_pc(pc); |
ae7e8ddc3
|
189 190 |
pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); |
8f6224308
|
191 |
put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); |
ae7e8ddc3
|
192 |
|
20cd93be6
|
193 |
memcpy(rq->cmd, pc->c, 12); |
1da177e4c
|
194 |
pc->rq = rq; |
7b6d91dae
|
195 |
if (rq->cmd_flags & REQ_WRITE) |
6e5fa7b88
|
196 |
pc->flags |= PC_FLAG_WRITING; |
19f52a784
|
197 |
|
5e3310958
|
198 |
pc->flags |= PC_FLAG_DMA_OK; |
1da177e4c
|
199 |
} |
0df962777
|
200 |
static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, |
8e5551239
|
201 |
struct ide_atapi_pc *pc, struct request *rq) |
1da177e4c
|
202 |
{ |
7bf7420a3
|
203 |
ide_init_pc(pc); |
1da177e4c
|
204 |
memcpy(pc->c, rq->cmd, sizeof(pc->c)); |
3d6392cfb
|
205 |
pc->rq = rq; |
34b7d2c95
|
206 |
if (blk_rq_bytes(rq)) { |
5e3310958
|
207 |
pc->flags |= PC_FLAG_DMA_OK; |
8968932e5
|
208 209 210 |
if (rq_data_dir(rq) == WRITE) pc->flags |= PC_FLAG_WRITING; } |
1da177e4c
|
211 |
} |
806f80a6f
|
212 213 |
static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, struct request *rq, sector_t block) |
1da177e4c
|
214 |
{ |
0df962777
|
215 |
struct ide_disk_obj *floppy = drive->driver_data; |
b788ee9c6
|
216 |
struct ide_cmd cmd; |
8e5551239
|
217 |
struct ide_atapi_pc *pc; |
1da177e4c
|
218 |
|
349d12a1f
|
219 220 |
ide_debug_log(IDE_DBG_FUNC, "enter, cmd: 0x%x ", rq->cmd[0]); |
088b1b886
|
221 222 223 224 |
if (drive->debug_mask & IDE_DBG_RQ) blk_dump_rq_flags(rq, (rq->rq_disk ? rq->rq_disk->disk_name : "dev?")); |
1da177e4c
|
225 226 |
if (rq->errors >= ERROR_MAX) { |
313afea7f
|
227 |
if (drive->failed_pc) { |
5e2040fd0
|
228 |
ide_floppy_report_error(floppy, drive->failed_pc); |
313afea7f
|
229 230 |
drive->failed_pc = NULL; } else |
7b3557262
|
231 232 |
printk(KERN_ERR PFX "%s: I/O error ", drive->name); |
33659ebba
|
233 |
if (rq->cmd_type == REQ_TYPE_SPECIAL) { |
6902a5331
|
234 |
rq->errors = 0; |
f974b196f
|
235 |
ide_complete_rq(drive, 0, blk_rq_bytes(rq)); |
313afea7f
|
236 237 238 |
return ide_stopped; } else goto out_end; |
1da177e4c
|
239 |
} |
33659ebba
|
240 241 242 |
switch (rq->cmd_type) { case REQ_TYPE_FS: |
9780e2dd8
|
243 244 |
if (((long)blk_rq_pos(rq) % floppy->bs_factor) || (blk_rq_sectors(rq) % floppy->bs_factor)) { |
7b3557262
|
245 246 247 |
printk(KERN_ERR PFX "%s: unsupported r/w rq size ", drive->name); |
313afea7f
|
248 |
goto out_end; |
1da177e4c
|
249 |
} |
2e8a6f89d
|
250 |
pc = &floppy->queued_pc; |
806f80a6f
|
251 |
idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); |
33659ebba
|
252 253 254 |
break; case REQ_TYPE_SPECIAL: case REQ_TYPE_SENSE: |
ac0b0113d
|
255 |
pc = (struct ide_atapi_pc *)rq->special; |
33659ebba
|
256 257 |
break; case REQ_TYPE_BLOCK_PC: |
2e8a6f89d
|
258 |
pc = &floppy->queued_pc; |
3d6392cfb
|
259 |
idefloppy_blockpc_cmd(floppy, pc, rq); |
33659ebba
|
260 261 |
break; default: |
2c7eaa43c
|
262 |
BUG(); |
33659ebba
|
263 |
} |
1da177e4c
|
264 |
|
068753203
|
265 |
ide_prep_sense(drive, rq); |
b788ee9c6
|
266 |
memset(&cmd, 0, sizeof(cmd)); |
229816941
|
267 |
if (rq_data_dir(rq)) |
b788ee9c6
|
268 269 270 |
cmd.tf_flags |= IDE_TFLAG_WRITE; cmd.rq = rq; |
229816941
|
271 |
|
33659ebba
|
272 |
if (rq->cmd_type == REQ_TYPE_FS || blk_rq_bytes(rq)) { |
dfb7e621f
|
273 |
ide_init_sg_cmd(&cmd, blk_rq_bytes(rq)); |
b788ee9c6
|
274 |
ide_map_sg(drive, &cmd); |
3eb76c1cc
|
275 |
} |
b98b3409a
|
276 |
|
1da177e4c
|
277 |
pc->rq = rq; |
5d41893c0
|
278 |
|
b788ee9c6
|
279 |
return ide_floppy_issue_pc(drive, &cmd, pc); |
313afea7f
|
280 281 |
out_end: drive->failed_pc = NULL; |
33659ebba
|
282 |
if (rq->cmd_type != REQ_TYPE_FS && rq->errors == 0) |
89f78b326
|
283 |
rq->errors = -EIO; |
5e955245d
|
284 |
ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); |
313afea7f
|
285 |
return ide_stopped; |
1da177e4c
|
286 287 288 |
} /* |
8e81bbba7
|
289 290 |
* Look at the flexible disk page parameters. We ignore the CHS capacity * parameters and use the LBA parameters instead. |
1da177e4c
|
291 |
*/ |
07bd3f473
|
292 293 |
static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive, struct ide_atapi_pc *pc) |
1da177e4c
|
294 |
{ |
0df962777
|
295 |
struct ide_disk_obj *floppy = drive->driver_data; |
2ac07d920
|
296 |
struct gendisk *disk = floppy->disk; |
d9a683076
|
297 |
u8 *page, buf[40]; |
1da177e4c
|
298 |
int capacity, lba_capacity; |
8e81bbba7
|
299 300 |
u16 transfer_rate, sector_size, cyls, rpm; u8 heads, sectors; |
1da177e4c
|
301 |
|
07bd3f473
|
302 |
ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); |
8e81bbba7
|
303 |
|
d9a683076
|
304 |
if (ide_queue_pc_tail(drive, disk, pc, buf, pc->req_xfer)) { |
7b3557262
|
305 306 |
printk(KERN_ERR PFX "Can't get flexible disk page params "); |
1da177e4c
|
307 308 |
return 1; } |
49cac39e7
|
309 |
|
d9a683076
|
310 |
if (buf[3] & 0x80) |
da167876b
|
311 |
drive->dev_flags |= IDE_DFLAG_WP; |
49cac39e7
|
312 |
else |
da167876b
|
313 |
drive->dev_flags &= ~IDE_DFLAG_WP; |
49cac39e7
|
314 |
|
da167876b
|
315 |
set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); |
49cac39e7
|
316 |
|
d9a683076
|
317 |
page = &buf[8]; |
8e81bbba7
|
318 |
|
d9a683076
|
319 320 321 322 323 324 |
transfer_rate = be16_to_cpup((__be16 *)&buf[8 + 2]); sector_size = be16_to_cpup((__be16 *)&buf[8 + 6]); cyls = be16_to_cpup((__be16 *)&buf[8 + 8]); rpm = be16_to_cpup((__be16 *)&buf[8 + 28]); heads = buf[8 + 4]; sectors = buf[8 + 5]; |
8e81bbba7
|
325 326 327 328 |
capacity = cyls * heads * sectors * sector_size; if (memcmp(page, &floppy->flexible_disk_page, 32)) |
7b3557262
|
329 |
printk(KERN_INFO PFX "%s: %dkB, %d/%d/%d CHS, %d kBps, " |
1da177e4c
|
330 331 |
"%d sector size, %d rpm ", |
8e81bbba7
|
332 333 334 335 336 337 338 |
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
|
339 |
lba_capacity = floppy->blocks * floppy->block_size; |
8e81bbba7
|
340 |
|
1da177e4c
|
341 |
if (capacity < lba_capacity) { |
7b3557262
|
342 |
printk(KERN_NOTICE PFX "%s: The disk reports a capacity of %d " |
1da177e4c
|
343 344 345 |
"bytes, but the drive only handles %d ", drive->name, lba_capacity, capacity); |
8e81bbba7
|
346 347 |
floppy->blocks = floppy->block_size ? capacity / floppy->block_size : 0; |
6f84083bb
|
348 |
drive->capacity64 = floppy->blocks * floppy->bs_factor; |
1da177e4c
|
349 |
} |
6f84083bb
|
350 |
|
1da177e4c
|
351 352 |
return 0; } |
1da177e4c
|
353 |
/* |
194ec0c07
|
354 355 |
* Determine if a media is present in the floppy drive, and if so, its LBA * capacity. |
1da177e4c
|
356 |
*/ |
806f80a6f
|
357 |
static int ide_floppy_get_capacity(ide_drive_t *drive) |
1da177e4c
|
358 |
{ |
0df962777
|
359 |
struct ide_disk_obj *floppy = drive->driver_data; |
2ac07d920
|
360 |
struct gendisk *disk = floppy->disk; |
8e5551239
|
361 |
struct ide_atapi_pc pc; |
194ec0c07
|
362 |
u8 *cap_desc; |
41fa9f863
|
363 |
u8 pc_buf[256], header_len, desc_cnt; |
194ec0c07
|
364 |
int i, rc = 1, blocks, length; |
349d12a1f
|
365 |
ide_debug_log(IDE_DBG_FUNC, "enter"); |
1da177e4c
|
366 367 |
drive->bios_cyl = 0; drive->bios_head = drive->bios_sect = 0; |
fdb77da4c
|
368 369 |
floppy->blocks = 0; floppy->bs_factor = 1; |
6f84083bb
|
370 |
drive->capacity64 = 0; |
1da177e4c
|
371 |
|
0127854d7
|
372 |
ide_floppy_create_read_capacity_cmd(&pc); |
b13345f39
|
373 |
if (ide_queue_pc_tail(drive, disk, &pc, pc_buf, pc.req_xfer)) { |
7b3557262
|
374 375 |
printk(KERN_ERR PFX "Can't get floppy parameters "); |
1da177e4c
|
376 377 |
return 1; } |
b13345f39
|
378 379 |
header_len = pc_buf[3]; cap_desc = &pc_buf[4]; |
194ec0c07
|
380 381 382 383 |
desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ for (i = 0; i < desc_cnt; i++) { unsigned int desc_start = 4 + i*8; |
b13345f39
|
384 385 |
blocks = be32_to_cpup((__be32 *)&pc_buf[desc_start]); length = be16_to_cpup((__be16 *)&pc_buf[desc_start + 6]); |
194ec0c07
|
386 |
|
7b3557262
|
387 |
ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, " |
088b1b886
|
388 389 390 |
"%d sector size", i, blocks * length / 1024, blocks, length); |
1da177e4c
|
391 |
|
194ec0c07
|
392 393 394 395 396 |
if (i) continue; /* * the code below is valid only for the 1st descriptor, ie i=0 */ |
1da177e4c
|
397 |
|
b13345f39
|
398 |
switch (pc_buf[desc_start + 4] & 0x03) { |
1da177e4c
|
399 400 |
/* Clik! drive returns this instead of CAPACITY_CURRENT */ case CAPACITY_UNFORMATTED: |
ea68d270f
|
401 |
if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
0571c7a4f
|
402 |
/* |
1da177e4c
|
403 404 405 406 407 408 |
* If it is not a clik drive, break out * (maintains previous driver behaviour) */ break; case CAPACITY_CURRENT: /* Normal Zip/LS-120 disks */ |
194ec0c07
|
409 |
if (memcmp(cap_desc, &floppy->cap_desc, 8)) |
7b3557262
|
410 411 412 413 414 |
printk(KERN_INFO PFX "%s: %dkB, %d blocks, %d " "sector size ", drive->name, blocks * length / 1024, blocks, length); |
194ec0c07
|
415 |
memcpy(&floppy->cap_desc, cap_desc, 8); |
1da177e4c
|
416 |
if (!length || length % 512) { |
7b3557262
|
417 418 419 |
printk(KERN_NOTICE PFX "%s: %d bytes block size" " not supported ", drive->name, length); |
1da177e4c
|
420 |
} else { |
194ec0c07
|
421 422 423 424 |
floppy->blocks = blocks; floppy->block_size = length; floppy->bs_factor = length / 512; if (floppy->bs_factor != 1) |
7b3557262
|
425 426 427 428 429 |
printk(KERN_NOTICE PFX "%s: Warning: " "non 512 bytes block size not " "fully supported ", drive->name); |
6f84083bb
|
430 431 |
drive->capacity64 = floppy->blocks * floppy->bs_factor; |
194ec0c07
|
432 |
rc = 0; |
1da177e4c
|
433 434 435 436 437 438 439 |
} break; case CAPACITY_NO_CARTRIDGE: /* * This is a KERN_ERR so it appears on screen * for the user to see */ |
7b3557262
|
440 441 442 |
printk(KERN_ERR PFX "%s: No disk in drive ", drive->name); |
1da177e4c
|
443 444 |
break; case CAPACITY_INVALID: |
7b3557262
|
445 |
printk(KERN_ERR PFX "%s: Invalid capacity for disk " |
1da177e4c
|
446 447 448 449 |
"in drive ", drive->name); break; } |
088b1b886
|
450 |
ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d", |
b13345f39
|
451 |
pc_buf[desc_start + 4] & 0x03); |
1da177e4c
|
452 453 454 |
} /* Clik! disk does not support get_flexible_disk_page */ |
ea68d270f
|
455 |
if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
07bd3f473
|
456 |
(void) ide_floppy_get_flexible_disk_page(drive, &pc); |
1da177e4c
|
457 |
|
1da177e4c
|
458 459 |
return rc; } |
806f80a6f
|
460 |
static void ide_floppy_setup(ide_drive_t *drive) |
1da177e4c
|
461 |
{ |
806f80a6f
|
462 |
struct ide_disk_obj *floppy = drive->driver_data; |
4dde4492d
|
463 |
u16 *id = drive->id; |
2e8a6f89d
|
464 |
|
85e39035c
|
465 |
drive->pc_callback = ide_floppy_callback; |
3ad6776cc
|
466 |
|
1da177e4c
|
467 |
/* |
0571c7a4f
|
468 469 |
* We used to check revisions here. At this point however I'm giving up. * Just assume they are all broken, its easier. |
1da177e4c
|
470 |
* |
0571c7a4f
|
471 472 473 474 |
* 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
|
475 |
*/ |
4dde4492d
|
476 |
if (!strncmp((char *)&id[ATA_ID_PROD], "IOMEGA ZIP 100 ATAPI", 20)) { |
ea68d270f
|
477 |
drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE; |
1da177e4c
|
478 |
/* This value will be visible in the /proc/ide/hdx/settings */ |
baf08f0be
|
479 |
drive->pc_delay = IDEFLOPPY_PC_DELAY; |
086fa5ff0
|
480 |
blk_queue_max_hw_sectors(drive->queue, 64); |
1da177e4c
|
481 482 483 |
} /* |
0571c7a4f
|
484 485 486 |
* 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
|
487 |
if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) { |
086fa5ff0
|
488 |
blk_queue_max_hw_sectors(drive->queue, 64); |
ea68d270f
|
489 |
drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; |
0578042db
|
490 |
/* IOMEGA Clik! drives do not support lock/unlock commands */ |
42619d35c
|
491 |
drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
1da177e4c
|
492 |
} |
194ec0c07
|
493 |
(void) ide_floppy_get_capacity(drive); |
1e874f448
|
494 495 |
ide_proc_register_driver(drive, floppy->driver); |
ae9f9f073
|
496 497 |
drive->dev_flags |= IDE_DFLAG_ATTACH; |
1da177e4c
|
498 |
} |
806f80a6f
|
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
static void ide_floppy_flush(ide_drive_t *drive) { } static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk) { int ret = 0; if (ide_do_test_unit_ready(drive, disk)) ide_do_start_stop(drive, disk, 1); ret = ide_floppy_get_capacity(drive); set_capacity(disk, ide_gd_capacity(drive)); return ret; } const struct ide_disk_ops ide_atapi_disk_ops = { .check = ide_check_atapi_device, .get_capacity = ide_floppy_get_capacity, .setup = ide_floppy_setup, .flush = ide_floppy_flush, .init_media = ide_floppy_init_media, .set_doorlock = ide_set_media_lock, .do_request = ide_floppy_do_request, |
806f80a6f
|
526 527 |
.ioctl = ide_floppy_ioctl, }; |