summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-09-19 19:15:08 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-09-19 19:15:08 +0000
commit03ba4131783cc9e872f8bb26a03f15bc11f27564 (patch)
tree88db8dba75ae06ba3bad08e42c5e52efc162535c /drivers/block
parent257730f99381dd26e10b832fce4c94cae7ac1176 (diff)
- Merge with Linux 2.1.121.
- Bugfixes.
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/Config.in8
-rw-r--r--drivers/block/Makefile8
-rw-r--r--drivers/block/acsi.c3
-rw-r--r--drivers/block/acsi_slm.c3
-rw-r--r--drivers/block/amiflop.c1
-rw-r--r--drivers/block/ataflop.c1
-rw-r--r--drivers/block/floppy.c3
-rw-r--r--drivers/block/genhd.c20
-rw-r--r--drivers/block/ide-pmac.c302
-rw-r--r--drivers/block/ide-probe.c2
-rw-r--r--drivers/block/ide-tape.c1
-rw-r--r--drivers/block/ide.c16
-rw-r--r--drivers/block/loop.c1
-rw-r--r--drivers/block/md.c1
-rw-r--r--drivers/block/nbd.c54
-rw-r--r--drivers/block/paride/Makefile37
-rw-r--r--drivers/block/paride/bpck.c5
-rw-r--r--drivers/block/paride/paride.c5
-rw-r--r--drivers/block/paride/pcd.c609
-rw-r--r--drivers/block/paride/pd.c15
-rw-r--r--drivers/block/paride/pf.c17
-rw-r--r--drivers/block/paride/pg.c349
-rw-r--r--drivers/block/paride/pt.c22
-rw-r--r--drivers/block/ps2esdi.c1
-rw-r--r--drivers/block/rd.c8
-rw-r--r--drivers/block/swim3.c1
-rw-r--r--drivers/block/xd.c1
-rw-r--r--drivers/block/z2ram.c347
28 files changed, 1213 insertions, 628 deletions
diff --git a/drivers/block/Config.in b/drivers/block/Config.in
index 86208ba98..02bfe7dcd 100644
--- a/drivers/block/Config.in
+++ b/drivers/block/Config.in
@@ -48,6 +48,14 @@ else
bool ' WInbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
fi
fi
+ if [ "$CONFIG_PMAC" = "y" ]; then
+ define_bool CONFIG_BLK_DEV_IDE_PMAC y
+ bool ' PowerMac IDE DMA support' CONFIG_BLK_DEV_IDEDMA_PMAC
+ if [ "$CONFIG_BLK_DEV_IDEDMA_PMAC" = "y" ]; then
+ define_bool CONFIG_BLK_DEV_IDEDMA y
+ bool ' Use DMA by default' CONFIG_PMAC_IDEDMA_AUTO
+ fi
+ fi
bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS
if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then
comment 'Note: most of these also require special kernel boot parameters'
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index f3543db2e..fa943cc48 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -106,6 +106,10 @@ ifeq ($(CONFIG_BLK_DEV_CMD640),y)
IDE_OBJS += cmd640.o
endif
+ifeq ($(CONFIG_BLK_DEV_IDE_PMAC),y)
+IDE_OBJS += ide-pmac.o
+endif
+
ifeq ($(CONFIG_BLK_DEV_IDEPCI),y)
IDE_OBJS += ide-pci.o
endif
@@ -269,10 +273,10 @@ endif
ifeq ($(CONFIG_PARIDE),y)
SUB_DIRS += paride
-MOD_SUB_DIRS += paride
+MOD_IN_SUB_DIRS += paride
else
ifeq ($(CONFIG_PARIDE),m)
- MOD_SUB_DIRS += paride
+ MOD_IN_SUB_DIRS += paride
endif
endif
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
index 3594eb189..f49f186a8 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -1788,7 +1788,8 @@ static struct file_operations acsi_fops = {
acsi_ioctl, /* ioctl */
NULL, /* mmap */
acsi_open, /* open */
- acsi_release, /* release */
+ NULL, /* flush */
+ acsi_release, /* release */
block_fsync, /* fsync */
NULL, /* fasync */
acsi_media_change, /* media_change */
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index 4b301cb2a..66121340f 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -288,7 +288,8 @@ static struct file_operations slm_fops = {
slm_ioctl, /* ioctl */
NULL, /* mmap */
slm_open, /* open */
- slm_release, /* release */
+ NULL, /* flush */
+ slm_release, /* release */
NULL /* fsync */
};
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index afee4899e..a7631741e 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1747,6 +1747,7 @@ static struct file_operations floppy_fops = {
fd_ioctl, /* ioctl */
NULL, /* mmap */
floppy_open, /* open */
+ NULL, /* flush */
floppy_release, /* release */
block_fsync, /* fsync */
NULL, /* fasync */
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 640ddfd3a..5c55700a7 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -2008,6 +2008,7 @@ static struct file_operations floppy_fops = {
fd_ioctl, /* ioctl */
NULL, /* mmap */
floppy_open, /* open */
+ NULL, /* flush */
floppy_release, /* release */
block_fsync, /* fsync */
NULL, /* fasync */
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index b8ca2ed8e..e555aa9d9 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -233,7 +233,7 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l)
/* End dma memory related stuff */
-static unsigned int fake_change = 0;
+static unsigned long fake_change = 0;
static int initialising=1;
static inline int TYPE(kdev_t x) {
@@ -3837,6 +3837,7 @@ static struct file_operations floppy_fops = {
fd_ioctl, /* ioctl */
NULL, /* mmap */
floppy_open, /* open */
+ NULL, /* flush */
floppy_release, /* release */
block_fsync, /* fsync */
NULL, /* fasync */
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index 040d922ef..c1b1e4e06 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -411,29 +411,23 @@ check_table:
} else {
/*
* Examine the partition table for common translations.
- * This is necessary for drives for situations where
- * the translated geometry is unavailable from the BIOS.
+ * This is useful for drives in situations where the
+ * translated geometry is unavailable from the BIOS.
*/
- int xlate_done = 0;
- for (i = 0; i < 4 && !xlate_done; i++) {
+ for (i = 0; i < 4; i++) {
struct partition *q = &p[i];
if (NR_SECTS(q)
&& (q->sector & 63) == 1
&& (q->end_sector & 63) == 63) {
unsigned int heads = q->end_head + 1;
- if (heads == 32 || heads == 64 || heads == 128 || heads == 255) {
-
+ if (heads == 32 || heads == 64 ||
+ heads == 128 || heads == 255 ||
+ heads == 240) {
(void) ide_xlate_1024(dev, heads, " [PTBL]");
- xlate_done = 1;
+ break;
}
}
}
- if (!xlate_done) {
- /*
- * Default translation is equivalent of "BIOS LBA":
- */
- ide_xlate_1024(dev, -2, " [LBA]");
- }
}
}
#endif /* CONFIG_BLK_DEV_IDE */
diff --git a/drivers/block/ide-pmac.c b/drivers/block/ide-pmac.c
new file mode 100644
index 000000000..cb8b13e06
--- /dev/null
+++ b/drivers/block/ide-pmac.c
@@ -0,0 +1,302 @@
+/*
+ * Support for IDE interfaces on PowerMacs.
+ * These IDE interfaces are memory-mapped and have a DBDMA channel
+ * for doing DMA.
+ *
+ * Copyright (C) 1998 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Some code taken from drivers/block/ide-dma.c:
+ *
+ * Copyright (c) 1995-1998 Mark Lord
+ *
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/dbdma.h>
+#include <asm/ide.h>
+#include <asm/mediabay.h>
+#include "ide.h"
+
+ide_ioreg_t pmac_ide_regbase[MAX_HWIFS];
+int pmac_ide_irq[MAX_HWIFS];
+
+#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+#define MAX_DCMDS 256 /* allow up to 256 DBDMA commands per xfer */
+
+static void pmac_ide_setup_dma(struct device_node *np, ide_hwif_t *hwif);
+static int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive);
+static int pmac_ide_build_dmatable(ide_drive_t *drive, int wr);
+#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
+
+/*
+ * N.B. this can't be an initfunc, because the media-bay task can
+ * call ide_[un]register at any time.
+ */
+void
+pmac_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq)
+{
+ int i;
+
+ *p = 0;
+ if (base == 0)
+ return;
+ if (base == mb_cd_base && !check_media_bay(MB_CD)) {
+ mb_cd_index = -1;
+ return;
+ }
+ for (i = 0; i < 8; ++i)
+ *p++ = base + i * 0x10;
+ *p = base + 0x160;
+ if (irq != NULL) {
+ *irq = 0;
+ for (i = 0; i < MAX_HWIFS; ++i) {
+ if (base == pmac_ide_regbase[i]) {
+ *irq = pmac_ide_irq[i];
+ break;
+ }
+ }
+ }
+}
+
+__initfunc(void
+pmac_ide_probe(void))
+{
+ struct device_node *np;
+ int i;
+ struct device_node *atas;
+ struct device_node *p, **pp, *removables, **rp;
+ unsigned long base;
+ int irq;
+ ide_hwif_t *hwif;
+
+ if (_machine != _MACH_Pmac)
+ return;
+ pp = &atas;
+ rp = &removables;
+ p = find_devices("ATA");
+ if (p == NULL)
+ p = find_devices("IDE");
+ if (p == NULL)
+ p = find_type_devices("ide");
+ if (p == NULL)
+ p = find_type_devices("ata");
+ /* Move removable devices such as the media-bay CDROM
+ on the PB3400 to the end of the list. */
+ for (; p != NULL; p = p->next) {
+ if (p->parent && p->parent->name
+ && strcasecmp(p->parent->name, "media-bay") == 0) {
+ *rp = p;
+ rp = &p->next;
+ } else {
+ *pp = p;
+ pp = &p->next;
+ }
+ }
+ *rp = NULL;
+ *pp = removables;
+
+ for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) {
+ if (np->n_addrs == 0) {
+ printk(KERN_WARNING "ide: no address for device %s\n",
+ np->full_name);
+ continue;
+ }
+ base = (unsigned long) ioremap(np->addrs[0].address, 0x200);
+ if (np->n_intrs == 0) {
+ printk("ide: no intrs for device %s, using 13\n",
+ np->full_name);
+ irq = 13;
+ } else {
+ irq = np->intrs[0].line;
+ }
+ pmac_ide_regbase[i] = base;
+ pmac_ide_irq[i] = irq;
+
+ if (np->parent && np->parent->name
+ && strcasecmp(np->parent->name, "media-bay") == 0) {
+ mb_cd_index = i;
+ mb_cd_base = base;
+ mb_cd_irq = irq;
+ }
+
+ hwif = &ide_hwifs[i];
+ pmac_ide_init_hwif_ports(hwif->io_ports, base, &hwif->irq);
+ hwif->chipset = ide_generic;
+ hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
+
+#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+ if (np->n_addrs >= 2 && np->n_intrs >= 2) {
+ /* has a DBDMA controller channel */
+ pmac_ide_setup_dma(np, hwif);
+ }
+#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
+
+ ++i;
+ }
+}
+
+#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+
+__initfunc(static void
+pmac_ide_setup_dma(struct device_node *np, ide_hwif_t *hwif))
+{
+ hwif->dma_base = (unsigned long) ioremap(np->addrs[1].address, 0x200);
+
+ /*
+ * Allocate space for the DBDMA commands.
+ * The +2 is +1 for the stop command and +1 to allow for
+ * aligning the start address to a multiple of 16 bytes.
+ */
+ hwif->dmatable = (unsigned long *)
+ kmalloc((MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), GFP_KERNEL);
+ if (hwif->dmatable == 0) {
+ printk(KERN_ERR "%s: unable to allocate DMA command list\n",
+ hwif->name);
+ return;
+ }
+
+ hwif->dmaproc = &pmac_ide_dmaproc;
+#ifdef CONFIG_PMAC_IDEDMA_AUTO
+ hwif->autodma = 1;
+#endif
+}
+
+/*
+ * pmac_ide_build_dmatable builds the DBDMA command list
+ * for a transfer and sets the DBDMA channel to point to it.
+ */
+static int
+pmac_ide_build_dmatable(ide_drive_t *drive, int wr)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ struct dbdma_cmd *table, *tstart;
+ int count = 0;
+ struct request *rq = HWGROUP(drive)->rq;
+ struct buffer_head *bh = rq->bh;
+ unsigned int size, addr;
+ volatile struct dbdma_regs *dma
+ = (volatile struct dbdma_regs *) hwif->dma_base;
+
+ table = tstart = (struct dbdma_cmd *) DBDMA_ALIGN(hwif->dmatable);
+ out_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
+
+ do {
+ /*
+ * Determine addr and size of next buffer area. We assume that
+ * individual virtual buffers are always composed linearly in
+ * physical memory. For example, we assume that any 8kB buffer
+ * is always composed of two adjacent physical 4kB pages rather
+ * than two possibly non-adjacent physical 4kB pages.
+ */
+ if (bh == NULL) { /* paging requests have (rq->bh == NULL) */
+ addr = virt_to_bus(rq->buffer);
+ size = rq->nr_sectors << 9;
+ } else {
+ /* group sequential buffers into one large buffer */
+ addr = virt_to_bus(bh->b_data);
+ size = bh->b_size;
+ while ((bh = bh->b_reqnext) != NULL) {
+ if ((addr + size) != virt_to_bus(bh->b_data))
+ break;
+ size += bh->b_size;
+ }
+ }
+
+ /*
+ * Fill in the next DBDMA command block.
+ * Note that one DBDMA command can transfer
+ * at most 65535 bytes.
+ */
+ while (size) {
+ unsigned int tc = (size < 0xfe00)? size: 0xfe00;
+
+ if (++count >= MAX_DCMDS) {
+ printk("%s: DMA table too small\n",
+ drive->name);
+ return 0; /* revert to PIO for this request */
+ }
+ st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE);
+ st_le16(&table->req_count, tc);
+ st_le32(&table->phy_addr, addr);
+ table->cmd_dep = 0;
+ table->xfer_status = 0;
+ table->res_count = 0;
+ addr += tc;
+ size -= tc;
+ ++table;
+ }
+ } while (bh != NULL);
+
+ /* convert the last command to an input/output last command */
+ if (count)
+ st_le16(&table[-1].command, wr? OUTPUT_LAST: INPUT_LAST);
+ else
+ printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
+
+ /* add the stop command to the end of the list */
+ memset(table, 0, sizeof(struct dbdma_cmd));
+ out_le16(&table->command, DBDMA_STOP);
+
+ out_le32(&dma->cmdptr, virt_to_bus(tstart));
+ return 1;
+}
+
+int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ volatile struct dbdma_regs *dma
+ = (volatile struct dbdma_regs *) hwif->dma_base;
+ int dstat;
+
+ switch (func) {
+ case ide_dma_on:
+ /* ide-floppy DMA doesn't work yet... */
+ drive->using_dma = drive->media != ide_floppy;
+ break;
+ case ide_dma_off:
+ printk(KERN_INFO "%s: DMA disabled\n", drive->name);
+ case ide_dma_off_quietly:
+ drive->using_dma = 0;
+ break;
+ case ide_dma_check:
+ /* ide-floppy DMA doesn't work yet... */
+ drive->using_dma = hwif->autodma && drive->media != ide_floppy;
+ break;
+ case ide_dma_read:
+ case ide_dma_write:
+ if (!pmac_ide_build_dmatable(drive, func==ide_dma_write))
+ return 1;
+ drive->waiting_for_dma = 1;
+ if (drive->media != ide_disk)
+ return 0;
+ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);
+ OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA,
+ IDE_COMMAND_REG);
+ case ide_dma_begin:
+ out_le32(&dma->control, (RUN << 16) | RUN);
+ break;
+ case ide_dma_end:
+ drive->waiting_for_dma = 0;
+ dstat = in_le32(&dma->status);
+ out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16));
+ /* verify good dma status */
+ return (dstat & (RUN|DEAD|ACTIVE)) != RUN;
+ case ide_dma_test_irq:
+ return (in_le32(&dma->status) & (RUN|ACTIVE)) == RUN;
+ default:
+ printk(KERN_ERR "pmac_ide_dmaproc: bad func %d\n", func);
+ }
+ return 0;
+}
+
+#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
diff --git a/drivers/block/ide-probe.c b/drivers/block/ide-probe.c
index ffe446afe..14b6bf323 100644
--- a/drivers/block/ide-probe.c
+++ b/drivers/block/ide-probe.c
@@ -13,7 +13,7 @@
* Version 1.00 move drive probing code from ide.c to ide-probe.c
* Version 1.01 fix compilation problem for m68k
* Version 1.02 increase WAIT_PIDENTIFY to avoid CD-ROM locking at boot
- * by Andrea Arcangeli <arcangeli@mbox.queen.it>
+ * by Andrea Arcangeli
* Version 1.03 fix for (hwif->chipset == ide_4drives)
*/
diff --git a/drivers/block/ide-tape.c b/drivers/block/ide-tape.c
index 3b6e2790f..61e084366 100644
--- a/drivers/block/ide-tape.c
+++ b/drivers/block/ide-tape.c
@@ -3708,6 +3708,7 @@ static struct file_operations idetape_fops = {
idetape_chrdev_ioctl, /* ioctl */
NULL, /* mmap */
idetape_chrdev_open, /* open */
+ NULL, /* flush */
idetape_chrdev_release, /* release */
NULL, /* fsync */
NULL, /* fasync */
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index 01a4e18e4..9213f5274 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -1104,8 +1104,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, unsigned long *hwgroup_flags
if (sleep) {
if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep))
sleep = jiffies + WAIT_MIN_SLEEP;
- hwgroup->timer.expires = sleep;
- add_timer(&hwgroup->timer);
+ mod_timer(&hwgroup->timer, sleep);
} else {
/* Ugly, but how can we sleep for the lock otherwise? perhaps from tq_scheduler? */
ide_release_lock(&ide_lock); /* for atari only */
@@ -1658,7 +1657,7 @@ void ide_unregister (unsigned int index)
ide_drive_t *drive, *d;
ide_hwif_t *hwif, *g;
ide_hwgroup_t *hwgroup;
- int irq_count = 0, unit;
+ int irq_count = 0, unit, i;
unsigned long flags;
if (index >= MAX_HWIFS)
@@ -1705,8 +1704,8 @@ void ide_unregister (unsigned int index)
* the hwgroup if we were the only member
*/
d = hwgroup->drive;
- for (index = 0; index < MAX_DRIVES; ++index) {
- drive = &hwif->drives[index];
+ for (i = 0; i < MAX_DRIVES; ++i) {
+ drive = &hwif->drives[i];
if (!drive->present)
continue;
while (hwgroup->drive->next != drive)
@@ -2638,6 +2637,12 @@ __initfunc(static void probe_for_hwifs (void))
(void) init_pdc4030();
}
#endif /* CONFIG_BLK_DEV_PDC4030 */
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
+ {
+ extern void pmac_ide_probe(void);
+ pmac_ide_probe();
+ }
+#endif /* CONFIG_BLK_DEV_IDE_PMAC */
}
__initfunc(void ide_init_builtin_drivers (void))
@@ -2869,6 +2874,7 @@ struct file_operations ide_fops[] = {{
ide_ioctl, /* ioctl */
NULL, /* mmap */
ide_open, /* open */
+ NULL, /* flush */
ide_release, /* release */
block_fsync, /* fsync */
NULL, /* fasync */
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 268c9187a..5a936899f 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -670,6 +670,7 @@ static struct file_operations lo_fops = {
lo_ioctl, /* ioctl */
NULL, /* mmap */
lo_open, /* open */
+ NULL, /* flush */
lo_release /* release */
};
diff --git a/drivers/block/md.c b/drivers/block/md.c
index d0eae5a29..b6cf3d34e 100644
--- a/drivers/block/md.c
+++ b/drivers/block/md.c
@@ -754,6 +754,7 @@ static struct file_operations md_fops=
md_ioctl,
NULL,
md_open,
+ NULL,
md_release,
block_fsync
};
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index ddec2b425..87a7d6495 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -61,13 +61,20 @@ static int requests_out;
static int nbd_open(struct inode *inode, struct file *file)
{
int dev;
+ struct nbd_device *nbdev;
if (!inode)
return -EINVAL;
dev = MINOR(inode->i_rdev);
if (dev >= MAX_NBD)
return -ENODEV;
+
+ nbdev = &nbd_dev[dev];
nbd_dev[dev].refcnt++;
+ if (!(nbdev->flags & NBD_INITIALISED)) {
+ nbdev->queue_lock = MUTEX;
+ nbdev->flags |= NBD_INITIALISED;
+ }
MOD_INC_USE_COUNT;
return 0;
}
@@ -81,12 +88,20 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size)
int result;
struct msghdr msg;
struct iovec iov;
+ unsigned long flags;
+ sigset_t oldset;
oldfs = get_fs();
set_fs(get_ds());
- do {
- sigset_t oldset;
+ spin_lock_irqsave(&current->sigmask_lock, flags);
+ oldset = current->blocked;
+ sigfillset(&current->blocked);
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
+
+
+ do {
iov.iov_base = buf;
iov.iov_len = size;
msg.msg_name = NULL;
@@ -98,22 +113,11 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size)
msg.msg_namelen = 0;
msg.msg_flags = 0;
- spin_lock_irq(&current->sigmask_lock);
- oldset = current->blocked;
- sigfillset(&current->blocked);
- recalc_sigpending(current);
- spin_unlock_irq(&current->sigmask_lock);
-
if (send)
result = sock_sendmsg(sock, &msg, size);
else
result = sock_recvmsg(sock, &msg, size, 0);
- spin_lock_irq(&current->sigmask_lock);
- current->blocked = oldset;
- recalc_sigpending(current);
- spin_unlock_irq(&current->sigmask_lock);
-
if (result <= 0) {
#ifdef PARANOIA
printk(KERN_ERR "NBD: %s - sock=%ld at buf=%ld, size=%d returned %d.\n",
@@ -124,6 +128,12 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size)
size -= result;
buf += result;
} while (size > 0);
+
+ spin_lock_irqsave(&current->sigmask_lock, flags);
+ current->blocked = oldset;
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
+
set_fs(oldfs);
return result;
}
@@ -205,16 +215,18 @@ void nbd_do_it(struct nbd_device *lo)
req = nbd_read_stat(lo);
if (!req)
return;
+ down (&lo->queue_lock);
#ifdef PARANOIA
if (req != lo->tail) {
printk(KERN_ALERT "NBD: I have problem...\n");
}
if (lo != &nbd_dev[MINOR(req->rq_dev)]) {
printk(KERN_ALERT "NBD: request corrupted!\n");
- continue;
+ goto next;
}
if (lo->magic != LO_MAGIC) {
printk(KERN_ALERT "NBD: nbd_dev[] corrupted: Not enough magic\n");
+ up (&lo->queue_lock);
return;
}
#endif
@@ -227,6 +239,8 @@ void nbd_do_it(struct nbd_device *lo)
lo->head = NULL;
}
lo->tail = lo->tail->next;
+ next:
+ up (&lo->queue_lock);
}
}
@@ -287,7 +301,7 @@ static void do_nbd_request(void)
lo = &nbd_dev[dev];
if (!lo->file)
FAIL("Request when not-ready.");
- if ((req->cmd == WRITE) && (lo->flags && NBD_READ_ONLY))
+ if ((req->cmd == WRITE) && (lo->flags & NBD_READ_ONLY))
FAIL("Write on read-only");
#ifdef PARANOIA
if (lo->magic != LO_MAGIC)
@@ -295,10 +309,11 @@ static void do_nbd_request(void)
requests_in++;
#endif
req->errors = 0;
-
- nbd_send_req(lo->sock, req); /* Why does this block? */
CURRENT = CURRENT->next;
req->next = NULL;
+
+ spin_unlock_irq(&io_request_lock);
+ down (&lo->queue_lock);
if (lo->head == NULL) {
lo->head = req;
lo->tail = req;
@@ -306,6 +321,10 @@ static void do_nbd_request(void)
lo->head->next = req;
lo->head = req;
}
+
+ nbd_send_req(lo->sock, req); /* Why does this block? */
+ up (&lo->queue_lock);
+ spin_lock_irq(&io_request_lock);
continue;
error_out:
@@ -415,6 +434,7 @@ static struct file_operations nbd_fops =
nbd_ioctl, /* ioctl */
NULL, /* mmap */
nbd_open, /* open */
+ NULL, /* flush */
nbd_release /* release */
};
diff --git a/drivers/block/paride/Makefile b/drivers/block/paride/Makefile
index abb45d2fc..ae2d54dd9 100644
--- a/drivers/block/paride/Makefile
+++ b/drivers/block/paride/Makefile
@@ -12,6 +12,7 @@ SUB_DIRS :=
MOD_SUB_DIRS := $(SUB_DIRS)
ALL_SUB_DIRS := $(SUB_DIRS)
+MOD_LIST_NAME := PARIDE_MODULES
L_TARGET := paride.a
MX_OBJS :=
LX_OBJS :=
@@ -30,7 +31,7 @@ ifeq ($(CONFIG_PARIDE_PD),y)
LX_OBJS += pd.o
else
ifeq ($(CONFIG_PARIDE_PD),m)
- MX_OBJS += pd.o
+ M_OBJS += pd.o
endif
endif
@@ -38,7 +39,7 @@ ifeq ($(CONFIG_PARIDE_PCD),y)
LX_OBJS += pcd.o
else
ifeq ($(CONFIG_PARIDE_PCD),m)
- MX_OBJS += pcd.o
+ M_OBJS += pcd.o
endif
endif
@@ -46,7 +47,7 @@ ifeq ($(CONFIG_PARIDE_PF),y)
LX_OBJS += pf.o
else
ifeq ($(CONFIG_PARIDE_PF),m)
- MX_OBJS += pf.o
+ M_OBJS += pf.o
endif
endif
@@ -54,7 +55,7 @@ ifeq ($(CONFIG_PARIDE_PT),y)
LX_OBJS += pt.o
else
ifeq ($(CONFIG_PARIDE_PT),m)
- MX_OBJS += pt.o
+ M_OBJS += pt.o
endif
endif
@@ -62,7 +63,7 @@ ifeq ($(CONFIG_PARIDE_PG),y)
LX_OBJS += pg.o
else
ifeq ($(CONFIG_PARIDE_PG),m)
- MX_OBJS += pg.o
+ M_OBJS += pg.o
endif
endif
@@ -70,7 +71,7 @@ ifeq ($(CONFIG_PARIDE_ATEN),y)
LX_OBJS += aten.o
else
ifeq ($(CONFIG_PARIDE_ATEN),m)
- MX_OBJS += aten.o
+ M_OBJS += aten.o
endif
endif
@@ -78,7 +79,7 @@ ifeq ($(CONFIG_PARIDE_BPCK),y)
LX_OBJS += bpck.o
else
ifeq ($(CONFIG_PARIDE_BPCK),m)
- MX_OBJS += bpck.o
+ M_OBJS += bpck.o
endif
endif
@@ -86,7 +87,7 @@ ifeq ($(CONFIG_PARIDE_COMM),y)
LX_OBJS += comm.o
else
ifeq ($(CONFIG_PARIDE_COMM),m)
- MX_OBJS += comm.o
+ M_OBJS += comm.o
endif
endif
@@ -94,7 +95,7 @@ ifeq ($(CONFIG_PARIDE_DSTR),y)
LX_OBJS += dstr.o
else
ifeq ($(CONFIG_PARIDE_DSTR),m)
- MX_OBJS += dstr.o
+ M_OBJS += dstr.o
endif
endif
@@ -102,7 +103,7 @@ ifeq ($(CONFIG_PARIDE_KBIC),y)
LX_OBJS += kbic.o
else
ifeq ($(CONFIG_PARIDE_KBIC),m)
- MX_OBJS += kbic.o
+ M_OBJS += kbic.o
endif
endif
@@ -110,7 +111,7 @@ ifeq ($(CONFIG_PARIDE_EPAT),y)
LX_OBJS += epat.o
else
ifeq ($(CONFIG_PARIDE_EPAT),m)
- MX_OBJS += epat.o
+ M_OBJS += epat.o
endif
endif
@@ -118,7 +119,7 @@ ifeq ($(CONFIG_PARIDE_EPIA),y)
LX_OBJS += epia.o
else
ifeq ($(CONFIG_PARIDE_EPIA),m)
- MX_OBJS += epia.o
+ M_OBJS += epia.o
endif
endif
@@ -126,7 +127,7 @@ ifeq ($(CONFIG_PARIDE_FIT2),y)
LX_OBJS += fit2.o
else
ifeq ($(CONFIG_PARIDE_FIT2),m)
- MX_OBJS += fit2.o
+ M_OBJS += fit2.o
endif
endif
@@ -134,7 +135,7 @@ ifeq ($(CONFIG_PARIDE_FIT3),y)
LX_OBJS += fit3.o
else
ifeq ($(CONFIG_PARIDE_FIT3),m)
- MX_OBJS += fit3.o
+ M_OBJS += fit3.o
endif
endif
@@ -142,7 +143,7 @@ ifeq ($(CONFIG_PARIDE_FRPW),y)
LX_OBJS += frpw.o
else
ifeq ($(CONFIG_PARIDE_FRPW),m)
- MX_OBJS += frpw.o
+ M_OBJS += frpw.o
endif
endif
@@ -150,7 +151,7 @@ ifeq ($(CONFIG_PARIDE_ON20),y)
LX_OBJS += on20.o
else
ifeq ($(CONFIG_PARIDE_ON20),m)
- MX_OBJS += on20.o
+ M_OBJS += on20.o
endif
endif
@@ -158,7 +159,7 @@ ifeq ($(CONFIG_PARIDE_ON26),y)
LX_OBJS += on26.o
else
ifeq ($(CONFIG_PARIDE_ON26),m)
- MX_OBJS += on26.o
+ M_OBJS += on26.o
endif
endif
@@ -166,7 +167,7 @@ ifeq ($(CONFIG_PARIDE_KTTI),y)
LX_OBJS += ktti.o
else
ifeq ($(CONFIG_PARIDE_KTTI),m)
- MX_OBJS += ktti.o
+ M_OBJS += ktti.o
endif
endif
diff --git a/drivers/block/paride/bpck.c b/drivers/block/paride/bpck.c
index 4b241c737..05e2de2da 100644
--- a/drivers/block/paride/bpck.c
+++ b/drivers/block/paride/bpck.c
@@ -10,10 +10,11 @@
/* Changes:
1.01 GRG 1998.05.05 init_proto, release_proto, pi->delay
+ 1.02 GRG 1998.08.15 default pi->delay returned to 4
*/
-#define BPCK_VERSION "1.01"
+#define BPCK_VERSION "1.02"
#include <linux/module.h>
#include <linux/delay.h>
@@ -450,7 +451,7 @@ static void bpck_release_proto( PIA *pi)
{ MOD_DEC_USE_COUNT;
}
-struct pi_protocol bpck = { "bpck",0,5,2,1,256,
+struct pi_protocol bpck = { "bpck",0,5,2,4,256,
bpck_write_regr,
bpck_read_regr,
bpck_write_block,
diff --git a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c
index 805b69e19..068deffd6 100644
--- a/drivers/block/paride/paride.c
+++ b/drivers/block/paride/paride.c
@@ -11,10 +11,11 @@
1.01 GRG 1998.05.03 Use spinlocks
1.02 GRG 1998.05.05 init_proto, release_proto, ktti
+ 1.03 GRG 1998.08.15 eliminate compiler warning
*/
-#define PI_VERSION "1.02"
+#define PI_VERSION "1.03"
#include <linux/module.h>
#include <linux/config.h>
@@ -249,7 +250,7 @@ static void pi_register_parport( PIA *pi, int verbose)
if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port,pp->name);
- pi->parname = pp->name;
+ pi->parname = (char *)pp->name;
#endif
}
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index ecacacb3b..4a083abbf 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -2,11 +2,11 @@
pcd.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
Under the terms of the GNU public license.
- This is a high-level driver for parallel port ATAPI CDROM
+ This is a high-level driver for parallel port ATAPI CD-ROM
drives based on chips supported by the paride module.
By default, the driver will autoprobe for a single parallel
- port ATAPI CDROM drive, but if their individual parameters are
+ port ATAPI CD-ROM drive, but if their individual parameters are
specified, the driver can handle up to 4 drives.
The behaviour of the pcd driver can be altered by setting
@@ -38,7 +38,7 @@
of the mode numbers supported by the adapter.
(-1 if not given)
- <slv> ATAPI CDROMs can be jumpered to master or slave.
+ <slv> ATAPI CD-ROMs can be jumpered to master or slave.
Set this to 0 to choose the master drive, 1 to
choose the slave, -1 (the default) to choose the
first drive found.
@@ -61,10 +61,11 @@
(default "pcd")
verbose This parameter controls the amount of logging
- that is done while the driver probes for
- devices. Set it to 0 for a quiet load, or 1 to
- see all the progress messages. (default 0)
-
+ that the driver will do. Set it to 0 for
+ normal operation, 1 to see autoprobe progress
+ messages, or 2 to see additional debugging
+ output. (default 0)
+
nice This parameter controls the driver's use of
idle CPU time, at the expense of some speed.
@@ -85,16 +86,20 @@
/* Changes:
- 1.01 GRG 1997.01.24 Added test unit ready support
+ 1.01 GRG 1998.01.24 Added test unit ready support
1.02 GRG 1998.05.06 Changes to pcd_completion, ready_wait,
and loosen interpretation of ATAPI
standard for clearing error status.
Use spinlocks. Eliminate sti().
1.03 GRG 1998.06.16 Eliminated an Ugh
+ 1.04 GRG 1998.08.15 Added extra debugging, improvements to
+ pcd_completion, use HZ in loop timing
+ 1.05 GRG 1998.08.16 Conformed to "Uniform CD-ROM" standard
+ 1.06 GRG 1998.08.19 Added audio ioctl support
*/
-#define PCD_VERSION "1.03"
+#define PCD_VERSION "1.06"
#define PCD_MAJOR 46
#define PCD_NAME "pcd"
#define PCD_UNITS 4
@@ -185,9 +190,10 @@ MODULE_PARM(drive3,"1-6i");
#define PCD_RETRIES 5
#define PCD_TMO 800 /* timeout in jiffies */
#define PCD_DELAY 50 /* spin delay in uS */
-#define PCD_READY_TMO 20
+#define PCD_READY_TMO 20 /* in seconds */
+#define PCD_RESET_TMO 30 /* in tenths of a second */
-#define PCD_SPIN (10000/PCD_DELAY)*PCD_TMO
+#define PCD_SPIN (1000000*PCD_TMO)/(HZ*PCD_DELAY)
#define IDE_ERR 0x01
#define IDE_DRQ 0x08
@@ -197,33 +203,33 @@ MODULE_PARM(drive3,"1-6i");
int pcd_init(void);
void cleanup_module( void );
-static int pcd_open(struct inode *inode, struct file *file);
-static void do_pcd_request(void);
-static void do_pcd_read(void);
-static int pcd_ioctl(struct inode *inode,struct file *file,
- unsigned int cmd, unsigned long arg);
-
-static int pcd_release (struct inode *inode, struct file *file);
+static int pcd_open(struct cdrom_device_info *cdi, int purpose);
+static void pcd_release(struct cdrom_device_info *cdi);
+static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
+static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr);
+static int pcd_tray_move(struct cdrom_device_info *cdi, int position);
+static int pcd_lock_door(struct cdrom_device_info *cdi, int lock);
+static int pcd_drive_reset(struct cdrom_device_info *cdi);
+static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn);
+static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
+ unsigned int cmd, void *arg);
static int pcd_detect(void);
-static void pcd_lock(int unit);
-static void pcd_unlock(int unit);
-static void pcd_eject(int unit);
-static int pcd_check_media(int unit);
static void do_pcd_read_drq(void);
+static void do_pcd_request(void);
+static void do_pcd_read(void);
static int pcd_blocksizes[PCD_UNITS];
-#define PCD_NAMELEN 8
-
struct pcd_unit {
- struct pi_adapter pia; /* interface to paride layer */
+ struct pi_adapter pia; /* interface to paride layer */
struct pi_adapter *pi;
- int drive; /* master/slave */
- int last_sense; /* result of last request sense */
- int access; /* count of active opens */
- int present; /* does this unit exist ? */
- char name[PCD_NAMELEN]; /* pcd0, pcd1, etc */
+ int drive; /* master/slave */
+ int last_sense; /* result of last request sense */
+ int changed; /* media change seen */
+ int present; /* does this unit exist ? */
+ char *name; /* pcd0, pcd1, etc */
+ struct cdrom_device_info info; /* uniform cdrom interface */
};
struct pcd_unit pcd[PCD_UNITS];
@@ -251,22 +257,32 @@ static int pcd_sector; /* address of next requested sector */
static int pcd_count; /* number of blocks still to do */
static char * pcd_buf; /* buffer for request in progress */
+static int pcd_warned = 0; /* Have we logged a phase warning ? */
+
/* kernel glue structures */
-static struct file_operations pcd_fops = {
- NULL, /* lseek - default */
- block_read, /* read - general block-dev read */
- block_write, /* write - general block-dev write */
- NULL, /* readdir - bad */
- NULL, /* select */
- pcd_ioctl, /* ioctl */
- NULL, /* mmap */
- pcd_open, /* open */
- pcd_release, /* release */
- block_fsync, /* fsync */
- NULL, /* fasync */
- NULL, /* media change ? */
- NULL /* revalidate new media */
+static struct cdrom_device_ops pcd_dops = {
+ pcd_open,
+ pcd_release,
+ pcd_drive_status,
+ pcd_media_changed,
+ pcd_tray_move,
+ pcd_lock_door,
+ 0, /* select speed */
+ 0, /* select disk */
+ 0, /* get last session */
+ pcd_get_mcn,
+ pcd_drive_reset,
+ pcd_audio_ioctl,
+ 0, /* dev_ioctl */
+ CDC_CLOSE_TRAY |
+ CDC_OPEN_TRAY |
+ CDC_LOCK |
+ CDC_MCN |
+ CDC_MEDIA_CHANGED |
+ CDC_RESET |
+ CDC_PLAY_AUDIO,
+ 0
};
static void pcd_init_units( void )
@@ -276,21 +292,31 @@ static void pcd_init_units( void )
pcd_drive_count = 0;
for (unit=0;unit<PCD_UNITS;unit++) {
PCD.pi = & PCD.pia;
- PCD.access = 0;
PCD.present = 0;
PCD.last_sense = 0;
- j = 0;
- while ((j < PCD_NAMELEN-2) && (PCD.name[j]=name[j])) j++;
- PCD.name[j++] = '0' + unit;
- PCD.name[j] = 0;
+ PCD.changed = 1;
PCD.drive = DU[D_SLV];
if (DU[D_PRT]) pcd_drive_count++;
+
+ j = 0;
+ while ((j < (sizeof(PCD.info.name)-2)) &&
+ (PCD.info.name[j]=name[j])) j++;
+ PCD.info.name[j++] = '0' + unit;
+ PCD.info.name[j] = 0;
+ PCD.name = &PCD.info.name[0];
+
+ PCD.info.ops = &pcd_dops;
+ PCD.info.handle = NULL;
+ PCD.info.dev = MKDEV(major,unit);
+ PCD.info.speed = 0;
+ PCD.info.capacity = 1;
+ PCD.info.mask = 0;
}
}
int pcd_init (void) /* preliminary initialisation */
-{ int i;
+{ int i, unit;
if (disable) return -1;
@@ -298,10 +324,14 @@ int pcd_init (void) /* preliminary initialisation */
if (pcd_detect()) return -1;
- if (register_blkdev(MAJOR_NR,name,&pcd_fops)) {
+ if (register_blkdev(MAJOR_NR,name,&cdrom_fops)) {
printk("pcd: unable to get major number %d\n",MAJOR_NR);
return -1;
}
+
+ for (unit=0;unit<PCD_UNITS;unit++)
+ if (PCD.present) register_cdrom(&PCD.info);
+
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */
@@ -311,100 +341,20 @@ int pcd_init (void) /* preliminary initialisation */
return 0;
}
-static int pcd_open (struct inode *inode, struct file *file)
+static int pcd_open(struct cdrom_device_info *cdi, int purpose)
-{ int unit = DEVICE_NR(inode->i_rdev);
+{ int unit = DEVICE_NR(cdi->dev);
if ((unit >= PCD_UNITS) || (!PCD.present)) return -ENODEV;
- if (file->f_mode & 2) return -EROFS; /* wants to write ? */
-
MOD_INC_USE_COUNT;
- if (pcd_check_media(unit)) {
- MOD_DEC_USE_COUNT;
- return -ENXIO;
- }
-
- pcd_lock(unit);
-
- PCD.access++;
return 0;
}
-static void do_pcd_request (void)
-
-{ int unit;
-
- if (pcd_busy) return;
- while (1) {
- if ((!CURRENT) || (CURRENT->rq_status == RQ_INACTIVE)) return;
- INIT_REQUEST;
- if (CURRENT->cmd == READ) {
- unit = MINOR(CURRENT->rq_dev);
- if (unit != pcd_unit) {
- pcd_bufblk = -1;
- pcd_unit = unit;
- }
- pcd_sector = CURRENT->sector;
- pcd_count = CURRENT->nr_sectors;
- pcd_buf = CURRENT->buffer;
- pcd_busy = 1;
- ps_set_intr(do_pcd_read,0,0,nice);
- return;
- }
- else end_request(0);
- }
-}
-
-static int pcd_ioctl(struct inode *inode,struct file *file,
- unsigned int cmd, unsigned long arg)
-
-/* we currently support only the EJECT ioctl. */
-
-{ int unit = DEVICE_NR(inode->i_rdev);
- if ((unit >= PCD_UNITS) || (!PCD.present)) return -ENODEV;
-
- switch (cmd) {
- case CDROMEJECT: if (PCD.access == 1) {
- pcd_eject(unit);
- return 0;
- }
- default:
- return -EINVAL;
- }
-}
-
-static int pcd_release (struct inode *inode, struct file *file)
-
-{ kdev_t devp;
- int unit;
-
- struct super_block *sb;
-
- devp = inode->i_rdev;
- unit = DEVICE_NR(devp);
-
- if ((unit >= PCD_UNITS) || (PCD.access <= 0))
- return -EINVAL;
-
- PCD.access--;
-
- if (!PCD.access) {
- fsync_dev(devp);
-
- sb = get_super(devp);
- if (sb) invalidate_inodes(sb);
-
- invalidate_buffers(devp);
- pcd_unlock(unit);
-
- }
-
- MOD_DEC_USE_COUNT;
-
- return 0;
+static void pcd_release(struct cdrom_device_info *cdi)
+{ MOD_DEC_USE_COUNT;
}
#ifdef MODULE
@@ -423,11 +373,14 @@ int init_module(void)
void cleanup_module(void)
{ int unit;
-
- unregister_blkdev(MAJOR_NR,name);
for (unit=0;unit<PCD_UNITS;unit++)
- if (PCD.present) pi_release(PI);
+ if (PCD.present) {
+ pi_release(PI);
+ unregister_cdrom(&PCD.info);
+ }
+
+ unregister_blkdev(MAJOR_NR,name);
}
#endif
@@ -489,39 +442,68 @@ static int pcd_command( int unit, char * cmd, int dlen, char * fun )
static int pcd_completion( int unit, char * buf, char * fun )
-{ int r, s, n;
-
- r = pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,fun,"completion");
-
- if ((RR(0,2)&2) && (RR(0,7)&IDE_DRQ)) {
- n = (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
- pi_read_block(PI,buf,n);
+{ int r, d, p, n, k, j;
+
+ r = -1; k = 0; j = 0;
+
+ if (!pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,
+ fun,"completion")) {
+ r = 0;
+ while (RR(0,7)&IDE_DRQ) {
+ d = (RR(0,4)+256*RR(0,5));
+ n = ((d+3)&0xfffc);
+ p = RR(0,2)&3;
+
+ if ((p == 2) && (n > 0) && (j == 0)) {
+ pi_read_block(PI,buf,n);
+ if (verbose > 1)
+ printk("%s: %s: Read %d bytes\n",PCD.name,fun,n);
+ r = 0; j++;
+ } else {
+ if (verbose > 1)
+ printk("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
+ PCD.name,fun,p,d,k);
+ if ((verbose < 2) && !pcd_warned) {
+ pcd_warned = 1;
+ printk("%s: WARNING: ATAPI phase errors\n",PCD.name);
+ }
+ mdelay(1);
+ }
+ if (k++ > PCD_TMO) {
+ printk("%s: Stuck DRQ\n",PCD.name);
+ break;
+ }
+ if (pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,
+ fun,"completion")) {
+ r = -1;
+ break;
+ }
+ }
}
-
- s = pcd_wait(unit,IDE_BUSY,IDE_READY|IDE_ERR,fun,"data done");
-
+
pi_disconnect(PI);
- return (r?r:s);
+ return r;
}
-static void pcd_req_sense( int unit, int quiet )
+static void pcd_req_sense( int unit, char *fun )
{ char rs_cmd[12] = { 0x03,0,0,0,16,0,0,0,0,0,0,0 };
char buf[16];
- int r;
+ int r, c;
r = pcd_command(unit,rs_cmd,16,"Request sense");
mdelay(1);
if (!r) pcd_completion(unit,buf,"Request sense");
- PCD.last_sense = -1;
+ PCD.last_sense = -1; c = 2;
if (!r) {
- if (!quiet) printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
- PCD.name,buf[2]&0xf,buf[12],buf[13]);
- PCD.last_sense = (buf[2]&0xf) | ((buf[12]&0xff)<<8)
- | ((buf[13]&0xff)<<16) ;
+ if (fun) printk("%s: %s: Sense key: %x, ASC: %x, ASQ: %x\n",
+ PCD.name,fun,buf[2]&0xf,buf[12],buf[13]);
+ c = buf[2]&0xf;
+ PCD.last_sense = c | ((buf[12]&0xff)<<8) | ((buf[13]&0xff)<<16);
}
+ if ((c == 2) || (c == 6)) PCD.changed = 1;
}
static int pcd_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
@@ -531,45 +513,42 @@ static int pcd_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
r = pcd_command(unit,cmd,dlen,fun);
mdelay(1);
if (!r) r = pcd_completion(unit,buf,fun);
- if (r) pcd_req_sense(unit,!fun);
+ if (r) pcd_req_sense(unit,fun);
return r;
}
-#define DBMSG(msg) NULL
+#define DBMSG(msg) ((verbose>1)?(msg):NULL)
-static void pcd_lock(int unit)
+static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr)
-{ char lo_cmd[12] = { 0x1e,0,0,0,1,0,0,0,0,0,0,0 };
- char cl_cmd[12] = { 0x1b,0,0,0,3,0,0,0,0,0,0,0 };
+{ int r;
+ int unit = DEVICE_NR(cdi->dev);
- pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd1"));
- pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd2"));
- pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd3"));
- pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd4"));
- pcd_atapi(unit,cl_cmd,0,pcd_scratch,"close door");
+ r = PCD.changed;
+ PCD.changed = 0;
- pcd_atapi(unit,lo_cmd,0,pcd_scratch,DBMSG("ld"));
- pcd_atapi(unit,lo_cmd,0,pcd_scratch,"lock door");
+ return r;
}
-static void pcd_unlock( int unit )
+static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
-{ char un_cmd[12] = { 0x1e,0,0,0,0,0,0,0,0,0,0,0 };
+{ char un_cmd[12] = { 0x1e,0,0,0,lock,0,0,0,0,0,0,0 };
+ int unit = DEVICE_NR(cdi->dev);
- pcd_atapi(unit,un_cmd,0,pcd_scratch,"unlock door");
+ return pcd_atapi(unit,un_cmd,0,pcd_scratch,
+ lock?"lock door":"unlock door");
}
-static void pcd_eject( int unit)
+static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
-{ char ej_cmd[12] = { 0x1b,0,0,0,2,0,0,0,0,0,0,0 };
+{ char ej_cmd[12] = { 0x1b,0,0,0,3-position,0,0,0,0,0,0,0 };
+ int unit = DEVICE_NR(cdi->dev);
- pcd_unlock(unit);
- pcd_atapi(unit,ej_cmd,0,pcd_scratch,"eject");
+ return pcd_atapi(unit,ej_cmd,0,pcd_scratch,
+ position?"eject":"close tray");
}
-#define PCD_RESET_TMO 30 /* in tenths of a second */
-
static void pcd_sleep( int cs )
{ current->state = TASK_INTERRUPTIBLE;
@@ -579,11 +558,6 @@ static void pcd_sleep( int cs )
static int pcd_reset( int unit )
-/* the ATAPI standard actually specifies the contents of all 7 registers
- after a reset, but the specification is ambiguous concerning the last
- two bytes, and different drives interpret the standard differently.
-*/
-
{ int i, k, flg;
int expect[5] = {1,1,1,0x14,0xeb};
@@ -591,11 +565,11 @@ static int pcd_reset( int unit )
WR(0,6,0xa0 + 0x10*PCD.drive);
WR(0,7,8);
- pcd_sleep(2); /* delay a bit*/
+ pcd_sleep(2); /* delay a bit */
k = 0;
while ((k++ < PCD_RESET_TMO) && (RR(1,6)&IDE_BUSY))
- pcd_sleep(10);
+ pcd_sleep(HZ/10);
flg = 1;
for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
@@ -611,6 +585,11 @@ static int pcd_reset( int unit )
return flg-1;
}
+static int pcd_drive_reset(struct cdrom_device_info *cdi)
+
+{ return pcd_reset(DEVICE_NR(cdi->dev));
+}
+
static int pcd_ready_wait( int unit, int tmo )
{ char tr_cmd[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
@@ -629,12 +608,16 @@ static int pcd_ready_wait( int unit, int tmo )
return 0x000020; /* timeout */
}
-static int pcd_check_media( int unit )
+static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
{ char rc_cmd[12] = { 0x25,0,0,0,0,0,0,0,0,0,0,0};
+ int unit = DEVICE_NR(cdi->dev);
- pcd_ready_wait(unit,PCD_READY_TMO);
- return (pcd_atapi(unit,rc_cmd,8,pcd_scratch,DBMSG("check media")));
+ if (pcd_ready_wait(unit,PCD_READY_TMO))
+ return CDS_DRIVE_NOT_READY;
+ if (pcd_atapi(unit,rc_cmd,8,pcd_scratch,DBMSG("check media")))
+ return CDS_NO_DISC;
+ return CDS_DISC_OK;
}
static int pcd_identify( int unit, char * id )
@@ -648,7 +631,7 @@ static int pcd_identify( int unit, char * id )
if (s) return -1;
if ((pcd_buffer[0] & 0x1f) != 5) {
- if (verbose) printk("%s: %s is not a CDROM\n",
+ if (verbose) printk("%s: %s is not a CD-ROM\n",
PCD.name,PCD.drive?"Slave":"Master");
return -1;
}
@@ -709,12 +692,37 @@ static int pcd_detect( void )
if (k) return 0;
- printk("%s: No CDROM drive found\n",name);
+ printk("%s: No CD-ROM drive found\n",name);
return -1;
}
/* I/O request processing */
+static void do_pcd_request (void)
+
+{ int unit;
+
+ if (pcd_busy) return;
+ while (1) {
+ if ((!CURRENT) || (CURRENT->rq_status == RQ_INACTIVE)) return;
+ INIT_REQUEST;
+ if (CURRENT->cmd == READ) {
+ unit = MINOR(CURRENT->rq_dev);
+ if (unit != pcd_unit) {
+ pcd_bufblk = -1;
+ pcd_unit = unit;
+ }
+ pcd_sector = CURRENT->sector;
+ pcd_count = CURRENT->nr_sectors;
+ pcd_buf = CURRENT->buffer;
+ pcd_busy = 1;
+ ps_set_intr(do_pcd_read,0,0,nice);
+ return;
+ }
+ else end_request(0);
+ }
+}
+
static int pcd_ready( void )
{ int unit = pcd_unit;
@@ -793,7 +801,7 @@ static void do_pcd_read_drq( void )
if (pcd_completion(unit,pcd_buffer,"read block")) {
if (pcd_retries < PCD_RETRIES) {
- mdelay(1);
+ mdelay(1);
pcd_retries++;
pi_do_claimed(PI,pcd_start);
return;
@@ -812,6 +820,227 @@ static void do_pcd_read_drq( void )
do_pcd_request();
spin_unlock_irqrestore(&io_request_lock,saved_flags);
}
+
+/* the audio_ioctl stuff is adapted from sr_ioctl.c */
+
+static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
+ unsigned int cmd, void *arg)
+
+{ int unit = DEVICE_NR(cdi->dev);
+
+ switch (cmd) {
+
+ case CDROMPAUSE:
+
+ { char cmd[12]={SCMD_PAUSE_RESUME,0,0,0,0,0,0,0,0,0,0,0};
+
+ return (pcd_atapi(unit,cmd,0,NULL,"pause")) * EIO;
+ }
+
+ case CDROMRESUME:
+
+ { char cmd[12]={SCMD_PAUSE_RESUME,0,0,0,0,0,0,0,1,0,0,0};
+
+ return (pcd_atapi(unit,cmd,0,NULL,"resume")) * EIO;
+ }
+
+ case CDROMPLAYMSF:
+
+ { char cmd[12]={SCMD_PLAYAUDIO_MSF,0,0,0,0,0,0,0,0,0,0,0};
+ struct cdrom_msf* msf = (struct cdrom_msf*)arg;
+
+ cmd[3] = msf->cdmsf_min0;
+ cmd[4] = msf->cdmsf_sec0;
+ cmd[5] = msf->cdmsf_frame0;
+ cmd[6] = msf->cdmsf_min1;
+ cmd[7] = msf->cdmsf_sec1;
+ cmd[8] = msf->cdmsf_frame1;
+
+ return (pcd_atapi(unit,cmd,0,NULL,"play msf")) * EIO;
+ }
+
+ case CDROMPLAYBLK:
+
+ { char cmd[12]={SCMD_PLAYAUDIO10,0,0,0,0,0,0,0,0,0,0,0};
+ struct cdrom_blk* blk = (struct cdrom_blk*)arg;
+
+ cmd[2] = blk->from >> 24;
+ cmd[3] = blk->from >> 16;
+ cmd[4] = blk->from >> 8;
+ cmd[5] = blk->from;
+ cmd[7] = blk->len >> 8;
+ cmd[8] = blk->len;
+
+ return (pcd_atapi(unit,cmd,0,NULL,"play block")) * EIO;
+ }
+
+ case CDROMPLAYTRKIND:
+
+ { char cmd[12]={SCMD_PLAYAUDIO_TI,0,0,0,0,0,0,0,0,0,0,0};
+ struct cdrom_ti* ti = (struct cdrom_ti*)arg;
+
+ cmd[4] = ti->cdti_trk0;
+ cmd[5] = ti->cdti_ind0;
+ cmd[7] = ti->cdti_trk1;
+ cmd[8] = ti->cdti_ind1;
+
+ return (pcd_atapi(unit,cmd,0,NULL,"play track")) * EIO;
+ }
+
+ case CDROMREADTOCHDR:
+
+ { char cmd[12]={SCMD_READ_TOC,0,0,0,0,0,0,0,12,0,0,0};
+ struct cdrom_tochdr* tochdr = (struct cdrom_tochdr*)arg;
+ char buffer[32];
+ int r;
+
+ r = pcd_atapi(unit,cmd,12,buffer,"read toc header");
+
+ tochdr->cdth_trk0 = buffer[2];
+ tochdr->cdth_trk1 = buffer[3];
+
+ return r * EIO;
+ }
+
+ case CDROMREADTOCENTRY:
+
+ { char cmd[12]={SCMD_READ_TOC,0,0,0,0,0,0,0,12,0,0,0};
+
+ struct cdrom_tocentry* tocentry = (struct cdrom_tocentry*)arg;
+ unsigned char buffer[32];
+ int r;
+
+ cmd[1] = (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
+ cmd[6] = tocentry->cdte_track;
+
+ r = pcd_atapi(unit,cmd,12,buffer,"read toc entry");
+
+ tocentry->cdte_ctrl = buffer[5] & 0xf;
+ tocentry->cdte_adr = buffer[5] >> 4;
+ tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04)?1:0;
+ if (tocentry->cdte_format == CDROM_MSF) {
+ tocentry->cdte_addr.msf.minute = buffer[9];
+ tocentry->cdte_addr.msf.second = buffer[10];
+ tocentry->cdte_addr.msf.frame = buffer[11];
+ } else
+ tocentry->cdte_addr.lba =
+ (((((buffer[8] << 8) + buffer[9]) << 8)
+ + buffer[10]) << 8) + buffer[11];
+
+ return r * EIO;
+ }
+
+ case CDROMSTOP:
+
+ { char cmd[12]={0x1b,1,0,0,0,0,0,0,0,0,0,0};
+
+ return (pcd_atapi(unit,cmd,0,NULL,"stop")) * EIO;
+ }
+
+ case CDROMSTART:
+
+ { char cmd[12]={0x1b,1,0,0,1,0,0,0,0,0,0,0};
+
+ return (pcd_atapi(unit,cmd,0,NULL,"start")) * EIO;
+ }
+
+ case CDROMVOLCTRL:
+
+ { char cmd[12]={0x5a,0,0,0,0,0,0,0,0,0,0,0};
+ char buffer[32];
+ char mask[32];
+ struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+
+ cmd[2] = 0xe;
+ cmd[4] = 28;
+
+ if (pcd_atapi(unit,cmd,28,buffer,"mode sense vol"))
+ return -EIO;
+
+ cmd[2] = 0x4e;
+
+ if (pcd_atapi(unit,cmd,28,buffer,"mode sense vol mask"))
+ return -EIO;
+
+ buffer[0] = 0;
+
+ buffer[21] = volctrl->channel0 & mask[21];
+ buffer[23] = volctrl->channel1 & mask[23];
+ buffer[25] = volctrl->channel2 & mask[25];
+ buffer[27] = volctrl->channel3 & mask[27];
+
+ cmd[0] = 0x55;
+ cmd[1] = 0x10;
+
+ return pcd_atapi(unit,cmd,28,buffer,"mode select vol") * EIO;
+ }
+
+ case CDROMVOLREAD:
+
+ { char cmd[12]={0x5a,0,0,0,0,0,0,0,0,0,0,0};
+ char buffer[32];
+ struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+ int r;
+
+ cmd[2] = 0xe;
+ cmd[4] = 28;
+
+ r = pcd_atapi(unit,cmd,28,buffer,"mode sense vol read");
+
+ volctrl->channel0 = buffer[21];
+ volctrl->channel1 = buffer[23];
+ volctrl->channel2 = buffer[25];
+ volctrl->channel3 = buffer[27];
+
+ return r * EIO;
+ }
+
+
+ case CDROMSUBCHNL:
+
+ { char cmd[12]={SCMD_READ_SUBCHANNEL,2,0x40,1,0,0,0,0,16,0,0,0};
+ struct cdrom_subchnl* subchnl = (struct cdrom_subchnl*)arg;
+ char buffer[32];
+
+ if (pcd_atapi(unit,cmd,16,buffer,"read subchannel"))
+ return -EIO;
+
+ subchnl->cdsc_audiostatus = buffer[1];
+ subchnl->cdsc_format = CDROM_MSF;
+ subchnl->cdsc_ctrl = buffer[5] & 0xf;
+ subchnl->cdsc_trk = buffer[6];
+ subchnl->cdsc_ind = buffer[7];
+
+ subchnl->cdsc_reladdr.msf.minute = buffer[13];
+ subchnl->cdsc_reladdr.msf.second = buffer[14];
+ subchnl->cdsc_reladdr.msf.frame = buffer[15];
+ subchnl->cdsc_absaddr.msf.minute = buffer[9];
+ subchnl->cdsc_absaddr.msf.second = buffer[10];
+ subchnl->cdsc_absaddr.msf.frame = buffer[11];
+
+ return 0;
+ }
+
+ default:
+
+ return -ENOSYS;
+ }
+}
+static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
+
+{ char cmd[12]={SCMD_READ_SUBCHANNEL,0,0x40,2,0,0,0,0,24,0,0,0};
+ char buffer[32];
+ int k;
+ int unit = DEVICE_NR(cdi->dev);
+
+ if (pcd_atapi(unit,cmd,24,buffer,"get mcn")) return -EIO;
+
+ for (k=0;k<13;k++) mcn->medium_catalog_number[k] = buffer[k+9];
+ mcn->medium_catalog_number[13] = 0;
+
+ return 0;
+}
+
/* end of pcd.c */
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 3be1de32c..69274fe48 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -78,9 +78,10 @@
(default 64)
verbose This parameter controls the amount of logging
- that is done while the driver probes for
- devices. Set it to 0 for a quiet load, or to 1
- see all the progress messages. (default 0)
+ that the driver will do. Set it to 0 for
+ normal operation, 1 to see autoprobe progress
+ messages, or 2 to see additional debugging
+ output. (default 0)
nice This parameter controls the driver's use of
idle CPU time, at the expense of some speed.
@@ -108,10 +109,11 @@
1.02 GRG 1998.05.06 SMP spinlock changes,
Added slave support
1.03 GRG 1998.06.16 Eliminate an Ugh.
+ 1.04 GRG 1998.08.15 Extra debugging, use HZ in loop timing
*/
-#define PD_VERSION "1.03"
+#define PD_VERSION "1.04"
#define PD_MAJOR 45
#define PD_NAME "pd"
#define PD_UNITS 4
@@ -223,7 +225,7 @@ MODULE_PARM(drive3,"1-8i");
#define PD_TMO 800 /* interrupt timeout in jiffies */
#define PD_SPIN_DEL 50 /* spin delay in micro-seconds */
-#define PD_SPIN (10000/PD_SPIN_DEL)*PD_TMO
+#define PD_SPIN (1000000*PD_TMO)/(HZ*PD_SPIN_DEL)
#define STAT_ERR 0x00001
#define STAT_INDEX 0x00002
@@ -359,6 +361,7 @@ static struct file_operations pd_fops = {
pd_ioctl, /* ioctl */
NULL, /* mmap */
pd_open, /* open */
+ NULL, /* flush */
pd_release, /* release */
block_fsync, /* fsync */
NULL, /* fasync */
@@ -666,7 +669,7 @@ static void pd_reset( int unit ) /* called only for MASTER drive */
udelay(250);
}
-#define DBMSG(msg) NULL
+#define DBMSG(msg) ((verbose>1)?(msg):NULL)
static int pd_wait_for( int unit, int w, char * msg ) /* polled wait */
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index a176c45d3..a2f1f1da9 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -76,10 +76,11 @@
(default 64)
verbose This parameter controls the amount of logging
- that is done while the driver probes for
- devices. Set it to 0 for a quiet load, or 1 to
- see all the progress messages. (default 0)
-
+ that the driver will do. Set it to 0 for
+ normal operation, 1 to see autoprobe progress
+ messages, or 2 to see additional debugging
+ output. (default 0)
+
nice This parameter controls the driver's use of
idle CPU time, at the expense of some speed.
@@ -107,10 +108,11 @@
Small change in pf_completion to round
up transfer size.
1.02 GRG 1998.06.16 Eliminated an Ugh
+ 1.03 GRG 1998.08.16 Use HZ in loop timings, extra debugging
*/
-#define PF_VERSION "1.02"
+#define PF_VERSION "1.03"
#define PF_MAJOR 47
#define PF_NAME "pf"
#define PF_UNITS 4
@@ -217,7 +219,7 @@ MODULE_PARM(drive3,"1-7i");
#define PF_TMO 800 /* interrupt timeout in jiffies */
#define PF_SPIN_DEL 50 /* spin delay in micro-seconds */
-#define PF_SPIN (10000/PF_SPIN_DEL)*PF_TMO
+#define PF_SPIN (1000000*PF_TMO)/(HZ*PF_SPIN_DEL)
#define STAT_ERR 0x00001
#define STAT_INDEX 0x00002
@@ -316,6 +318,7 @@ static struct file_operations pf_fops = {
pf_ioctl, /* ioctl */
NULL, /* mmap */
pf_open, /* open */
+ NULL, /* flush */
pf_release, /* release */
block_fsync, /* fsync */
NULL, /* fasync */
@@ -627,7 +630,7 @@ static int pf_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
return r;
}
-#define DBMSG(msg) NULL
+#define DBMSG(msg) ((verbose>1)?(msg):NULL)
static void pf_lock(int unit, int func)
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index 816b44ede..fd001008d 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -1,35 +1,35 @@
/*
- pg.c (c) 1998 Grant R. Guenther <grant@torque.net>
- Under the terms of the GNU public license.
+ pg.c (c) 1998 Grant R. Guenther <grant@torque.net>
+ Under the terms of the GNU public license.
The pg driver provides a simple character device interface for
- sending ATAPI commands to a device. With the exception of the
+ sending ATAPI commands to a device. With the exception of the
ATAPI reset operation, all operations are performed by a pair
- of read and write operations to the appropriate /dev/pgN device.
+ of read and write operations to the appropriate /dev/pgN device.
A write operation delivers a command and any outbound data in
- a single buffer. Normally, the write will succeed unless the
- device is offline or malfunctioning, or there is already another
+ a single buffer. Normally, the write will succeed unless the
+ device is offline or malfunctioning, or there is already another
command pending. If the write succeeds, it should be followed
- immediately by a read operation, to obtain any returned data and
- status information. A read will fail if there is no operation
- in progress.
+ immediately by a read operation, to obtain any returned data and
+ status information. A read will fail if there is no operation
+ in progress.
As a special case, the device can be reset with a write operation,
- and in this case, no following read is expected, or permitted.
+ and in this case, no following read is expected, or permitted.
There are no ioctl() operations. Any single operation
may transfer at most PG_MAX_DATA bytes. Note that the driver must
- copy the data through an internal buffer. In keeping with all
+ copy the data through an internal buffer. In keeping with all
current ATAPI devices, command packets are assumed to be exactly
12 bytes in length.
To permit future changes to this interface, the headers in the
read and write buffers contain a single character "magic" flag.
- Currently this flag must be the character "P".
+ Currently this flag must be the character "P".
- By default, the driver will autoprobe for a single parallel
- port ATAPI device, but if their individual parameters are
- specified, the driver can handle up to 4 devices.
+ By default, the driver will autoprobe for a single parallel
+ port ATAPI device, but if their individual parameters are
+ specified, the driver can handle up to 4 devices.
To use this device, you must have the following device
special files defined:
@@ -41,48 +41,48 @@
(You'll need to change the 97 to something else if you use
the 'major' parameter to install the driver on a different
- major number.)
+ major number.)
- The behaviour of the pg driver can be altered by setting
- some parameters from the insmod command line. The following
- parameters are adjustable:
+ The behaviour of the pg driver can be altered by setting
+ some parameters from the insmod command line. The following
+ parameters are adjustable:
- drive0 These four arguments can be arrays of
- drive1 1-6 integers as follows:
- drive2
- drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
+ drive0 These four arguments can be arrays of
+ drive1 1-6 integers as follows:
+ drive2
+ drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
- Where,
+ Where,
- <prt> is the base of the parallel port address for
- the corresponding drive. (required)
+ <prt> is the base of the parallel port address for
+ the corresponding drive. (required)
- <pro> is the protocol number for the adapter that
- supports this drive. These numbers are
- logged by 'paride' when the protocol modules
- are initialised. (0 if not given)
+ <pro> is the protocol number for the adapter that
+ supports this drive. These numbers are
+ logged by 'paride' when the protocol modules
+ are initialised. (0 if not given)
- <uni> for those adapters that support chained
- devices, this is the unit selector for the
- chain of devices on the given port. It should
- be zero for devices that don't support chaining.
- (0 if not given)
+ <uni> for those adapters that support chained
+ devices, this is the unit selector for the
+ chain of devices on the given port. It should
+ be zero for devices that don't support chaining.
+ (0 if not given)
- <mod> this can be -1 to choose the best mode, or one
- of the mode numbers supported by the adapter.
- (-1 if not given)
+ <mod> this can be -1 to choose the best mode, or one
+ of the mode numbers supported by the adapter.
+ (-1 if not given)
- <slv> ATAPI devices can be jumpered to master or slave.
- Set this to 0 to choose the master drive, 1 to
- choose the slave, -1 (the default) to choose the
- first drive found.
+ <slv> ATAPI devices can be jumpered to master or slave.
+ Set this to 0 to choose the master drive, 1 to
+ choose the slave, -1 (the default) to choose the
+ first drive found.
- <dly> some parallel ports require the driver to
- go more slowly. -1 sets a default value that
- should work with the chosen protocol. Otherwise,
- set this to a small integer, the larger it is
- the slower the port i/o. In some cases, setting
- this to zero will speed up the device. (default -1)
+ <dly> some parallel ports require the driver to
+ go more slowly. -1 sets a default value that
+ should work with the chosen protocol. Otherwise,
+ set this to a small integer, the larger it is
+ the slower the port i/o. In some cases, setting
+ this to zero will speed up the device. (default -1)
major You may use this parameter to overide the
default major number (97) that this driver
@@ -94,23 +94,23 @@
device (in /proc output, for instance).
(default "pg").
- verbose This parameter controls the amount of logging
- that is done by the driver. Set it to 0 for
+ verbose This parameter controls the amount of logging
+ that is done by the driver. Set it to 0 for
quiet operation, to 1 to enable progress
messages while the driver probes for devices,
or to 2 for full debug logging. (default 0)
- If this driver is built into the kernel, you can use
- the following command line parameters, with the same values
- as the corresponding module parameters listed above:
+ If this driver is built into the kernel, you can use
+ the following command line parameters, with the same values
+ as the corresponding module parameters listed above:
- pg.drive0
- pg.drive1
- pg.drive2
- pg.drive3
+ pg.drive0
+ pg.drive1
+ pg.drive2
+ pg.drive3
- In addition, you can use the parameter pg.disable to disable
- the driver entirely.
+ In addition, you can use the parameter pg.disable to disable
+ the driver entirely.
*/
@@ -175,9 +175,9 @@ static int pg_drive_count;
#include "setup.h"
static STT pg_stt[5] = {{"drive0",6,drive0},
- {"drive1",6,drive1},
- {"drive2",6,drive2},
- {"drive3",6,drive3},
+ {"drive1",6,drive1},
+ {"drive2",6,drive2},
+ {"drive3",6,drive3},
{"disable",1,&disable}};
void pg_setup( char *str, int *ints)
@@ -221,9 +221,9 @@ void cleanup_module( void );
static int pg_open(struct inode *inode, struct file *file);
static int pg_release (struct inode *inode, struct file *file);
static ssize_t pg_read(struct file * filp, char * buf,
- size_t count, loff_t *ppos);
+ size_t count, loff_t *ppos);
static ssize_t pg_write(struct file * filp, const char * buf,
- size_t count, loff_t *ppos);
+ size_t count, loff_t *ppos);
static int pg_detect(void);
static int pg_identify (int unit, int log);
@@ -257,39 +257,40 @@ static char pg_scratch[512]; /* scratch block buffer */
/* kernel glue structures */
static struct file_operations pg_fops = {
- NULL, /* lseek - default */
- pg_read, /* read */
- pg_write, /* write */
- NULL, /* readdir - bad */
- NULL, /* select */
- NULL, /* ioctl */
- NULL, /* mmap */
- pg_open, /* open */
- pg_release, /* release */
- NULL, /* fsync */
- NULL, /* fasync */
- NULL, /* media change ? */
- NULL /* revalidate new media */
+ NULL, /* lseek - default */
+ pg_read, /* read */
+ pg_write, /* write */
+ NULL, /* readdir - bad */
+ NULL, /* select */
+ NULL, /* ioctl */
+ NULL, /* mmap */
+ pg_open, /* open */
+ NULL, /* flush */
+ pg_release, /* release */
+ NULL, /* fsync */
+ NULL, /* fasync */
+ NULL, /* media change ? */
+ NULL /* revalidate new media */
};
void pg_init_units( void )
{ int unit, j;
- pg_drive_count = 0;
- for (unit=0;unit<PG_UNITS;unit++) {
- PG.pi = & PG.pia;
- PG.access = 0;
- PG.busy = 0;
- PG.present = 0;
+ pg_drive_count = 0;
+ for (unit=0;unit<PG_UNITS;unit++) {
+ PG.pi = & PG.pia;
+ PG.access = 0;
+ PG.busy = 0;
+ PG.present = 0;
PG.bufptr = NULL;
PG.drive = DU[D_SLV];
- j = 0;
- while ((j < PG_NAMELEN-2) && (PG.name[j]=name[j])) j++;
- PG.name[j++] = '0' + unit;
- PG.name[j] = 0;
- if (DU[D_PRT]) pg_drive_count++;
- }
+ j = 0;
+ while ((j < PG_NAMELEN-2) && (PG.name[j]=name[j])) j++;
+ PG.name[j++] = '0' + unit;
+ PG.name[j] = 0;
+ if (DU[D_PRT]) pg_drive_count++;
+ }
}
int pg_init (void) /* preliminary initialisation */
@@ -302,15 +303,15 @@ int pg_init (void) /* preliminary initialisation */
if (pg_detect()) return -1;
- if (register_chrdev(major,name,&pg_fops)) {
- printk("pg_init: unable to get major number %d\n",
- major);
- for (unit=0;unit<PG_UNITS;unit++)
- if (PG.present) pi_release(PI);
- return -1;
- }
+ if (register_chrdev(major,name,&pg_fops)) {
+ printk("pg_init: unable to get major number %d\n",
+ major);
+ for (unit=0;unit<PG_UNITS;unit++)
+ if (PG.present) pi_release(PI);
+ return -1;
+ }
- return 0;
+ return 0;
}
#ifdef MODULE
@@ -323,16 +324,16 @@ int init_module(void)
{ int err;
- err = pg_init();
+ err = pg_init();
- return err;
+ return err;
}
void cleanup_module(void)
{ int unit;
- unregister_chrdev(major,name);
+ unregister_chrdev(major,name);
for (unit=0;unit<PG_UNITS;unit++)
if (PG.present) pi_release(PI);
@@ -348,8 +349,8 @@ void cleanup_module(void)
static void pg_sleep( int cs )
{ current->state = TASK_INTERRUPTIBLE;
- current->timeout = jiffies + cs;
- schedule();
+ current->timeout = jiffies + cs;
+ schedule();
}
static int pg_wait( int unit, int go, int stop, int tmo, char * msg )
@@ -358,26 +359,26 @@ static int pg_wait( int unit, int go, int stop, int tmo, char * msg )
PG.status = 0;
- j = 0;
- while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(jiffies<tmo)) {
- if (j++ < PG_SPIN) udelay(PG_SPIN_DEL);
+ j = 0;
+ while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(jiffies<tmo)) {
+ if (j++ < PG_SPIN) udelay(PG_SPIN_DEL);
else pg_sleep(1);
}
- if ((r&(STAT_ERR&stop))||(jiffies>=tmo)) {
- s = RR(0,7);
- e = RR(0,1);
- p = RR(0,2);
- if (verbose > 1)
+ if ((r&(STAT_ERR&stop))||(jiffies>=tmo)) {
+ s = RR(0,7);
+ e = RR(0,1);
+ p = RR(0,2);
+ if (verbose > 1)
printk("%s: %s: stat=0x%x err=0x%x phase=%d%s\n",
- PG.name,msg,s,e,p,(jiffies>=tmo)?" timeout":"");
+ PG.name,msg,s,e,p,(jiffies>=tmo)?" timeout":"");
- if (jiffies>=tmo) e |= 0x100;
+ if (jiffies>=tmo) e |= 0x100;
PG.status = (e >> 4) & 0xff;
- return -1;
- }
- return 0;
+ return -1;
+ }
+ return 0;
}
static int pg_command( int unit, char * cmd, int dlen, int tmo )
@@ -386,64 +387,64 @@ static int pg_command( int unit, char * cmd, int dlen, int tmo )
pi_connect(PI);
- WR(0,6,DRIVE);
+ WR(0,6,DRIVE);
- if (pg_wait(unit,STAT_BUSY|STAT_DRQ,0,tmo,"before command")) {
- pi_disconnect(PI);
- return -1;
- }
+ if (pg_wait(unit,STAT_BUSY|STAT_DRQ,0,tmo,"before command")) {
+ pi_disconnect(PI);
+ return -1;
+ }
- WR(0,4,dlen % 256);
- WR(0,5,dlen / 256);
- WR(0,7,0xa0); /* ATAPI packet command */
+ WR(0,4,dlen % 256);
+ WR(0,5,dlen / 256);
+ WR(0,7,0xa0); /* ATAPI packet command */
- if (pg_wait(unit,STAT_BUSY,STAT_DRQ,tmo,"command DRQ")) {
- pi_disconnect(PI);
- return -1;
- }
+ if (pg_wait(unit,STAT_BUSY,STAT_DRQ,tmo,"command DRQ")) {
+ pi_disconnect(PI);
+ return -1;
+ }
- if (RR(0,2) != 1) {
- printk("%s: command phase error\n",PG.name);
- pi_disconnect(PI);
- return -1;
- }
+ if (RR(0,2) != 1) {
+ printk("%s: command phase error\n",PG.name);
+ pi_disconnect(PI);
+ return -1;
+ }
- pi_write_block(PI,cmd,12);
+ pi_write_block(PI,cmd,12);
if (verbose > 1) {
printk("%s: Command sent, dlen=%d packet= ", PG.name,dlen);
for (k=0;k<12;k++) printk("%02x ",cmd[k]&0xff);
printk("\n");
}
- return 0;
+ return 0;
}
static int pg_completion( int unit, char * buf, int tmo)
{ int r, d, n, p;
- r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
+ r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
tmo,"completion");
PG.dlen = 0;
- while (RR(0,7)&STAT_DRQ) {
- d = (RR(0,4)+256*RR(0,5));
- n = ((d+3)&0xfffc);
+ while (RR(0,7)&STAT_DRQ) {
+ d = (RR(0,4)+256*RR(0,5));
+ n = ((d+3)&0xfffc);
p = RR(0,2)&3;
if (p == 0) pi_write_block(PI,buf,n);
if (p == 2) pi_read_block(PI,buf,n);
if (verbose > 1) printk("%s: %s %d bytes\n",PG.name,
p?"Read":"Write",n);
- PG.dlen += (1-p)*d;
- buf += d;
- r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
- tmo,"completion");
- }
+ PG.dlen += (1-p)*d;
+ buf += d;
+ r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
+ tmo,"completion");
+ }
- pi_disconnect(PI);
+ pi_disconnect(PI);
- return r;
+ return r;
}
static int pg_reset( int unit )
@@ -457,9 +458,9 @@ static int pg_reset( int unit )
pg_sleep(2);
- k = 0;
- while ((k++ < PG_RESET_TMO) && (RR(1,6)&STAT_BUSY))
- pg_sleep(1);
+ k = 0;
+ while ((k++ < PG_RESET_TMO) && (RR(1,6)&STAT_BUSY))
+ pg_sleep(1);
flg = 1;
for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
@@ -494,7 +495,7 @@ static int pg_identify( int unit, int log )
char id_cmd[12] = { ATAPI_IDENTIFY,0,0,0,36,0,0,0,0,0,0,0};
char buf[36];
- s = pg_command(unit,id_cmd,36,jiffies+PG_TMO);
+ s = pg_command(unit,id_cmd,36,jiffies+PG_TMO);
if (s) return -1;
s = pg_completion(unit,buf,jiffies+PG_TMO);
if (s) return -1;
@@ -502,7 +503,7 @@ static int pg_identify( int unit, int log )
if (log) {
xs(buf,mf,8,8);
xs(buf,id,16,16);
- printk("%s: %s %s, %s\n",PG.name,mf,id,ms[PG.drive]);
+ printk("%s: %s %s, %s\n",PG.name,mf,id,ms[PG.drive]);
}
return 0;
@@ -511,7 +512,7 @@ static int pg_identify( int unit, int log )
static int pg_probe( int unit )
/* returns 0, with id set if drive is detected
- -1, if drive detection failed
+ -1, if drive detection failed
*/
{ if (PG.drive == -1) {
@@ -520,7 +521,7 @@ static int pg_probe( int unit )
} else {
if (!pg_reset(unit)) return pg_identify(unit,1);
}
- return -1;
+ return -1;
}
static int pg_detect( void )
@@ -534,22 +535,22 @@ static int pg_detect( void )
if (pg_drive_count == 0) {
unit = 0;
if (pi_init(PI,1,-1,-1,-1,-1,-1,pg_scratch,
- PI_PG,verbose,PG.name)) {
- if (!pg_probe(unit)) {
+ PI_PG,verbose,PG.name)) {
+ if (!pg_probe(unit)) {
PG.present = 1;
k++;
- } else pi_release(PI);
+ } else pi_release(PI);
}
} else for (unit=0;unit<PG_UNITS;unit++) if (DU[D_PRT])
if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
DU[D_PRO],DU[D_DLY],pg_scratch,PI_PG,verbose,
PG.name)) {
- if (!pg_probe(unit)) {
- PG.present = 1;
- k++;
- } else pi_release(PI);
- }
+ if (!pg_probe(unit)) {
+ PG.present = 1;
+ k++;
+ } else pi_release(PI);
+ }
if (k) return 0;
@@ -563,16 +564,16 @@ static int pg_open (struct inode *inode, struct file *file)
{ int unit = DEVICE_NR(inode->i_rdev);
- if ((unit >= PG_UNITS) || (!PG.present)) return -ENODEV;
+ if ((unit >= PG_UNITS) || (!PG.present)) return -ENODEV;
- PG.access++;
+ PG.access++;
if (PG.access > 1) {
PG.access--;
return -EBUSY;
}
- MOD_INC_USE_COUNT;
+ MOD_INC_USE_COUNT;
if (PG.busy) {
pg_reset(unit);
@@ -590,34 +591,34 @@ static int pg_open (struct inode *inode, struct file *file)
return -ENOMEM;
}
- return 0;
+ return 0;
}
static int pg_release (struct inode *inode, struct file *file)
{
- int unit = DEVICE_NR(inode->i_rdev);
+ int unit = DEVICE_NR(inode->i_rdev);
- if ((unit >= PG_UNITS) || (PG.access <= 0))
- return -EINVAL;
+ if ((unit >= PG_UNITS) || (PG.access <= 0))
+ return -EINVAL;
PG.access--;
kfree(PG.bufptr);
PG.bufptr = NULL;
- MOD_DEC_USE_COUNT;
+ MOD_DEC_USE_COUNT;
return 0;
}
static ssize_t pg_write(struct file * filp, const char * buf,
- size_t count, loff_t *ppos)
+ size_t count, loff_t *ppos)
{ struct inode *ino = filp->f_dentry->d_inode;
- int unit = DEVICE_NR(ino->i_rdev);
- struct pg_write_hdr hdr;
- int hs = sizeof(hdr);
+ int unit = DEVICE_NR(ino->i_rdev);
+ struct pg_write_hdr hdr;
+ int hs = sizeof(hdr);
if (PG.busy) return -EBUSY;
if (count < hs) return -EINVAL;
@@ -652,7 +653,7 @@ static ssize_t pg_write(struct file * filp, const char * buf,
}
static ssize_t pg_read(struct file * filp, char * buf,
- size_t count, loff_t *ppos)
+ size_t count, loff_t *ppos)
{ struct inode *ino = filp->f_dentry->d_inode;
int unit = DEVICE_NR(ino->i_rdev);
@@ -673,7 +674,7 @@ static ssize_t pg_read(struct file * filp, char * buf,
copy = 0;
if (hdr.dlen < 0) {
- hdr.dlen = -1 * hdr.dlen;
+ hdr.dlen = -1 * hdr.dlen;
copy = hdr.dlen;
if (copy > (count - hs)) copy = count - hs;
}
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index de77c1b5a..44c4dadfb 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -72,10 +72,11 @@
(default "pt").
verbose This parameter controls the amount of logging
- that is done while the driver probes for
- devices. Set it to 0 for a quiet load, or 1 to
- see all the progress messages. (default 0)
-
+ that the driver will do. Set it to 0 for
+ normal operation, 1 to see autoprobe progress
+ messages, or 2 to see additional debugging
+ output. (default 0)
+
If this driver is built into the kernel, you can use
the following command line parameters, with the same values
as the corresponding module parameters listed above:
@@ -97,10 +98,12 @@
for clearing error status.
Eliminate sti();
1.02 GRG 1998.06.16 Eliminate an Ugh.
+ 1.03 GRG 1998.08.15 Adjusted PT_TMO, use HZ in loop timing,
+ extra debugging
*/
-#define PT_VERSION "1.02"
+#define PT_VERSION "1.03"
#define PT_MAJOR 96
#define PT_NAME "pt"
#define PT_UNITS 4
@@ -174,13 +177,13 @@ MODULE_PARM(drive3,"1-6i");
#include "paride.h"
#define PT_MAX_RETRIES 5
-#define PT_TMO 800 /* interrupt timeout in jiffies */
+#define PT_TMO 3000 /* interrupt timeout in jiffies */
#define PT_SPIN_DEL 50 /* spin delay in micro-seconds */
-#define PT_RESET_TMO 30 /* 3 seconds */
+#define PT_RESET_TMO 30 /* 30 seconds */
#define PT_READY_TMO 60 /* 60 seconds */
#define PT_REWIND_TMO 1200 /* 20 minutes */
-#define PT_SPIN (10000/PT_SPIN_DEL)*PT_TMO
+#define PT_SPIN ((1000000/(HZ*PT_SPIN_DEL))*PT_TMO)
#define STAT_ERR 0x00001
#define STAT_INDEX 0x00002
@@ -265,6 +268,7 @@ static struct file_operations pt_fops = {
pt_ioctl, /* ioctl */
NULL, /* mmap */
pt_open, /* open */
+ NULL, /* flush */
pt_release, /* release */
NULL, /* fsync */
NULL, /* fasync */
@@ -505,7 +509,7 @@ static void pt_write_fm( int unit )
pt_media_access_cmd(unit,PT_TMO,wm_cmd,"write filemark");
}
-#define DBMSG(msg) NULL
+#define DBMSG(msg) ((verbose>1)?(msg):NULL)
static int pt_reset( int unit )
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
index bef50bd36..e56616a77 100644
--- a/drivers/block/ps2esdi.c
+++ b/drivers/block/ps2esdi.c
@@ -157,6 +157,7 @@ static struct file_operations ps2esdi_fops =
ps2esdi_ioctl, /* ioctl */
NULL, /* mmap */
ps2esdi_open, /* open */
+ NULL, /* flush */
ps2esdi_release, /* release */
block_fsync /* fsync */
};
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 822e3ec18..dd1933a47 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -223,6 +223,7 @@ static struct file_operations initrd_fops = {
NULL, /* ioctl */
NULL, /* mmap */
NULL, /* open */
+ NULL, /* flush */
initrd_release, /* release */
NULL /* fsync */
};
@@ -249,13 +250,11 @@ static int rd_open(struct inode * inode, struct file * filp)
return 0;
}
-#ifdef MODULE
static int rd_release(struct inode * inode, struct file * filp)
{
MOD_DEC_USE_COUNT;
return 0;
}
-#endif
static struct file_operations fd_fops = {
NULL, /* lseek - default */
@@ -266,11 +265,8 @@ static struct file_operations fd_fops = {
rd_ioctl, /* ioctl */
NULL, /* mmap */
rd_open, /* open */
-#ifndef MODULE
- NULL, /* no special release code... */
-#else
+ NULL, /* flush */
rd_release, /* module needs to decrement use count */
-#endif
block_fsync /* fsync */
};
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index 5598ad0a7..bacb3df98 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -968,6 +968,7 @@ static struct file_operations floppy_fops = {
floppy_ioctl, /* ioctl */
NULL, /* mmap */
floppy_open, /* open */
+ NULL, /* flush */
floppy_release, /* release */
block_fsync, /* fsync */
NULL, /* fasync */
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index ffb1645ac..ccbcc0a97 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -157,6 +157,7 @@ static struct file_operations xd_fops = {
xd_ioctl, /* ioctl */
NULL, /* mmap */
xd_open, /* open */
+ NULL, /* flush */
xd_release, /* release */
block_fsync /* fsync */
};
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index ac13bcff2..193208d0d 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -63,46 +63,46 @@ do_z2_request( void )
while ( TRUE )
{
- INIT_REQUEST;
-
- start = CURRENT->sector << 9;
- len = CURRENT->current_nr_sectors << 9;
-
- if ( ( start + len ) > z2ram_size )
- {
- printk( KERN_ERR DEVICE_NAME ": bad access: block=%ld, count=%ld\n",
- CURRENT->sector,
- CURRENT->current_nr_sectors);
- end_request( FALSE );
- continue;
- }
-
- if ( ( CURRENT->cmd != READ ) && ( CURRENT->cmd != WRITE ) )
- {
- printk( KERN_ERR DEVICE_NAME ": bad command: %d\n", CURRENT->cmd );
- end_request( FALSE );
- continue;
- }
-
- while ( len )
- {
- addr = start & Z2RAM_CHUNKMASK;
- size = Z2RAM_CHUNKSIZE - addr;
- if ( len < size )
- size = len;
-
- addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ];
-
- if ( CURRENT->cmd == READ )
- memcpy( CURRENT->buffer, (char *)addr, size );
- else
- memcpy( (char *)addr, CURRENT->buffer, size );
-
- start += size;
- len -= size;
- }
-
- end_request( TRUE );
+ INIT_REQUEST;
+
+ start = CURRENT->sector << 9;
+ len = CURRENT->current_nr_sectors << 9;
+
+ if ( ( start + len ) > z2ram_size )
+ {
+ printk( KERN_ERR DEVICE_NAME ": bad access: block=%ld, count=%ld\n",
+ CURRENT->sector,
+ CURRENT->current_nr_sectors);
+ end_request( FALSE );
+ continue;
+ }
+
+ if ( ( CURRENT->cmd != READ ) && ( CURRENT->cmd != WRITE ) )
+ {
+ printk( KERN_ERR DEVICE_NAME ": bad command: %d\n", CURRENT->cmd );
+ end_request( FALSE );
+ continue;
+ }
+
+ while ( len )
+ {
+ addr = start & Z2RAM_CHUNKMASK;
+ size = Z2RAM_CHUNKSIZE - addr;
+ if ( len < size )
+ size = len;
+
+ addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ];
+
+ if ( CURRENT->cmd == READ )
+ memcpy( CURRENT->buffer, (char *)addr, size );
+ else
+ memcpy( (char *)addr, CURRENT->buffer, size );
+
+ start += size;
+ len -= size;
+ }
+
+ end_request( TRUE );
}
}
@@ -113,13 +113,13 @@ get_z2ram( void )
for ( i = 0; i < Z2RAM_SIZE / Z2RAM_CHUNKSIZE; i++ )
{
- if ( test_bit( i, zorro_unused_z2ram ) )
- {
- z2_count++;
- z2ram_map[ z2ram_size++ ] =
- ZTWO_VADDR( Z2RAM_START ) + ( i << Z2RAM_CHUNKSHIFT );
- clear_bit( i, zorro_unused_z2ram );
- }
+ if ( test_bit( i, zorro_unused_z2ram ) )
+ {
+ z2_count++;
+ z2ram_map[ z2ram_size++ ] =
+ ZTWO_VADDR( Z2RAM_START ) + ( i << Z2RAM_CHUNKSHIFT );
+ clear_bit( i, zorro_unused_z2ram );
+ }
}
return;
@@ -131,18 +131,18 @@ get_chipram( void )
while ( amiga_chip_avail() > ( Z2RAM_CHUNKSIZE * 4 ) )
{
- chip_count++;
- z2ram_map[ z2ram_size ] =
- (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE );
+ chip_count++;
+ z2ram_map[ z2ram_size ] =
+ (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE );
- if ( z2ram_map[ z2ram_size ] == 0 )
- {
- break;
- }
+ if ( z2ram_map[ z2ram_size ] == 0 )
+ {
+ break;
+ }
- z2ram_size++;
+ z2ram_size++;
}
-
+
return;
}
@@ -151,99 +151,99 @@ z2_open( struct inode *inode, struct file *filp )
{
int device;
int max_z2_map = ( Z2RAM_SIZE / Z2RAM_CHUNKSIZE ) *
- sizeof( z2ram_map[0] );
+ sizeof( z2ram_map[0] );
int max_chip_map = ( amiga_chip_size / Z2RAM_CHUNKSIZE ) *
- sizeof( z2ram_map[0] );
+ sizeof( z2ram_map[0] );
device = DEVICE_NR( inode->i_rdev );
if ( current_device != -1 && current_device != device )
{
- return -EBUSY;
+ return -EBUSY;
}
if ( current_device == -1 )
{
- z2_count = 0;
- chip_count = 0;
- z2ram_size = 0;
-
- switch ( device )
- {
- case Z2MINOR_COMBINED:
-
- z2ram_map = kmalloc( max_z2_map + max_chip_map, GFP_KERNEL );
- if ( z2ram_map == NULL )
- {
- printk( KERN_ERR DEVICE_NAME
- ": cannot get mem for z2ram_map\n" );
- return -ENOMEM;
- }
-
- get_z2ram();
- get_chipram();
-
- if ( z2ram_size != 0 )
- printk( KERN_INFO DEVICE_NAME
- ": using %iK Zorro II RAM and %iK Chip RAM (Total %dK)\n",
- z2_count * Z2RAM_CHUNK1024,
- chip_count * Z2RAM_CHUNK1024,
- ( z2_count + chip_count ) * Z2RAM_CHUNK1024 );
-
- break;
+ z2_count = 0;
+ chip_count = 0;
+ z2ram_size = 0;
+
+ switch ( device )
+ {
+ case Z2MINOR_COMBINED:
+
+ z2ram_map = kmalloc( max_z2_map + max_chip_map, GFP_KERNEL );
+ if ( z2ram_map == NULL )
+ {
+ printk( KERN_ERR DEVICE_NAME
+ ": cannot get mem for z2ram_map\n" );
+ return -ENOMEM;
+ }
+
+ get_z2ram();
+ get_chipram();
+
+ if ( z2ram_size != 0 )
+ printk( KERN_INFO DEVICE_NAME
+ ": using %iK Zorro II RAM and %iK Chip RAM (Total %dK)\n",
+ z2_count * Z2RAM_CHUNK1024,
+ chip_count * Z2RAM_CHUNK1024,
+ ( z2_count + chip_count ) * Z2RAM_CHUNK1024 );
+
+ break;
case Z2MINOR_Z2ONLY:
- z2ram_map = kmalloc( max_z2_map, GFP_KERNEL );
- if ( z2ram_map == NULL )
- {
- printk( KERN_ERR DEVICE_NAME
- ": cannot get mem for z2ram_map\n" );
- return -ENOMEM;
- }
-
- get_z2ram();
-
- if ( z2ram_size != 0 )
- printk( KERN_INFO DEVICE_NAME
- ": using %iK of Zorro II RAM\n",
- z2_count * Z2RAM_CHUNK1024 );
-
- break;
-
- case Z2MINOR_CHIPONLY:
- z2ram_map = kmalloc( max_chip_map, GFP_KERNEL );
- if ( z2ram_map == NULL )
- {
- printk( KERN_ERR DEVICE_NAME
- ": cannot get mem for z2ram_map\n" );
- return -ENOMEM;
- }
-
- get_chipram();
-
- if ( z2ram_size != 0 )
- printk( KERN_INFO DEVICE_NAME
- ": using %iK Chip RAM\n",
- chip_count * Z2RAM_CHUNK1024 );
-
- break;
-
- default:
- return -ENODEV;
- }
-
- if ( z2ram_size == 0 )
- {
- kfree( z2ram_map );
- printk( KERN_NOTICE DEVICE_NAME
- ": no unused ZII/Chip RAM found\n" );
- return -ENOMEM;
- }
-
- current_device = device;
- z2ram_size <<= Z2RAM_CHUNKSHIFT;
- z2_sizes[ device ] = z2ram_size >> 10;
- blk_size[ MAJOR_NR ] = z2_sizes;
+ z2ram_map = kmalloc( max_z2_map, GFP_KERNEL );
+ if ( z2ram_map == NULL )
+ {
+ printk( KERN_ERR DEVICE_NAME
+ ": cannot get mem for z2ram_map\n" );
+ return -ENOMEM;
+ }
+
+ get_z2ram();
+
+ if ( z2ram_size != 0 )
+ printk( KERN_INFO DEVICE_NAME
+ ": using %iK of Zorro II RAM\n",
+ z2_count * Z2RAM_CHUNK1024 );
+
+ break;
+
+ case Z2MINOR_CHIPONLY:
+ z2ram_map = kmalloc( max_chip_map, GFP_KERNEL );
+ if ( z2ram_map == NULL )
+ {
+ printk( KERN_ERR DEVICE_NAME
+ ": cannot get mem for z2ram_map\n" );
+ return -ENOMEM;
+ }
+
+ get_chipram();
+
+ if ( z2ram_size != 0 )
+ printk( KERN_INFO DEVICE_NAME
+ ": using %iK Chip RAM\n",
+ chip_count * Z2RAM_CHUNK1024 );
+
+ break;
+
+ default:
+ return -ENODEV;
+ }
+
+ if ( z2ram_size == 0 )
+ {
+ kfree( z2ram_map );
+ printk( KERN_NOTICE DEVICE_NAME
+ ": no unused ZII/Chip RAM found\n" );
+ return -ENOMEM;
+ }
+
+ current_device = device;
+ z2ram_size <<= Z2RAM_CHUNKSHIFT;
+ z2_sizes[ device ] = z2ram_size >> 10;
+ blk_size[ MAJOR_NR ] = z2_sizes;
}
#if defined(MODULE)
@@ -258,7 +258,7 @@ z2_release( struct inode *inode, struct file *filp )
{
if ( current_device == -1 )
- return;
+ return;
sync_dev( inode->i_rdev );
@@ -271,16 +271,17 @@ z2_release( struct inode *inode, struct file *filp )
static struct file_operations z2_fops =
{
- NULL, /* lseek - default */
- block_read, /* read - general block-dev read */
- block_write, /* write - general block-dev write */
- NULL, /* readdir - bad */
- NULL, /* poll */
- NULL, /* ioctl */
- NULL, /* mmap */
- z2_open, /* open */
- z2_release, /* release */
- block_fsync /* fsync */
+ NULL, /* lseek - default */
+ block_read, /* read - general block-dev read */
+ block_write, /* write - general block-dev write */
+ NULL, /* readdir - bad */
+ NULL, /* poll */
+ NULL, /* ioctl */
+ NULL, /* mmap */
+ z2_open, /* open */
+ NULL, /* flush */
+ z2_release, /* release */
+ block_fsync /* fsync */
};
__initfunc(int
@@ -288,13 +289,13 @@ z2_init( void ))
{
if ( !MACH_IS_AMIGA )
- return -ENXIO;
+ return -ENXIO;
if ( register_blkdev( MAJOR_NR, DEVICE_NAME, &z2_fops ) )
{
- printk( KERN_ERR DEVICE_NAME ": Unable to get major %d\n",
- MAJOR_NR );
- return -EBUSY;
+ printk( KERN_ERR DEVICE_NAME ": Unable to get major %d\n",
+ MAJOR_NR );
+ return -EBUSY;
}
blk_dev[ MAJOR_NR ].request_fn = DEVICE_REQUEST;
@@ -313,7 +314,7 @@ init_module( void )
error = z2_init();
if ( error == 0 )
{
- printk( KERN_INFO DEVICE_NAME ": loaded as module\n" );
+ printk( KERN_INFO DEVICE_NAME ": loaded as module\n" );
}
return error;
@@ -325,29 +326,29 @@ cleanup_module( void )
int i, j;
if ( unregister_blkdev( MAJOR_NR, DEVICE_NAME ) != 0 )
- printk( KERN_ERR DEVICE_NAME ": unregister of device failed\n");
+ printk( KERN_ERR DEVICE_NAME ": unregister of device failed\n");
if ( current_device != -1 )
{
- i = 0;
-
- for ( j = 0 ; j < z2_count; j++ )
- {
- set_bit( i++, zorro_unused_z2ram );
- }
-
- for ( j = 0 ; j < chip_count; j++ )
- {
- if ( z2ram_map[ i ] )
- {
- amiga_chip_free( (void *) z2ram_map[ i++ ] );
- }
- }
-
- if ( z2ram_map != NULL )
- {
- kfree( z2ram_map );
- }
+ i = 0;
+
+ for ( j = 0 ; j < z2_count; j++ )
+ {
+ set_bit( i++, zorro_unused_z2ram );
+ }
+
+ for ( j = 0 ; j < chip_count; j++ )
+ {
+ if ( z2ram_map[ i ] )
+ {
+ amiga_chip_free( (void *) z2ram_map[ i++ ] );
+ }
+ }
+
+ if ( z2ram_map != NULL )
+ {
+ kfree( z2ram_map );
+ }
}
return;