diff options
Diffstat (limited to 'drivers/ide/ide-floppy.c')
-rw-r--r-- | drivers/ide/ide-floppy.c | 357 |
1 files changed, 46 insertions, 311 deletions
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index cf0aa25470ee..aeb1ad782f54 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -15,12 +15,6 @@ | |||
15 | * Documentation/ide/ChangeLog.ide-floppy.1996-2002 | 15 | * Documentation/ide/ChangeLog.ide-floppy.1996-2002 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #define DRV_NAME "ide-floppy" | ||
19 | #define PFX DRV_NAME ": " | ||
20 | |||
21 | #define IDEFLOPPY_VERSION "1.00" | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/types.h> | 18 | #include <linux/types.h> |
25 | #include <linux/string.h> | 19 | #include <linux/string.h> |
26 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
@@ -49,19 +43,6 @@ | |||
49 | 43 | ||
50 | #include "ide-floppy.h" | 44 | #include "ide-floppy.h" |
51 | 45 | ||
52 | /* module parameters */ | ||
53 | static unsigned long debug_mask; | ||
54 | module_param(debug_mask, ulong, 0644); | ||
55 | |||
56 | /* define to see debug info */ | ||
57 | #define IDEFLOPPY_DEBUG_LOG 0 | ||
58 | |||
59 | #if IDEFLOPPY_DEBUG_LOG | ||
60 | #define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) | ||
61 | #else | ||
62 | #define ide_debug_log(lvl, fmt, args...) do {} while (0) | ||
63 | #endif | ||
64 | |||
65 | /* | 46 | /* |
66 | * 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 |
67 | * the packet command IDEFLOPPY_MAX_PC_RETRIES times. | 48 | * the packet command IDEFLOPPY_MAX_PC_RETRIES times. |
@@ -83,43 +64,13 @@ module_param(debug_mask, ulong, 0644); | |||
83 | /* 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. */ |
84 | #define IDEFLOPPY_ERROR_GENERAL 101 | 65 | #define IDEFLOPPY_ERROR_GENERAL 101 |
85 | 66 | ||
86 | static DEFINE_MUTEX(idefloppy_ref_mutex); | ||
87 | |||
88 | static void idefloppy_cleanup_obj(struct kref *); | ||
89 | |||
90 | static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) | ||
91 | { | ||
92 | struct ide_floppy_obj *floppy = NULL; | ||
93 | |||
94 | mutex_lock(&idefloppy_ref_mutex); | ||
95 | floppy = ide_drv_g(disk, ide_floppy_obj); | ||
96 | if (floppy) { | ||
97 | if (ide_device_get(floppy->drive)) | ||
98 | floppy = NULL; | ||
99 | else | ||
100 | kref_get(&floppy->kref); | ||
101 | } | ||
102 | mutex_unlock(&idefloppy_ref_mutex); | ||
103 | return floppy; | ||
104 | } | ||
105 | |||
106 | static void ide_floppy_put(struct ide_floppy_obj *floppy) | ||
107 | { | ||
108 | ide_drive_t *drive = floppy->drive; | ||
109 | |||
110 | mutex_lock(&idefloppy_ref_mutex); | ||
111 | kref_put(&floppy->kref, idefloppy_cleanup_obj); | ||
112 | ide_device_put(drive); | ||
113 | mutex_unlock(&idefloppy_ref_mutex); | ||
114 | } | ||
115 | |||
116 | /* | 67 | /* |
117 | * 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 |
118 | * ide_end_request to pass to the next buffer. | 69 | * ide_end_request to pass to the next buffer. |
119 | */ | 70 | */ |
120 | 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) |
121 | { | 72 | { |
122 | idefloppy_floppy_t *floppy = drive->driver_data; | 73 | struct ide_disk_obj *floppy = drive->driver_data; |
123 | struct request *rq = HWGROUP(drive)->rq; | 74 | struct request *rq = HWGROUP(drive)->rq; |
124 | int error; | 75 | int error; |
125 | 76 | ||
@@ -161,12 +112,12 @@ static void idefloppy_update_buffers(ide_drive_t *drive, | |||
161 | struct bio *bio = rq->bio; | 112 | struct bio *bio = rq->bio; |
162 | 113 | ||
163 | while ((bio = rq->bio) != NULL) | 114 | while ((bio = rq->bio) != NULL) |
164 | idefloppy_end_request(drive, 1, 0); | 115 | ide_floppy_end_request(drive, 1, 0); |
165 | } | 116 | } |
166 | 117 | ||
167 | static void ide_floppy_callback(ide_drive_t *drive, int dsc) | 118 | static void ide_floppy_callback(ide_drive_t *drive, int dsc) |
168 | { | 119 | { |
169 | idefloppy_floppy_t *floppy = drive->driver_data; | 120 | struct ide_disk_obj *floppy = drive->driver_data; |
170 | struct ide_atapi_pc *pc = drive->pc; | 121 | struct ide_atapi_pc *pc = drive->pc; |
171 | int uptodate = pc->error ? 0 : 1; | 122 | int uptodate = pc->error ? 0 : 1; |
172 | 123 | ||
@@ -200,10 +151,10 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc) | |||
200 | "Aborting request!\n"); | 151 | "Aborting request!\n"); |
201 | } | 152 | } |
202 | 153 | ||
203 | idefloppy_end_request(drive, uptodate, 0); | 154 | ide_floppy_end_request(drive, uptodate, 0); |
204 | } | 155 | } |
205 | 156 | ||
206 | static void ide_floppy_report_error(idefloppy_floppy_t *floppy, | 157 | static void ide_floppy_report_error(struct ide_disk_obj *floppy, |
207 | struct ide_atapi_pc *pc) | 158 | struct ide_atapi_pc *pc) |
208 | { | 159 | { |
209 | /* supress error messages resulting from Medium not present */ | 160 | /* supress error messages resulting from Medium not present */ |
@@ -222,7 +173,7 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy, | |||
222 | static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, | 173 | static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, |
223 | struct ide_atapi_pc *pc) | 174 | struct ide_atapi_pc *pc) |
224 | { | 175 | { |
225 | idefloppy_floppy_t *floppy = drive->driver_data; | 176 | struct ide_disk_obj *floppy = drive->driver_data; |
226 | 177 | ||
227 | if (floppy->failed_pc == NULL && | 178 | if (floppy->failed_pc == NULL && |
228 | pc->c[0] != GPCMD_REQUEST_SENSE) | 179 | pc->c[0] != GPCMD_REQUEST_SENSE) |
@@ -286,7 +237,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, | |||
286 | struct ide_atapi_pc *pc, struct request *rq, | 237 | struct ide_atapi_pc *pc, struct request *rq, |
287 | unsigned long sector) | 238 | unsigned long sector) |
288 | { | 239 | { |
289 | idefloppy_floppy_t *floppy = drive->driver_data; | 240 | struct ide_disk_obj *floppy = drive->driver_data; |
290 | int block = sector / floppy->bs_factor; | 241 | int block = sector / floppy->bs_factor; |
291 | int blocks = rq->nr_sectors / floppy->bs_factor; | 242 | int blocks = rq->nr_sectors / floppy->bs_factor; |
292 | int cmd = rq_data_dir(rq); | 243 | int cmd = rq_data_dir(rq); |
@@ -310,7 +261,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, | |||
310 | pc->flags |= PC_FLAG_DMA_OK; | 261 | pc->flags |= PC_FLAG_DMA_OK; |
311 | } | 262 | } |
312 | 263 | ||
313 | static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, | 264 | static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, |
314 | struct ide_atapi_pc *pc, struct request *rq) | 265 | struct ide_atapi_pc *pc, struct request *rq) |
315 | { | 266 | { |
316 | ide_init_pc(pc); | 267 | ide_init_pc(pc); |
@@ -329,13 +280,12 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, | |||
329 | pc->req_xfer = pc->buf_size = rq->data_len; | 280 | pc->req_xfer = pc->buf_size = rq->data_len; |
330 | } | 281 | } |
331 | 282 | ||
332 | static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | 283 | static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, |
333 | struct request *rq, sector_t block_s) | 284 | struct request *rq, sector_t block) |
334 | { | 285 | { |
335 | idefloppy_floppy_t *floppy = drive->driver_data; | 286 | struct ide_disk_obj *floppy = drive->driver_data; |
336 | ide_hwif_t *hwif = drive->hwif; | 287 | ide_hwif_t *hwif = drive->hwif; |
337 | struct ide_atapi_pc *pc; | 288 | struct ide_atapi_pc *pc; |
338 | unsigned long block = (unsigned long)block_s; | ||
339 | 289 | ||
340 | ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " | 290 | ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " |
341 | "errors: %d\n", | 291 | "errors: %d\n", |
@@ -353,7 +303,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
353 | else | 303 | else |
354 | printk(KERN_ERR PFX "%s: I/O error\n", drive->name); | 304 | printk(KERN_ERR PFX "%s: I/O error\n", drive->name); |
355 | 305 | ||
356 | idefloppy_end_request(drive, 0, 0); | 306 | ide_floppy_end_request(drive, 0, 0); |
357 | return ide_stopped; | 307 | return ide_stopped; |
358 | } | 308 | } |
359 | if (blk_fs_request(rq)) { | 309 | if (blk_fs_request(rq)) { |
@@ -361,11 +311,11 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
361 | (rq->nr_sectors % floppy->bs_factor)) { | 311 | (rq->nr_sectors % floppy->bs_factor)) { |
362 | printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", | 312 | printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", |
363 | drive->name); | 313 | drive->name); |
364 | idefloppy_end_request(drive, 0, 0); | 314 | ide_floppy_end_request(drive, 0, 0); |
365 | return ide_stopped; | 315 | return ide_stopped; |
366 | } | 316 | } |
367 | pc = &floppy->queued_pc; | 317 | pc = &floppy->queued_pc; |
368 | idefloppy_create_rw_cmd(drive, pc, rq, block); | 318 | idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); |
369 | } else if (blk_special_request(rq)) { | 319 | } else if (blk_special_request(rq)) { |
370 | pc = (struct ide_atapi_pc *) rq->buffer; | 320 | pc = (struct ide_atapi_pc *) rq->buffer; |
371 | } else if (blk_pc_request(rq)) { | 321 | } else if (blk_pc_request(rq)) { |
@@ -373,7 +323,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
373 | idefloppy_blockpc_cmd(floppy, pc, rq); | 323 | idefloppy_blockpc_cmd(floppy, pc, rq); |
374 | } else { | 324 | } else { |
375 | blk_dump_rq_flags(rq, PFX "unsupported command in queue"); | 325 | blk_dump_rq_flags(rq, PFX "unsupported command in queue"); |
376 | idefloppy_end_request(drive, 0, 0); | 326 | ide_floppy_end_request(drive, 0, 0); |
377 | return ide_stopped; | 327 | return ide_stopped; |
378 | } | 328 | } |
379 | 329 | ||
@@ -394,7 +344,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
394 | */ | 344 | */ |
395 | 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) |
396 | { | 346 | { |
397 | idefloppy_floppy_t *floppy = drive->driver_data; | 347 | struct ide_disk_obj *floppy = drive->driver_data; |
398 | struct gendisk *disk = floppy->disk; | 348 | struct gendisk *disk = floppy->disk; |
399 | struct ide_atapi_pc pc; | 349 | struct ide_atapi_pc pc; |
400 | u8 *page; | 350 | u8 *page; |
@@ -410,11 +360,11 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | |||
410 | } | 360 | } |
411 | 361 | ||
412 | if (pc.buf[3] & 0x80) | 362 | if (pc.buf[3] & 0x80) |
413 | drive->atapi_flags |= IDE_AFLAG_WP; | 363 | drive->dev_flags |= IDE_DFLAG_WP; |
414 | else | 364 | else |
415 | drive->atapi_flags &= ~IDE_AFLAG_WP; | 365 | drive->dev_flags &= ~IDE_DFLAG_WP; |
416 | 366 | ||
417 | set_disk_ro(disk, !!(drive->atapi_flags & IDE_AFLAG_WP)); | 367 | set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); |
418 | 368 | ||
419 | page = &pc.buf[8]; | 369 | page = &pc.buf[8]; |
420 | 370 | ||
@@ -445,7 +395,9 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | |||
445 | drive->name, lba_capacity, capacity); | 395 | drive->name, lba_capacity, capacity); |
446 | floppy->blocks = floppy->block_size ? | 396 | floppy->blocks = floppy->block_size ? |
447 | capacity / floppy->block_size : 0; | 397 | capacity / floppy->block_size : 0; |
398 | drive->capacity64 = floppy->blocks * floppy->bs_factor; | ||
448 | } | 399 | } |
400 | |||
449 | return 0; | 401 | return 0; |
450 | } | 402 | } |
451 | 403 | ||
@@ -455,7 +407,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | |||
455 | */ | 407 | */ |
456 | static int ide_floppy_get_capacity(ide_drive_t *drive) | 408 | static int ide_floppy_get_capacity(ide_drive_t *drive) |
457 | { | 409 | { |
458 | idefloppy_floppy_t *floppy = drive->driver_data; | 410 | struct ide_disk_obj *floppy = drive->driver_data; |
459 | struct gendisk *disk = floppy->disk; | 411 | struct gendisk *disk = floppy->disk; |
460 | struct ide_atapi_pc pc; | 412 | struct ide_atapi_pc pc; |
461 | u8 *cap_desc; | 413 | u8 *cap_desc; |
@@ -466,7 +418,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
466 | drive->bios_head = drive->bios_sect = 0; | 418 | drive->bios_head = drive->bios_sect = 0; |
467 | floppy->blocks = 0; | 419 | floppy->blocks = 0; |
468 | floppy->bs_factor = 1; | 420 | floppy->bs_factor = 1; |
469 | set_capacity(floppy->disk, 0); | 421 | drive->capacity64 = 0; |
470 | 422 | ||
471 | ide_floppy_create_read_capacity_cmd(&pc); | 423 | ide_floppy_create_read_capacity_cmd(&pc); |
472 | if (ide_queue_pc_tail(drive, disk, &pc)) { | 424 | if (ide_queue_pc_tail(drive, disk, &pc)) { |
@@ -523,6 +475,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
523 | "non 512 bytes block size not " | 475 | "non 512 bytes block size not " |
524 | "fully supported\n", | 476 | "fully supported\n", |
525 | drive->name); | 477 | drive->name); |
478 | drive->capacity64 = | ||
479 | floppy->blocks * floppy->bs_factor; | ||
526 | rc = 0; | 480 | rc = 0; |
527 | } | 481 | } |
528 | break; | 482 | break; |
@@ -547,21 +501,12 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
547 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) | 501 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
548 | (void) ide_floppy_get_flexible_disk_page(drive); | 502 | (void) ide_floppy_get_flexible_disk_page(drive); |
549 | 503 | ||
550 | set_capacity(disk, floppy->blocks * floppy->bs_factor); | ||
551 | |||
552 | return rc; | 504 | return rc; |
553 | } | 505 | } |
554 | 506 | ||
555 | sector_t ide_floppy_capacity(ide_drive_t *drive) | 507 | static void ide_floppy_setup(ide_drive_t *drive) |
556 | { | ||
557 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
558 | unsigned long capacity = floppy->blocks * floppy->bs_factor; | ||
559 | |||
560 | return capacity; | ||
561 | } | ||
562 | |||
563 | static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) | ||
564 | { | 508 | { |
509 | struct ide_disk_obj *floppy = drive->driver_data; | ||
565 | u16 *id = drive->id; | 510 | u16 *id = drive->id; |
566 | 511 | ||
567 | drive->pc_callback = ide_floppy_callback; | 512 | drive->pc_callback = ide_floppy_callback; |
@@ -592,252 +537,42 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) | |||
592 | blk_queue_max_sectors(drive->queue, 64); | 537 | blk_queue_max_sectors(drive->queue, 64); |
593 | drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; | 538 | drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; |
594 | /* IOMEGA Clik! drives do not support lock/unlock commands */ | 539 | /* IOMEGA Clik! drives do not support lock/unlock commands */ |
595 | drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; | 540 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
596 | } | 541 | } |
597 | 542 | ||
598 | (void) ide_floppy_get_capacity(drive); | 543 | (void) ide_floppy_get_capacity(drive); |
599 | 544 | ||
600 | ide_proc_register_driver(drive, floppy->driver); | 545 | ide_proc_register_driver(drive, floppy->driver); |
601 | } | ||
602 | 546 | ||
603 | static void ide_floppy_remove(ide_drive_t *drive) | 547 | drive->dev_flags |= IDE_DFLAG_ATTACH; |
604 | { | ||
605 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
606 | struct gendisk *g = floppy->disk; | ||
607 | |||
608 | ide_proc_unregister_driver(drive, floppy->driver); | ||
609 | |||
610 | del_gendisk(g); | ||
611 | |||
612 | ide_floppy_put(floppy); | ||
613 | } | 548 | } |
614 | 549 | ||
615 | static void idefloppy_cleanup_obj(struct kref *kref) | 550 | static void ide_floppy_flush(ide_drive_t *drive) |
616 | { | 551 | { |
617 | struct ide_floppy_obj *floppy = to_ide_drv(kref, ide_floppy_obj); | ||
618 | ide_drive_t *drive = floppy->drive; | ||
619 | struct gendisk *g = floppy->disk; | ||
620 | |||
621 | drive->driver_data = NULL; | ||
622 | g->private_data = NULL; | ||
623 | put_disk(g); | ||
624 | kfree(floppy); | ||
625 | } | 552 | } |
626 | 553 | ||
627 | static int ide_floppy_probe(ide_drive_t *); | 554 | static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk) |
628 | |||
629 | static ide_driver_t idefloppy_driver = { | ||
630 | .gen_driver = { | ||
631 | .owner = THIS_MODULE, | ||
632 | .name = "ide-floppy", | ||
633 | .bus = &ide_bus_type, | ||
634 | }, | ||
635 | .probe = ide_floppy_probe, | ||
636 | .remove = ide_floppy_remove, | ||
637 | .version = IDEFLOPPY_VERSION, | ||
638 | .do_request = idefloppy_do_request, | ||
639 | .end_request = idefloppy_end_request, | ||
640 | .error = __ide_error, | ||
641 | #ifdef CONFIG_IDE_PROC_FS | ||
642 | .proc = ide_floppy_proc, | ||
643 | .settings = ide_floppy_settings, | ||
644 | #endif | ||
645 | }; | ||
646 | |||
647 | static int idefloppy_open(struct inode *inode, struct file *filp) | ||
648 | { | 555 | { |
649 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
650 | struct ide_floppy_obj *floppy; | ||
651 | ide_drive_t *drive; | ||
652 | int ret = 0; | 556 | int ret = 0; |
653 | 557 | ||
654 | floppy = ide_floppy_get(disk); | 558 | if (ide_do_test_unit_ready(drive, disk)) |
655 | if (!floppy) | 559 | ide_do_start_stop(drive, disk, 1); |
656 | return -ENXIO; | ||
657 | |||
658 | drive = floppy->drive; | ||
659 | |||
660 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | ||
661 | |||
662 | floppy->openers++; | ||
663 | |||
664 | if (floppy->openers == 1) { | ||
665 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | ||
666 | /* Just in case */ | ||
667 | |||
668 | if (ide_do_test_unit_ready(drive, disk)) | ||
669 | ide_do_start_stop(drive, disk, 1); | ||
670 | |||
671 | if (ide_floppy_get_capacity(drive) | ||
672 | && (filp->f_flags & O_NDELAY) == 0 | ||
673 | /* | ||
674 | * Allow O_NDELAY to open a drive without a disk, or with an | ||
675 | * unreadable disk, so that we can get the format capacity | ||
676 | * of the drive or begin the format - Sam | ||
677 | */ | ||
678 | ) { | ||
679 | ret = -EIO; | ||
680 | goto out_put_floppy; | ||
681 | } | ||
682 | |||
683 | if ((drive->atapi_flags & IDE_AFLAG_WP) && (filp->f_mode & 2)) { | ||
684 | ret = -EROFS; | ||
685 | goto out_put_floppy; | ||
686 | } | ||
687 | |||
688 | drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED; | ||
689 | ide_set_media_lock(drive, disk, 1); | ||
690 | check_disk_change(inode->i_bdev); | ||
691 | } else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) { | ||
692 | ret = -EBUSY; | ||
693 | goto out_put_floppy; | ||
694 | } | ||
695 | return 0; | ||
696 | |||
697 | out_put_floppy: | ||
698 | floppy->openers--; | ||
699 | ide_floppy_put(floppy); | ||
700 | return ret; | ||
701 | } | ||
702 | |||
703 | static int idefloppy_release(struct inode *inode, struct file *filp) | ||
704 | { | ||
705 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
706 | struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); | ||
707 | ide_drive_t *drive = floppy->drive; | ||
708 | |||
709 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | ||
710 | |||
711 | if (floppy->openers == 1) { | ||
712 | ide_set_media_lock(drive, disk, 0); | ||
713 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | ||
714 | } | ||
715 | |||
716 | floppy->openers--; | ||
717 | |||
718 | ide_floppy_put(floppy); | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
724 | { | ||
725 | struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk, | ||
726 | ide_floppy_obj); | ||
727 | ide_drive_t *drive = floppy->drive; | ||
728 | 560 | ||
729 | geo->heads = drive->bios_head; | 561 | ret = ide_floppy_get_capacity(drive); |
730 | geo->sectors = drive->bios_sect; | ||
731 | geo->cylinders = (u16)drive->bios_cyl; /* truncate */ | ||
732 | return 0; | ||
733 | } | ||
734 | 562 | ||
735 | static int idefloppy_media_changed(struct gendisk *disk) | 563 | set_capacity(disk, ide_gd_capacity(drive)); |
736 | { | ||
737 | struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); | ||
738 | ide_drive_t *drive = floppy->drive; | ||
739 | int ret; | ||
740 | 564 | ||
741 | /* do not scan partitions twice if this is a removable device */ | ||
742 | if (drive->dev_flags & IDE_DFLAG_ATTACH) { | ||
743 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | ||
744 | return 0; | ||
745 | } | ||
746 | ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED); | ||
747 | drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED; | ||
748 | return ret; | 565 | return ret; |
749 | } | 566 | } |
750 | 567 | ||
751 | static int idefloppy_revalidate_disk(struct gendisk *disk) | 568 | const struct ide_disk_ops ide_atapi_disk_ops = { |
752 | { | 569 | .check = ide_check_atapi_device, |
753 | struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); | 570 | .get_capacity = ide_floppy_get_capacity, |
754 | set_capacity(disk, ide_floppy_capacity(floppy->drive)); | 571 | .setup = ide_floppy_setup, |
755 | return 0; | 572 | .flush = ide_floppy_flush, |
756 | } | 573 | .init_media = ide_floppy_init_media, |
757 | 574 | .set_doorlock = ide_set_media_lock, | |
758 | static struct block_device_operations idefloppy_ops = { | 575 | .do_request = ide_floppy_do_request, |
759 | .owner = THIS_MODULE, | 576 | .end_request = ide_floppy_end_request, |
760 | .open = idefloppy_open, | 577 | .ioctl = ide_floppy_ioctl, |
761 | .release = idefloppy_release, | ||
762 | .ioctl = ide_floppy_ioctl, | ||
763 | .getgeo = idefloppy_getgeo, | ||
764 | .media_changed = idefloppy_media_changed, | ||
765 | .revalidate_disk = idefloppy_revalidate_disk | ||
766 | }; | 578 | }; |
767 | |||
768 | static int ide_floppy_probe(ide_drive_t *drive) | ||
769 | { | ||
770 | idefloppy_floppy_t *floppy; | ||
771 | struct gendisk *g; | ||
772 | |||
773 | if (!strstr("ide-floppy", drive->driver_req)) | ||
774 | goto failed; | ||
775 | |||
776 | if (drive->media != ide_floppy) | ||
777 | goto failed; | ||
778 | |||
779 | if (!ide_check_atapi_device(drive, DRV_NAME)) { | ||
780 | printk(KERN_ERR PFX "%s: not supported by this version of " | ||
781 | DRV_NAME "\n", drive->name); | ||
782 | goto failed; | ||
783 | } | ||
784 | floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); | ||
785 | if (!floppy) { | ||
786 | printk(KERN_ERR PFX "%s: Can't allocate a floppy structure\n", | ||
787 | drive->name); | ||
788 | goto failed; | ||
789 | } | ||
790 | |||
791 | g = alloc_disk(1 << PARTN_BITS); | ||
792 | if (!g) | ||
793 | goto out_free_floppy; | ||
794 | |||
795 | ide_init_disk(g, drive); | ||
796 | |||
797 | kref_init(&floppy->kref); | ||
798 | |||
799 | floppy->drive = drive; | ||
800 | floppy->driver = &idefloppy_driver; | ||
801 | floppy->disk = g; | ||
802 | |||
803 | g->private_data = &floppy->driver; | ||
804 | |||
805 | drive->driver_data = floppy; | ||
806 | |||
807 | drive->debug_mask = debug_mask; | ||
808 | |||
809 | idefloppy_setup(drive, floppy); | ||
810 | drive->dev_flags |= IDE_DFLAG_ATTACH; | ||
811 | |||
812 | g->minors = 1 << PARTN_BITS; | ||
813 | g->driverfs_dev = &drive->gendev; | ||
814 | if (drive->dev_flags & IDE_DFLAG_REMOVABLE) | ||
815 | g->flags = GENHD_FL_REMOVABLE; | ||
816 | g->fops = &idefloppy_ops; | ||
817 | add_disk(g); | ||
818 | return 0; | ||
819 | |||
820 | out_free_floppy: | ||
821 | kfree(floppy); | ||
822 | failed: | ||
823 | return -ENODEV; | ||
824 | } | ||
825 | |||
826 | static void __exit idefloppy_exit(void) | ||
827 | { | ||
828 | driver_unregister(&idefloppy_driver.gen_driver); | ||
829 | } | ||
830 | |||
831 | static int __init idefloppy_init(void) | ||
832 | { | ||
833 | printk(KERN_INFO DRV_NAME " driver " IDEFLOPPY_VERSION "\n"); | ||
834 | return driver_register(&idefloppy_driver.gen_driver); | ||
835 | } | ||
836 | |||
837 | MODULE_ALIAS("ide:*m-floppy*"); | ||
838 | MODULE_ALIAS("ide-floppy"); | ||
839 | module_init(idefloppy_init); | ||
840 | module_exit(idefloppy_exit); | ||
841 | MODULE_LICENSE("GPL"); | ||
842 | MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); | ||
843 | |||