#define IDEFLOPPY_VERSION "0.99.newide"
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/cdrom.h>
#include <linux/ide.h>
#include <linux/bitops.h>
+#include <linux/mutex.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
unsigned long flags;
} idefloppy_floppy_t;
-#define IDEFLOPPY_TICKS_DELAY 3 /* default delay for ZIP 100 */
+#define IDEFLOPPY_TICKS_DELAY HZ/20 /* default delay for ZIP 100 (50ms) */
/*
* Floppy flag bits values.
u8 reserved[4];
} idefloppy_mode_parameter_header_t;
-static DECLARE_MUTEX(idefloppy_ref_sem);
+static DEFINE_MUTEX(idefloppy_ref_mutex);
#define to_ide_floppy(obj) container_of(obj, struct ide_floppy_obj, kref)
{
struct ide_floppy_obj *floppy = NULL;
- down(&idefloppy_ref_sem);
+ mutex_lock(&idefloppy_ref_mutex);
floppy = ide_floppy_g(disk);
if (floppy)
kref_get(&floppy->kref);
- up(&idefloppy_ref_sem);
+ mutex_unlock(&idefloppy_ref_mutex);
return floppy;
}
static void ide_floppy_put(struct ide_floppy_obj *floppy)
{
- down(&idefloppy_ref_sem);
+ mutex_lock(&idefloppy_ref_mutex);
kref_put(&floppy->kref, ide_floppy_release);
- up(&idefloppy_ref_sem);
+ mutex_unlock(&idefloppy_ref_mutex);
}
/*
/* Why does this happen? */
if (!rq)
return 0;
- if (!(rq->flags & REQ_SPECIAL)) { //if (!IDEFLOPPY_RQ_CMD (rq->cmd)) {
+ if (!blk_special_request(rq)) {
/* our real local end request function */
ide_end_request(drive, uptodate, nsecs);
return 0;
idefloppy_do_end_request(drive, 1, done >> 9);
+#if IDEFLOPPY_DEBUG_BUGS
if (bcount) {
printk(KERN_ERR "%s: leftover data in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
idefloppy_write_zeros(drive, bcount);
}
+#endif
}
static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc)
ide_init_drive_cmd(rq);
rq->buffer = (char *) pc;
- rq->flags = REQ_SPECIAL; //rq->cmd = IDEFLOPPY_PC_RQ;
+ rq->cmd_type = REQ_TYPE_SPECIAL;
rq->rq_disk = floppy->disk;
(void) ide_do_drive_cmd(drive, rq, ide_preempt);
}
"transferred\n", pc->actually_transferred);
clear_bit(PC_DMA_IN_PROGRESS, &pc->flags);
- local_irq_enable();
+ local_irq_enable_in_hardirq();
if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) {
/* Error detected */
"to send us more data than expected "
"- discarding data\n");
idefloppy_discard_data(drive,bcount.all);
- if (HWGROUP(drive)->handler != NULL)
- BUG();
+ BUG_ON(HWGROUP(drive)->handler != NULL);
ide_set_handler(drive,
&idefloppy_pc_intr,
IDEFLOPPY_WAIT_CMD,
pc->actually_transferred += bcount.all;
pc->current_position += bcount.all;
- if (HWGROUP(drive)->handler != NULL)
- BUG();
+ BUG_ON(HWGROUP(drive)->handler != NULL);
ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */
return ide_started;
}
"issuing a packet command\n");
return ide_do_reset(drive);
}
- if (HWGROUP(drive)->handler != NULL)
- BUG();
+ BUG_ON(HWGROUP(drive)->handler != NULL);
/* Set the interrupt routine */
ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);
/* Send the actual packet */
* 40 and 50msec work well. idefloppy_pc_intr will not be actually
* used until after the packet is moved in about 50 msec.
*/
- if (HWGROUP(drive)->handler != NULL)
- BUG();
+ BUG_ON(HWGROUP(drive)->handler != NULL);
ide_set_handler(drive,
&idefloppy_pc_intr, /* service routine for packet command */
floppy->ticks, /* wait this long before "failing" */
atapi_bcount_t bcount;
ide_handler_t *pkt_xfer_routine;
+#if 0 /* Accessing floppy->pc is not valid here, the previous pc may be gone
+ and have lived on another thread's stack; that stack may have become
+ unmapped meanwhile (CONFIG_DEBUG_PAGEALLOC). */
#if IDEFLOPPY_DEBUG_BUGS
if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD &&
pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
"Two request sense in serial were issued\n");
}
#endif /* IDEFLOPPY_DEBUG_BUGS */
+#endif
if (floppy->failed_pc == NULL &&
pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD)
pc->callback = &idefloppy_rw_callback;
pc->rq = rq;
pc->b_count = cmd == READ ? 0 : rq->bio->bi_size;
- if (rq->flags & REQ_RW)
+ if (rq->cmd_flags & REQ_RW)
set_bit(PC_WRITING, &pc->flags);
pc->buffer = NULL;
pc->request_transfer = pc->buffer_size = blocks * floppy->block_size;
idefloppy_pc_t *pc;
unsigned long block = (unsigned long)block_s;
- debug_log(KERN_INFO "rq_status: %d, dev: %s, flags: %lx, errors: %d\n",
- rq->rq_status,
- rq->rq_disk ? rq->rq_disk->disk_name ? "?",
+ debug_log(KERN_INFO "dev: %s, flags: %lx, errors: %d\n",
+ rq->rq_disk ? rq->rq_disk->disk_name : "?",
rq->flags, rq->errors);
debug_log(KERN_INFO "sector: %ld, nr_sectors: %ld, "
"current_nr_sectors: %d\n", (long)rq->sector,
idefloppy_do_end_request(drive, 0, 0);
return ide_stopped;
}
- if (rq->flags & REQ_CMD) {
+ if (blk_fs_request(rq)) {
if (((long)rq->sector % floppy->bs_factor) ||
(rq->nr_sectors % floppy->bs_factor)) {
printk("%s: unsupported r/w request size\n",
}
pc = idefloppy_next_pc_storage(drive);
idefloppy_create_rw_cmd(floppy, pc, rq, block);
- } else if (rq->flags & REQ_SPECIAL) {
+ } else if (blk_special_request(rq)) {
pc = (idefloppy_pc_t *) rq->buffer;
- } else if (rq->flags & REQ_BLOCK_PC) {
+ } else if (blk_pc_request(rq)) {
pc = idefloppy_next_pc_storage(drive);
if (idefloppy_blockpc_cmd(floppy, pc, rq)) {
idefloppy_do_end_request(drive, 0, 0);
ide_init_drive_cmd (&rq);
rq.buffer = (char *) pc;
- rq.flags = REQ_SPECIAL; // rq.cmd = IDEFLOPPY_PC_RQ;
+ rq.cmd_type = REQ_TYPE_SPECIAL;
rq.rq_disk = floppy->disk;
return ide_do_drive_cmd(drive, &rq, ide_wait);
/*
** Get ATAPI_FORMAT_UNIT progress indication.
**
-** Userland gives a pointer to an int. The int is set to a progresss
+** Userland gives a pointer to an int. The int is set to a progress
** indicator 0-65536, with 65536=100%.
**
** If the drive does not support format progress indication, we just check
idefloppy_add_settings(drive);
}
-static int ide_floppy_remove(struct device *dev)
+static void ide_floppy_remove(ide_drive_t *drive)
{
- ide_drive_t *drive = to_ide_device(dev);
idefloppy_floppy_t *floppy = drive->driver_data;
struct gendisk *g = floppy->disk;
del_gendisk(g);
ide_floppy_put(floppy);
-
- return 0;
}
static void ide_floppy_release(struct kref *kref)
#endif /* CONFIG_PROC_FS */
-static int ide_floppy_probe(struct device *);
+static int ide_floppy_probe(ide_drive_t *);
static ide_driver_t idefloppy_driver = {
- .owner = THIS_MODULE,
.gen_driver = {
+ .owner = THIS_MODULE,
.name = "ide-floppy",
.bus = &ide_bus_type,
- .probe = ide_floppy_probe,
- .remove = ide_floppy_remove,
},
+ .probe = ide_floppy_probe,
+ .remove = ide_floppy_remove,
.version = IDEFLOPPY_VERSION,
.media = ide_floppy,
.supports_dsc_overlap = 0,
return 0;
}
+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;
+}
+
static int idefloppy_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
ide_drive_t *drive = floppy->drive;
void __user *argp = (void __user *)arg;
- int err = generic_ide_ioctl(drive, file, bdev, cmd, arg);
+ int err;
int prevent = (arg) ? 1 : 0;
idefloppy_pc_t pc;
- if (err != -EINVAL)
- return err;
switch (cmd) {
case CDROMEJECT:
case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
return idefloppy_get_format_progress(drive, argp);
}
- return -EINVAL;
+ return generic_ide_ioctl(drive, file, bdev, cmd, arg);
}
static int idefloppy_media_changed(struct gendisk *disk)
.open = idefloppy_open,
.release = idefloppy_release,
.ioctl = idefloppy_ioctl,
+ .getgeo = idefloppy_getgeo,
.media_changed = idefloppy_media_changed,
.revalidate_disk= idefloppy_revalidate_disk
};
-static int ide_floppy_probe(struct device *dev)
+static int ide_floppy_probe(ide_drive_t *drive)
{
- ide_drive_t *drive = to_ide_device(dev);
idefloppy_floppy_t *floppy;
struct gendisk *g;
printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name);
goto failed;
}
- if ((floppy = (idefloppy_floppy_t *) kmalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
+ if ((floppy = kzalloc(sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name);
goto failed;
}
ide_register_subdriver(drive, &idefloppy_driver);
- memset(floppy, 0, sizeof(*floppy));
-
kref_init(&floppy->kref);
floppy->drive = drive;
g->minors = 1 << PARTN_BITS;
g->driverfs_dev = &drive->gendev;
- strcpy(g->devfs_name, drive->devfs_name);
g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
g->fops = &idefloppy_ops;
drive->attach = 1;
driver_unregister(&idefloppy_driver.gen_driver);
}
-/*
- * idefloppy_init will register the driver for each floppy.
- */
-static int idefloppy_init (void)
+static int __init idefloppy_init(void)
{
printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
return driver_register(&idefloppy_driver.gen_driver);
}
+MODULE_ALIAS("ide:*m-floppy*");
module_init(idefloppy_init);
module_exit(idefloppy_exit);
MODULE_LICENSE("GPL");