Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2002-09-08 18:41:49 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-09-08 18:41:49 -0700
commitd4cddb795d19f1ed3bdaa216f8be4e8b1034843c (patch)
treedecaab32244e646d049e4663789505fbaad2b8ba
parentf9506f4d7e4d06ca6f7006d8156ef6ba08ff1f1d (diff)
parentb32c3a0cc6c27e43c1b6dbbc840bbd569c5f84cc (diff)
Merge bk://thebsh.namesys.com/bk/reiser3-linux-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
-rw-r--r--arch/alpha/Makefile3
-rw-r--r--arch/alpha/kernel/core_apecs.c39
-rw-r--r--arch/alpha/kernel/core_cia.c32
-rw-r--r--arch/alpha/kernel/core_irongate.c39
-rw-r--r--arch/alpha/kernel/core_lca.c38
-rw-r--r--arch/alpha/kernel/core_mcpcia.c97
-rw-r--r--arch/alpha/kernel/core_polaris.c46
-rw-r--r--arch/alpha/kernel/core_t2.c160
-rw-r--r--arch/alpha/kernel/core_titan.c115
-rw-r--r--arch/alpha/kernel/core_tsunami.c122
-rw-r--r--arch/alpha/kernel/core_wildfire.c115
-rw-r--r--arch/alpha/kernel/irq.c2
-rw-r--r--arch/alpha/kernel/pci.c19
-rw-r--r--arch/alpha/kernel/pci_impl.h13
-rw-r--r--arch/alpha/kernel/pci_iommu.c20
-rw-r--r--arch/alpha/kernel/process.c8
-rw-r--r--arch/alpha/kernel/proto.h2
-rw-r--r--arch/alpha/kernel/smp.c2
-rw-r--r--arch/alpha/kernel/sys_alcor.c2
-rw-r--r--arch/alpha/kernel/sys_rx164.c19
-rw-r--r--arch/alpha/kernel/sys_sable.c8
-rw-r--r--arch/alpha/kernel/time.c8
-rw-r--r--arch/alpha/kernel/traps.c4
-rw-r--r--arch/i386/kernel/init_task.c2
-rw-r--r--arch/i386/pci/fixup.c17
-rw-r--r--arch/ppc/mm/fault.c2
-rw-r--r--arch/sparc/mm/fault.c2
-rw-r--r--drivers/acorn/block/mfmhd.c68
-rw-r--r--drivers/block/DAC960.c9
-rw-r--r--drivers/block/DAC960.h2
-rw-r--r--drivers/block/acsi.c29
-rw-r--r--drivers/block/blkpg.c27
-rw-r--r--drivers/block/cciss.c10
-rw-r--r--drivers/block/cciss.h3
-rw-r--r--drivers/block/cpqarray.c27
-rw-r--r--drivers/block/genhd.c53
-rw-r--r--drivers/block/loop.c5
-rw-r--r--drivers/block/paride/pcd.c1045
-rw-r--r--drivers/block/paride/pd.c10
-rw-r--r--drivers/block/ps2esdi.c19
-rw-r--r--drivers/block/rd.c19
-rw-r--r--drivers/block/umem.c11
-rw-r--r--drivers/block/xd.c14
-rw-r--r--drivers/cdrom/cdrom.c2
-rw-r--r--drivers/cdrom/cdu31a.c16
-rw-r--r--drivers/cdrom/mcdx.c47
-rw-r--r--drivers/cdrom/sbpcd.c1314
-rw-r--r--drivers/cdrom/sbpcd.h58
-rw-r--r--drivers/ide/hd.c23
-rw-r--r--drivers/ide/ide-cd.c30
-rw-r--r--drivers/ide/ide-disk.c22
-rw-r--r--drivers/ide/ide-floppy.c27
-rw-r--r--drivers/ide/ide-geometry.c2
-rw-r--r--drivers/ide/ide-probe.c32
-rw-r--r--drivers/ide/ide.c24
-rw-r--r--drivers/md/md.c16
-rw-r--r--drivers/message/i2o/i2o_block.c29
-rw-r--r--drivers/mtd/ftl.c11
-rw-r--r--drivers/mtd/nftlcore.c16
-rw-r--r--drivers/pci/probe.c26
-rw-r--r--drivers/pci/quirks.c12
-rw-r--r--drivers/pci/setup-res.c2
-rw-r--r--drivers/s390/block/dasd.c4
-rw-r--r--drivers/s390/block/dasd_genhd.c16
-rw-r--r--drivers/scsi/qlogicfc.c17
-rw-r--r--drivers/scsi/qlogicfc.h2
-rw-r--r--drivers/scsi/sd.c40
-rw-r--r--drivers/scsi/sd.h2
-rw-r--r--drivers/scsi/sr.c309
-rw-r--r--drivers/scsi/sr.h11
-rw-r--r--drivers/scsi/sr_ioctl.c142
-rw-r--r--drivers/scsi/sr_vendor.c118
-rw-r--r--drivers/scsi/st.c14
-rw-r--r--fs/affs/file.c10
-rw-r--r--fs/block_dev.c62
-rw-r--r--fs/buffer.c73
-rw-r--r--fs/driverfs/inode.c13
-rw-r--r--fs/exec.c49
-rw-r--r--fs/ext2/dir.c11
-rw-r--r--fs/ext3/inode.c30
-rw-r--r--fs/fat/inode.c17
-rw-r--r--fs/jffs/inode-v23.c11
-rw-r--r--fs/jffs2/file.c4
-rw-r--r--fs/jfs/jfs_metapage.c1
-rw-r--r--fs/minix/dir.c12
-rw-r--r--fs/namei.c3
-rw-r--r--fs/partitions/check.c463
-rw-r--r--fs/ramfs/inode.c14
-rw-r--r--fs/reiserfs/inode.c22
-rw-r--r--fs/reiserfs/stree.c6
-rw-r--r--fs/reiserfs/tail_conversion.c5
-rw-r--r--fs/sysv/dir.c3
-rw-r--r--include/asm-alpha/core_t2.h40
-rw-r--r--include/asm-alpha/dma.h47
-rw-r--r--include/asm-alpha/floppy.h23
-rw-r--r--include/asm-alpha/ide.h11
-rw-r--r--include/asm-alpha/kmap_types.h31
-rw-r--r--include/asm-alpha/user.h1
-rw-r--r--include/asm-i386/highmem.h6
-rw-r--r--include/asm-i386/spinlock.h2
-rw-r--r--include/asm-i386/tlbflush.h18
-rw-r--r--include/asm-ppc/hardirq.h2
-rw-r--r--include/asm-ppc/highmem.h6
-rw-r--r--include/asm-sparc/hardirq.h6
-rw-r--r--include/asm-sparc/highmem.h6
-rw-r--r--include/linux/blkdev.h3
-rw-r--r--include/linux/genhd.h33
-rw-r--r--include/linux/highmem.h4
-rw-r--r--include/linux/ide.h3
-rw-r--r--include/linux/init_task.h5
-rw-r--r--include/linux/pci.h10
-rw-r--r--include/linux/preempt.h10
-rw-r--r--include/linux/raid/md.h1
-rw-r--r--include/linux/sched.h53
-rw-r--r--init/do_mounts.c27
-rw-r--r--kernel/exit.c151
-rw-r--r--kernel/fork.c24
-rw-r--r--kernel/ksyms.c4
-rw-r--r--kernel/sched.c9
-rw-r--r--kernel/signal.c537
-rw-r--r--mm/filemap.c95
-rw-r--r--mm/page_alloc.c9
-rw-r--r--mm/vmscan.c4
123 files changed, 3419 insertions, 3242 deletions
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index c22b4900075f..5ff98abd62ad 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -128,6 +128,9 @@ archmrproper:
vmlinux: arch/alpha/vmlinux.lds.s
+arch/$(ARCH)/vmlinux.lds.s: arch/$(ARCH)/vmlinux.lds.S
+ $(CPP) $(CPPFLAGS) $(CPPFLAGS_$@) -D__ASSEMBLY__ -P -C -U$(ARCH) $< -o $@
+
bootpfile:
@$(MAKEBOOT) bootpfile
diff --git a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c
index 738f2893be31..642153e74964 100644
--- a/arch/alpha/kernel/core_apecs.c
+++ b/arch/alpha/kernel/core_apecs.c
@@ -90,11 +90,11 @@
*/
static int
-mk_conf_addr(struct pci_bus *bus_dev, unsigned int device_fn, int where,
+mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
unsigned long *pci_addr, unsigned char *type1)
{
unsigned long addr;
- u8 bus = bus_dev->number;
+ u8 bus = pbus->number;
DBGC(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
" pci_addr=0x%p, type1=0x%p)\n",
@@ -272,8 +272,8 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
}
static int
-apecs_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
- u8 *value)
+apecs_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
{
unsigned long addr, pci_addr;
unsigned char type1;
@@ -283,27 +283,16 @@ apecs_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- switch (size) {
- case 1:
- mask = 0x00;
- shift = (where & 3) * 8;
- break;
- case 2:
- mask = 0x08;
- shift = (where & 3) * 8;
- break;
- case 4:
- mask = 0x18;
- shift = 0;
- break;
- }
+ mask = (size - 1) * 8;
+ shift = (where & 3) * 8;
addr = (pci_addr << 5) + mask + APECS_CONF;
*value = conf_read(addr, type1) >> (shift);
return PCIBIOS_SUCCESSFUL;
}
static int
-apecs_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
+apecs_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
{
unsigned long addr, pci_addr;
unsigned char type1;
@@ -312,17 +301,7 @@ apecs_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- switch (size) {
- case 1:
- mask = 0x00;
- break;
- case 2:
- mask = 0x08;
- break;
- case 4:
- mask = 0x18;
- break;
- }
+ mask = (size - 1) * 8;
addr = (pci_addr << 5) + mask + APECS_CONF;
conf_write(addr, value << ((where & 3) * 8), type1);
return PCIBIOS_SUCCESSFUL;
diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
index 469c1dda51db..b8c7a5e694f3 100644
--- a/arch/alpha/kernel/core_cia.c
+++ b/arch/alpha/kernel/core_cia.c
@@ -219,22 +219,9 @@ cia_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- switch (size) {
- case 1:
- mask = 0x00;
- shift = (where & 3) * 8;
- break;
- case 2:
- mask = 0x08;
- shift = (where & 3) * 8;
- break;
- case 4:
- mase = 0x18;
- shift = 0;
- break;
- }
-
- addr = (pci_addr << 5) + 0x18 + CIA_CONF;
+ mask = (size - 1) * 8;
+ shift = (where & 3) * 8;
+ addr = (pci_addr << 5) + mask + CIA_CONF;
*value = conf_read(addr, type1) >> (shift);
return PCIBIOS_SUCCESSFUL;
}
@@ -250,18 +237,7 @@ cia_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- switch (size) {
- case 1:
- mask = 0x00;
- break;
- case 2:
- mask = 0x08;
- break;
- case 4:
- mase = 0x18;
- break;
- }
-
+ mask = (size - 1) * 8;
addr = (pci_addr << 5) + mask + CIA_CONF;
conf_write(addr, value << ((where & 3) * 8), type1);
return PCIBIOS_SUCCESSFUL;
diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c
index 59f91ce4f833..1709838729a6 100644
--- a/arch/alpha/kernel/core_irongate.c
+++ b/arch/alpha/kernel/core_irongate.c
@@ -83,11 +83,11 @@
*/
static int
-mk_conf_addr(struct pci_bus *bus_dev, unsigned int device_fn, int where,
+mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
unsigned long *pci_addr, unsigned char *type1)
{
unsigned long addr;
- u8 bus = bus_dev->number;
+ u8 bus = pbus->number;
DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
"pci_addr=0x%p, type1=0x%p)\n",
@@ -113,7 +113,18 @@ irongate_read_config(struct pci_bus *bus, unsigned int devfn, int where,
if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- *value = __kernel_ldbu(*(vucp)addr);
+ switch (size) {
+ case 1:
+ *value = __kernel_ldbu(*(vucp)addr);
+ break;
+ case 2:
+ *value = __kernel_ldwu(*(vusp)addr);
+ break;
+ case 4:
+ *value = *(vuip)addr;
+ break;
+ }
+
return PCIBIOS_SUCCESSFUL;
}
@@ -127,13 +138,27 @@ irongate_write_config(struct pci_bus *bus, unsigned int devfn, int where,
if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- __kernel_stb(value, *(vucp)addr);
- mb();
- __kernel_ldbu(*(vucp)addr);
+ switch (size) {
+ case 1:
+ __kernel_stb(value, *(vucp)addr);
+ mb();
+ __kernel_ldbu(*(vucp)addr);
+ break;
+ case 2:
+ __kernel_stw(value, *(vusp)addr);
+ mb();
+ __kernel_ldwu(*(vusp)addr);
+ break;
+ case 4:
+ *(vuip)addr = value;
+ mb();
+ *(vuip)addr;
+ break;
+ }
+
return PCIBIOS_SUCCESSFUL;
}
-
struct pci_ops irongate_pci_ops =
{
.read = irongate_read_config,
diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c
index 0c172677003b..197f03c10ea0 100644
--- a/arch/alpha/kernel/core_lca.c
+++ b/arch/alpha/kernel/core_lca.c
@@ -99,11 +99,11 @@
*/
static int
-mk_conf_addr(struct pci_bus *bus_dev, unsigned int device_fn, int where,
+mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
unsigned long *pci_addr)
{
unsigned long addr;
- u8 bus = bus_dev->number;
+ u8 bus = pbus->number;
if (bus == 0) {
int device = device_fn >> 3;
@@ -204,32 +204,20 @@ lca_read_config(struct pci_bus *bus, unsigned int devfn, int where,
{
unsigned long addr, pci_addr;
long mask;
- int shift
+ int shift;
- if (mk_conf_addr(bus, devfn, dev, where, &pci_addr))
+ if (mk_conf_addr(bus, devfn, where, &pci_addr))
return PCIBIOS_DEVICE_NOT_FOUND;
- switch (size) {
- case 1:
- shift = (where & 3) * 8;
- mask = 0x00;
- break;
- case 2:
- shift = (where & 3) * 8;
- mask = 0x08
- break;
- case 4:
- shift = 0;
- mask = 0x18
- break;
- }
+ shift = (where & 3) * 8;
+ mask = (size - 1) * 8;
addr = (pci_addr << 5) + mask + LCA_CONF;
*value = conf_read(addr) >> (shift);
return PCIBIOS_SUCCESSFUL;
}
static int
-lca_write_config(struct pci_bus *dev, unsigned int devfn, int where, int size,
+lca_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
u32 value)
{
unsigned long addr, pci_addr;
@@ -238,17 +226,7 @@ lca_write_config(struct pci_bus *dev, unsigned int devfn, int where, int size,
if (mk_conf_addr(bus, devfn, where, &pci_addr))
return PCIBIOS_DEVICE_NOT_FOUND;
- switch (size) {
- case 1:
- mask = 0x00;
- break;
- case 2:
- mask = 0x08
- break;
- case 4:
- mask = 0x18
- break;
- }
+ mask = (size - 1) * 8;
addr = (pci_addr << 5) + mask + LCA_CONF;
conf_write(addr, value << ((where & 3) * 8));
return PCIBIOS_SUCCESSFUL;
diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c
index 655ed6757535..5b249fde8c0d 100644
--- a/arch/alpha/kernel/core_mcpcia.c
+++ b/arch/alpha/kernel/core_mcpcia.c
@@ -171,11 +171,11 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1,
}
static int
-mk_conf_addr(struct pci_dev *dev, int where, struct pci_controller *hose,
- unsigned long *pci_addr, unsigned char *type1)
+mk_conf_addr(struct pci_bus *pbus, unsigned int devfn, int where,
+ struct pci_controller *hose, unsigned long *pci_addr,
+ unsigned char *type1)
{
- u8 bus = dev->bus->number;
- u8 devfn = dev->devfn;
+ u8 bus = pbus->number;
unsigned long addr;
DBG_CFG(("mk_conf_addr(bus=%d,devfn=0x%x,hose=%d,where=0x%x,"
@@ -185,7 +185,7 @@ mk_conf_addr(struct pci_dev *dev, int where, struct pci_controller *hose,
/* Type 1 configuration cycle for *ALL* busses. */
*type1 = 1;
- if (dev->bus->number == hose->first_busno)
+ if (bus == hose->first_busno)
bus = 0;
addr = (bus << 16) | (devfn << 8) | (where);
addr <<= 5; /* swizzle for SPARSE */
@@ -197,94 +197,53 @@ mk_conf_addr(struct pci_dev *dev, int where, struct pci_controller *hose,
}
static int
-mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+mcpcia_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
{
- struct pci_controller *hose = dev->sysdata;
+ struct pci_controller *hose = bus->sysdata;
unsigned long addr, w;
unsigned char type1;
- if (mk_conf_addr(dev, where, hose, &addr, &type1))
+ if (mk_conf_addr(bus, devfn, where, hose, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= 0x00;
+ addr |= (size - 1) * 8;
w = conf_read(addr, type1, hose);
- *value = __kernel_extbl(w, where & 3);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
-{
- struct pci_controller *hose = dev->sysdata;
- unsigned long addr, w;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, hose, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr |= 0x08;
- w = conf_read(addr, type1, hose);
- *value = __kernel_extwl(w, where & 3);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
-{
- struct pci_controller *hose = dev->sysdata;
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, hose, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- addr |= 0x18;
- *value = conf_read(addr, type1, hose);
+ switch (size) {
+ case 1:
+ *value = __kernel_extbl(w, where & 3);
+ break;
+ case 2:
+ *value = __kernel_extwl(w, where & 3);
+ break;
+ case 4:
+ *value = w;
+ break;
+ }
return PCIBIOS_SUCCESSFUL;
}
static int
-mcpcia_write_config(struct pci_dev *dev, int where, u32 value, long mask)
+mcpcia_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
{
- struct pci_controller *hose = dev->sysdata;
+ struct pci_controller *hose = bus->sysdata;
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(dev, where, hose, &addr, &type1))
+ if (mk_conf_addr(bus, devfn, where, hose, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- addr |= mask;
+ addr |= (size - 1) * 8;
value = __kernel_insql(value, where & 3);
conf_write(addr, value, type1, hose);
return PCIBIOS_SUCCESSFUL;
}
-static int
-mcpcia_write_config_byte(struct pci_dev *dev, int where, u8 value)
-{
- return mcpcia_write_config(dev, where, value, 0x00);
-}
-
-static int
-mcpcia_write_config_word(struct pci_dev *dev, int where, u16 value)
-{
- return mcpcia_write_config(dev, where, value, 0x08);
-}
-
-static int
-mcpcia_write_config_dword(struct pci_dev *dev, int where, u32 value)
-{
- return mcpcia_write_config(dev, where, value, 0x18);
-}
-
struct pci_ops mcpcia_pci_ops =
{
- read_byte: mcpcia_read_config_byte,
- read_word: mcpcia_read_config_word,
- read_dword: mcpcia_read_config_dword,
- write_byte: mcpcia_write_config_byte,
- write_word: mcpcia_write_config_word,
- write_dword: mcpcia_write_config_dword
+ .read = mcpcia_read_config,
+ .write = mcpcia_write_config,
};
void
diff --git a/arch/alpha/kernel/core_polaris.c b/arch/alpha/kernel/core_polaris.c
index a7b063925d7e..604071eef3c8 100644
--- a/arch/alpha/kernel/core_polaris.c
+++ b/arch/alpha/kernel/core_polaris.c
@@ -65,10 +65,10 @@
*/
static int
-mk_conf_addr(struct pci_bus *bus_dev, unsigned int device_fn, int where,
+mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
unsigned long *pci_addr, u8 *type1)
{
- u8 bus = bus_dev->number;
+ u8 bus = pbus->number;
*type1 = (bus == 0) ? 0 : 1;
*pci_addr = (bus << 16) | (device_fn << 8) | (where) |
@@ -85,13 +85,24 @@ static int
polaris_read_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *value)
{
- unsigned long pci_addr;
+ unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
+ if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- *value = __kernel_ldbu(*(vucp)pci_addr);
+ switch (size) {
+ case 1:
+ *value = __kernel_ldbu(*(vucp)addr);
+ break;
+ case 2:
+ *value = __kernel_ldwu(*(vusp)addr);
+ break;
+ case 4:
+ *value = *(vuip)addr;
+ break;
+ }
+
return PCIBIOS_SUCCESSFUL;
}
@@ -100,15 +111,30 @@ static int
polaris_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 value)
{
- unsigned long pci_addr;
+ unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
+ if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- __kernel_stb(value, *(vucp)pci_addr);
- mb();
- __kernel_ldbu(*(vucp)pci_addr);
+ switch (size) {
+ case 1:
+ __kernel_stb(value, *(vucp)addr);
+ mb();
+ __kernel_ldbu(*(vucp)addr);
+ break;
+ case 2:
+ __kernel_stw(value, *(vusp)addr);
+ mb();
+ __kernel_ldwu(*(vusp)addr);
+ break;
+ case 4:
+ *(vuip)addr = value;
+ mb();
+ *(vuip)addr;
+ break;
+ }
+
return PCIBIOS_SUCCESSFUL;
}
diff --git a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c
index 6fbd379ae099..801b5b2c2037 100644
--- a/arch/alpha/kernel/core_t2.c
+++ b/arch/alpha/kernel/core_t2.c
@@ -26,6 +26,18 @@
#include "proto.h"
#include "pci_impl.h"
+/*
+ * By default, we direct-map starting at 2GB, in order to allow the
+ * maximum size direct-map window (2GB) to match the maximum amount of
+ * memory (2GB) that can be present on SABLEs. But that limits the
+ * floppy to DMA only via the scatter/gather window set up for 8MB
+ * ISA DMA, since the maximum ISA DMA address is 2GB-1.
+ *
+ * For now, this seems a reasonable trade-off: even though most SABLEs
+ * have far less than even 1GB of memory, floppy usage/performance will
+ * not really be affected by forcing it to go via scatter/gather...
+ */
+#define T2_DIRECTMAP_2G 1
/*
* NOTE: Herein lie back-to-back mb instructions. They are magic.
@@ -89,11 +101,11 @@
*/
static int
-mk_conf_addr(struct pci_bus *bus_dev, unsigned int device_fn, int where,
+mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
unsigned long *pci_addr, unsigned char *type1)
{
unsigned long addr;
- u8 bus = bus_dev->number;
+ u8 bus = pbus->number;
DBG(("mk_conf_addr(bus=%d, dfn=0x%x, where=0x%x,"
" addr=0x%lx, type1=0x%x)\n",
@@ -248,20 +260,8 @@ t2_read_config(struct pci_bus *bus, unsigned int devfn, int where,
if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- switch (size) {
- case 1:
- mask = 0x00;
- shift = (where & 3) * 8;
- break;
- case 2:
- mask = 0x08;
- shift = (where & 3) * 8;
- break;
- case 4:
- mask = 0x18;
- shift = 0;
- break;
- }
+ mask = (size - 1) * 8;
+ shift = (where & 3) * 8;
addr = (pci_addr << 5) + mask + T2_CONF;
*value = conf_read(addr, type1) >> (shift);
return PCIBIOS_SUCCESSFUL;
@@ -275,20 +275,10 @@ t2_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
unsigned char type1;
long mask;
- if (mk_conf_addr(dev, where, &pci_addr, &type1))
+ if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- switch (size) {
- case 1:
- mask = 0x00;
- break;
- case 2:
- mask = 0x08;
- break;
- case 4:
- mask = 0x18;
- break;
- }
+ mask = (size - 1) * 8;
addr = (pci_addr << 5) + mask + T2_CONF;
conf_write(addr, value << ((where & 3) * 8), type1);
return PCIBIOS_SUCCESSFUL;
@@ -304,6 +294,7 @@ void __init
t2_init_arch(void)
{
struct pci_controller *hose;
+ unsigned long t2_iocsr;
unsigned int i;
for (i = 0; i < NR_CPUS; i++) {
@@ -312,43 +303,80 @@ t2_init_arch(void)
}
#if 0
- {
- /* Set up error reporting. */
- unsigned long t2_err;
+ /* Set up error reporting. */
+ t2_iocsr = *(vulp)T2_IOCSR;
+ *(vulp)T2_IOCSR = t2_iocsr | (0x1UL << 7); /* TLB error check */
+ mb();
+ *(vulp)T2_IOCSR; /* read it back to make sure */
+#endif
- t2_err = *(vulp)T2_IOCSR;
- t2_err |= (0x1 << 7); /* master abort */
- *(vulp)T2_IOCSR = t2_err;
- mb();
+ /* Enable scatter/gather TLB use. */
+ t2_iocsr = *(vulp)T2_IOCSR;
+ if (!(t2_iocsr & (0x1UL << 26))) {
+ printk("t2_init_arch: enabling SG TLB, IOCSR was 0x%lx\n",
+ t2_iocsr);
+ *(vulp)T2_IOCSR = t2_iocsr | (0x1UL << 26);
+ mb();
+ *(vulp)T2_IOCSR; /* read it back to make sure */
}
-#endif
- printk("t2_init: HBASE was 0x%lx\n", *(vulp)T2_HBASE);
#if 0
- printk("t2_init: WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n",
- *(vulp)T2_WBASE1,
- *(vulp)T2_WMASK1,
- *(vulp)T2_TBASE1);
- printk("t2_init: WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n",
- *(vulp)T2_WBASE2,
- *(vulp)T2_WMASK2,
- *(vulp)T2_TBASE2);
+ printk("t2_init_arch: HBASE was 0x%lx\n", *(vulp)T2_HBASE);
+ printk("t2_init_arch: WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n",
+ *(vulp)T2_WBASE1, *(vulp)T2_WMASK1, *(vulp)T2_TBASE1);
+ printk("t2_init_arch: WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n",
+ *(vulp)T2_WBASE2, *(vulp)T2_WMASK2, *(vulp)T2_TBASE2);
#endif
/*
+ * Create our single hose.
+ */
+
+ pci_isa_hose = hose = alloc_pci_controller();
+ hose->io_space = &ioport_resource;
+ hose->mem_space = &iomem_resource;
+ hose->index = 0;
+
+ hose->sparse_mem_base = T2_SPARSE_MEM - IDENT_ADDR;
+ hose->dense_mem_base = T2_DENSE_MEM - IDENT_ADDR;
+ hose->sparse_io_base = T2_IO - IDENT_ADDR;
+ hose->dense_io_base = 0;
+
+ /* Note we can only do 1 SG window, as the other is for direct, so
+ do an ISA SG area, especially for the floppy. */
+ hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
+ hose->sg_pci = NULL;
+
+ /*
* Set up the PCI->physical memory translation windows.
- * For now, window 2 is disabled. In the future, we may
- * want to use it to do scatter/gather DMA.
*
- * Window 1 goes at 1 GB and is 1 GB large.
+ * Window 1 goes at ? GB and is ?GB large, direct mapped.
+ * Window 2 goes at 8 MB and is 8MB large, scatter/gather (for ISA).
*/
- /* WARNING!! must correspond to the DMA_WIN params!!! */
+#if T2_DIRECTMAP_2G
+ __direct_map_base = 0x80000000UL;
+ __direct_map_size = 0x80000000UL;
+
+ /* WARNING!! must correspond to the direct map window params!!! */
+ *(vulp)T2_WBASE1 = 0x80080fffU;
+ *(vulp)T2_WMASK1 = 0x7ff00000U;
+ *(vulp)T2_TBASE1 = 0;
+#else /* T2_DIRECTMAP_2G */
+ __direct_map_base = 0x40000000UL;
+ __direct_map_size = 0x40000000UL;
+
+ /* WARNING!! must correspond to the direct map window params!!! */
*(vulp)T2_WBASE1 = 0x400807ffU;
*(vulp)T2_WMASK1 = 0x3ff00000U;
*(vulp)T2_TBASE1 = 0;
+#endif /* T2_DIRECTMAP_2G */
+
+ /* WARNING!! must correspond to the SG arena/window params!!! */
+ *(vulp)T2_WBASE2 = 0x008c000fU;
+ *(vulp)T2_WMASK2 = 0x00700000U;
+ *(vulp)T2_TBASE2 = virt_to_phys(hose->sg_isa->ptes) >> 1;
- *(vulp)T2_WBASE2 = 0x0;
*(vulp)T2_HBASE = 0x0;
/* Zero HAE. */
@@ -356,26 +384,28 @@ t2_init_arch(void)
*(vulp)T2_HAE_2 = 0; mb();
*(vulp)T2_HAE_3 = 0; mb();
#if 0
- *(vulp)T2_HAE_4 = 0; mb(); /* do not touch this */
+ *(vulp)T2_HAE_4 = 0; mb(); /* DO NOT TOUCH THIS!!! */
#endif
- /*
- * Create our single hose.
- */
+ t2_pci_tbi(hose, 0, -1); /* flush TLB all */
+}
- pci_isa_hose = hose = alloc_pci_controller();
- hose->io_space = &ioport_resource;
- hose->mem_space = &iomem_resource;
- hose->index = 0;
+void
+t2_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
+{
+ unsigned long t2_iocsr;
- hose->sparse_mem_base = T2_SPARSE_MEM - IDENT_ADDR;
- hose->dense_mem_base = T2_DENSE_MEM - IDENT_ADDR;
- hose->sparse_io_base = T2_IO - IDENT_ADDR;
- hose->dense_io_base = 0;
+ t2_iocsr = *(vulp)T2_IOCSR;
- hose->sg_isa = hose->sg_pci = NULL;
- __direct_map_base = 0x40000000;
- __direct_map_size = 0x40000000;
+ /* set the TLB Clear bit */
+ *(vulp)T2_IOCSR = t2_iocsr | (0x1UL << 28);
+ mb();
+ *(vulp)T2_IOCSR; /* read it back to make sure */
+
+ /* clear the TLB Clear bit */
+ *(vulp)T2_IOCSR = t2_iocsr & ~(0x1UL << 28);
+ mb();
+ *(vulp)T2_IOCSR; /* read it back to make sure */
}
#define SIC_SEIC (1UL << 33) /* System Event Clear */
diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
index 4b8168f97ca3..eef1c29c7a9b 100644
--- a/arch/alpha/kernel/core_titan.c
+++ b/arch/alpha/kernel/core_titan.c
@@ -82,19 +82,18 @@ static struct
*/
static int
-mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
- unsigned char *type1)
+mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
+ unsigned long *pci_addr, unsigned char *type1)
{
- struct pci_controller *hose = dev->sysdata;
+ struct pci_controller *hose = pbus->sysdata;
unsigned long addr;
- u8 bus = dev->bus->number;
- u8 device_fn = dev->devfn;
+ u8 bus = pbus->number;
DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
"pci_addr=0x%p, type1=0x%p)\n",
bus, device_fn, where, pci_addr, type1));
- if (hose->first_busno == dev->bus->number)
+ if (hose->first_busno == bus)
bus = 0;
*type1 = (bus != 0);
@@ -106,98 +105,66 @@ mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
return 0;
}
-static int
-titan_read_config_byte(struct pci_dev *dev, int where, u8 *value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *value = __kernel_ldbu(*(vucp)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-titan_read_config_word(struct pci_dev *dev, int where, u16 *value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *value = __kernel_ldwu(*(vusp)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
static int
-titan_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+titan_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(dev, where, &addr, &type1))
+ if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- *value = *(vuip)addr;
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-titan_write_config_byte(struct pci_dev *dev, int where, u8 value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ switch (size) {
+ case 1:
+ *value = __kernel_ldbu(*(vucp)addr);
+ break;
+ case 2:
+ *value = __kernel_ldwu(*(vusp)addr);
+ break;
+ case 4:
+ *value = *(vuip)addr;
+ break;
+ }
- __kernel_stb(value, *(vucp)addr);
- mb();
- __kernel_ldbu(*(vucp)addr);
return PCIBIOS_SUCCESSFUL;
}
static int
-titan_write_config_word(struct pci_dev *dev, int where, u16 value)
+titan_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(dev, where, &addr, &type1))
+ if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- __kernel_stw(value, *(vusp)addr);
- mb();
- __kernel_ldwu(*(vusp)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-titan_write_config_dword(struct pci_dev *dev, int where, u32 value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ switch (size) {
+ case 1:
+ __kernel_stb(value, *(vucp)addr);
+ mb();
+ __kernel_ldbu(*(vucp)addr);
+ break;
+ case 2:
+ __kernel_stw(value, *(vusp)addr);
+ mb();
+ __kernel_ldwu(*(vusp)addr);
+ break;
+ case 4:
+ *(vuip)addr = value;
+ mb();
+ *(vuip)addr;
+ break;
+ }
- *(vuip)addr = value;
- mb();
- *(vuip)addr;
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops titan_pci_ops =
{
- read_byte: titan_read_config_byte,
- read_word: titan_read_config_word,
- read_dword: titan_read_config_dword,
- write_byte: titan_write_config_byte,
- write_word: titan_write_config_word,
- write_dword: titan_write_config_dword
+ .read = titan_read_config,
+ .write = titan_write_config,
};
diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c
index 48908861f4bf..7628bc241085 100644
--- a/arch/alpha/kernel/core_tsunami.c
+++ b/arch/alpha/kernel/core_tsunami.c
@@ -89,19 +89,18 @@ static struct
*/
static int
-mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
- unsigned char *type1)
+mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
+ unsigned long *pci_addr, unsigned char *type1)
{
- struct pci_controller *hose = dev->sysdata;
+ struct pci_controller *hose = pbus->sysdata;
unsigned long addr;
- u8 bus = dev->bus->number;
- u8 device_fn = dev->devfn;
+ u8 bus = pbus->number;
DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
"pci_addr=0x%p, type1=0x%p)\n",
bus, device_fn, where, pci_addr, type1));
- if (hose->first_busno == dev->bus->number)
+ if (hose->first_busno == bus)
bus = 0;
*type1 = (bus != 0);
@@ -114,97 +113,65 @@ mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
}
static int
-tsunami_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+tsunami_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(dev, where, &addr, &type1))
+ if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- *value = __kernel_ldbu(*(vucp)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-tsunami_read_config_word(struct pci_dev *dev, int where, u16 *value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *value = __kernel_ldwu(*(vusp)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-tsunami_read_config_dword(struct pci_dev *dev, int where, u32 *value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *value = *(vuip)addr;
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-tsunami_write_config_byte(struct pci_dev *dev, int where, u8 value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ switch (size) {
+ case 1:
+ *value = __kernel_ldbu(*(vucp)addr);
+ break;
+ case 2:
+ *value = __kernel_ldwu(*(vusp)addr);
+ break;
+ case 4:
+ *value = *(vuip)addr;
+ break;
+ }
- __kernel_stb(value, *(vucp)addr);
- mb();
- __kernel_ldbu(*(vucp)addr);
return PCIBIOS_SUCCESSFUL;
}
static int
-tsunami_write_config_word(struct pci_dev *dev, int where, u16 value)
+tsunami_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(dev, where, &addr, &type1))
+ if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- __kernel_stw(value, *(vusp)addr);
- mb();
- __kernel_ldwu(*(vusp)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-tsunami_write_config_dword(struct pci_dev *dev, int where, u32 value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ switch (size) {
+ case 1:
+ __kernel_stb(value, *(vucp)addr);
+ mb();
+ __kernel_ldbu(*(vucp)addr);
+ break;
+ case 2:
+ __kernel_stw(value, *(vusp)addr);
+ mb();
+ __kernel_ldwu(*(vusp)addr);
+ break;
+ case 4:
+ *(vuip)addr = value;
+ mb();
+ *(vuip)addr;
+ break;
+ }
- *(vuip)addr = value;
- mb();
- *(vuip)addr;
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops tsunami_pci_ops =
{
- read_byte: tsunami_read_config_byte,
- read_word: tsunami_read_config_word,
- read_dword: tsunami_read_config_dword,
- write_byte: tsunami_write_config_byte,
- write_word: tsunami_write_config_word,
- write_dword: tsunami_write_config_dword
+ .read = tsunami_read_config,
+ .write = tsunami_write_config,
};
void
@@ -350,10 +317,17 @@ tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
* Window 0 is scatter-gather 8MB at 8MB (for isa)
* Window 1 is scatter-gather (up to) 1GB at 1GB
* Window 2 is direct access 2GB at 2GB
+ *
+ * NOTE: we need the align_entry settings for Acer devices on ES40,
+ * specifically floppy and IDE when memory is larger than 2GB.
*/
hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
+ /* Initially set for 4 PTEs, but will be overridden to 64K for ISA. */
+ hose->sg_isa->align_entry = 4;
+
hose->sg_pci = iommu_arena_new(hose, 0x40000000,
size_for_memory(0x40000000), 0);
+ hose->sg_pci->align_entry = 4; /* Tsunami caches 4 PTEs at a time */
__direct_map_base = 0x80000000;
__direct_map_size = 0x80000000;
diff --git a/arch/alpha/kernel/core_wildfire.c b/arch/alpha/kernel/core_wildfire.c
index cf27355f98ef..10b77131e080 100644
--- a/arch/alpha/kernel/core_wildfire.c
+++ b/arch/alpha/kernel/core_wildfire.c
@@ -357,19 +357,18 @@ wildfire_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
}
static int
-mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
- unsigned char *type1)
+mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
+ unsigned long *pci_addr, unsigned char *type1)
{
- struct pci_controller *hose = dev->sysdata;
+ struct pci_controller *hose = pbus->sysdata;
unsigned long addr;
- u8 bus = dev->bus->number;
- u8 device_fn = dev->devfn;
+ u8 bus = pbus->number;
DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
"pci_addr=0x%p, type1=0x%p)\n",
bus, device_fn, where, pci_addr, type1));
- if (hose->first_busno == dev->bus->number)
+ if (hose->first_busno == bus)
bus = 0;
*type1 = (bus != 0);
@@ -382,97 +381,65 @@ mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
}
static int
-wildfire_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+wildfire_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(dev, where, &addr, &type1))
+ if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- *value = __kernel_ldbu(*(vucp)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-wildfire_read_config_word(struct pci_dev *dev, int where, u16 *value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *value = __kernel_ldwu(*(vusp)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-wildfire_read_config_dword(struct pci_dev *dev, int where, u32 *value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *value = *(vuip)addr;
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-wildfire_write_config_byte(struct pci_dev *dev, int where, u8 value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ switch (size) {
+ case 1:
+ *value = __kernel_ldbu(*(vucp)addr);
+ break;
+ case 2:
+ *value = __kernel_ldwu(*(vusp)addr);
+ break;
+ case 4:
+ *value = *(vuip)addr;
+ break;
+ }
- __kernel_stb(value, *(vucp)addr);
- mb();
- __kernel_ldbu(*(vucp)addr);
return PCIBIOS_SUCCESSFUL;
}
static int
-wildfire_write_config_word(struct pci_dev *dev, int where, u16 value)
+wildfire_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
{
unsigned long addr;
unsigned char type1;
- if (mk_conf_addr(dev, where, &addr, &type1))
+ if (mk_conf_addr(bus, devfn, where, &addr, &type1))
return PCIBIOS_DEVICE_NOT_FOUND;
- __kernel_stw(value, *(vusp)addr);
- mb();
- __kernel_ldwu(*(vusp)addr);
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-wildfire_write_config_dword(struct pci_dev *dev, int where, u32 value)
-{
- unsigned long addr;
- unsigned char type1;
-
- if (mk_conf_addr(dev, where, &addr, &type1))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ switch (size) {
+ case 1:
+ __kernel_stb(value, *(vucp)addr);
+ mb();
+ __kernel_ldbu(*(vucp)addr);
+ break;
+ case 2:
+ __kernel_stw(value, *(vusp)addr);
+ mb();
+ __kernel_ldwu(*(vusp)addr);
+ break;
+ case 4:
+ *(vuip)addr = value;
+ mb();
+ *(vuip)addr;
+ break;
+ }
- *(vuip)addr = value;
- mb();
- *(vuip)addr;
return PCIBIOS_SUCCESSFUL;
}
struct pci_ops wildfire_pci_ops =
{
- read_byte: wildfire_read_config_byte,
- read_word: wildfire_read_config_word,
- read_dword: wildfire_read_config_dword,
- write_byte: wildfire_write_config_byte,
- write_word: wildfire_write_config_word,
- write_dword: wildfire_write_config_dword
+ .read = wildfire_read_config,
+ .write = wildfire_write_config,
};
#if DEBUG_DUMP_REGS
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 71bff0b02488..ff03ca642089 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -12,11 +12,11 @@
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
#include <linux/signal.h>
#include <linux/sched.h>
+#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/random.h>
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index c6cda4e39dae..cb74c9705cad 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -97,15 +97,22 @@ quirk_cypress(struct pci_dev *dev)
way to turn this off. The bridge also supports several extended
BIOS ranges (disabled after power-up), and some consoles do turn
them on. So if we use a large direct-map window, or a large SG
- window, we must avoid entire 0xfff00000-0xffffffff region. */
+ window, we must avoid the entire 0xfff00000-0xffffffff region. */
else if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA) {
- if (__direct_map_base + __direct_map_size >= 0xfff00000)
- __direct_map_size = 0xfff00000 - __direct_map_base;
- else {
+#define DMAPSZ (max_low_pfn << PAGE_SHIFT) /* memory size, not window size */
+ if ((__direct_map_base + DMAPSZ - 1) >= 0xfff00000UL) {
+ __direct_map_size = 0xfff00000UL - __direct_map_base;
+ printk("%s: adjusting direct map size to 0x%x\n",
+ __FUNCTION__, __direct_map_size);
+ } else {
struct pci_controller *hose = dev->sysdata;
struct pci_iommu_arena *pci = hose->sg_pci;
- if (pci && pci->dma_base + pci->size >= 0xfff00000)
- pci->size = 0xfff00000 - pci->dma_base;
+ if (pci &&
+ (pci->dma_base + pci->size - 1) >= 0xfff00000UL) {
+ pci->size = 0xfff00000UL - pci->dma_base;
+ printk("%s: adjusting PCI S/G size to 0x%x\n",
+ __FUNCTION__, pci->size);
+ }
}
}
}
diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h
index e850b911789d..7139e6c2da71 100644
--- a/arch/alpha/kernel/pci_impl.h
+++ b/arch/alpha/kernel/pci_impl.h
@@ -52,15 +52,16 @@ struct pci_iommu_arena;
#define APECS_AND_LCA_DEFAULT_MEM_BASE ((16+2)*1024*1024)
/*
- * Because the MCPCIA core logic supports more bits for physical addresses,
- * it should allow an expanded range of SPARSE memory addresses.
- * However, we do not use them all, in order to avoid the HAE manipulation
- * that would be needed.
+ * Because MCPCIA and T2 core logic support more bits for
+ * physical addresses, they should allow an expanded range of SPARSE
+ * memory addresses. However, we do not use them all, in order to
+ * avoid the HAE manipulation that would be needed.
*/
#define MCPCIA_DEFAULT_MEM_BASE ((32+2)*1024*1024)
+#define T2_DEFAULT_MEM_BASE ((16+1)*1024*1024)
/*
- * Because CIA and PYXIS and T2 have more bits for physical addresses,
+ * Because CIA and PYXIS have more bits for physical addresses,
* they support an expanded range of SPARSE memory addresses.
*/
#define DEFAULT_MEM_BASE ((128+16)*1024*1024)
@@ -157,8 +158,6 @@ extern struct resource *alloc_resource(void);
extern struct pci_iommu_arena *iommu_arena_new(struct pci_controller *,
dma_addr_t, unsigned long,
unsigned long);
-extern long iommu_arena_alloc(struct pci_iommu_arena *arena, long n);
-
extern const char *const pci_io_names[];
extern const char *const pci_mem_names[];
extern const char pci_hae0_name[];
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index f85e4bfb5f52..72f574168a00 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -30,6 +30,9 @@
#define DEBUG_NODIRECT 0
#define DEBUG_FORCEDAC 0
+/* Most Alphas support 32-bit ISA DMA. Exceptions are XL, Ruffian,
+ Nautilus, Sable, and Alcor (see asm-alpha/dma.h for details). */
+#define ISA_DMA_MASK (MAX_DMA_ADDRESS - IDENT_ADDR - 1)
static inline unsigned long
mk_iommu_pte(unsigned long paddr)
@@ -129,8 +132,8 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask)
return p;
}
-long
-iommu_arena_alloc(struct pci_iommu_arena *arena, long n)
+static long
+iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align)
{
unsigned long flags;
unsigned long *ptes;
@@ -140,7 +143,7 @@ iommu_arena_alloc(struct pci_iommu_arena *arena, long n)
/* Search for N empty ptes */
ptes = arena->ptes;
- mask = arena->align_entry - 1;
+ mask = max(align, arena->align_entry) - 1;
p = iommu_arena_find_pages(arena, n, mask);
if (p < 0) {
spin_unlock_irqrestore(&arena->lock, flags);
@@ -181,7 +184,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
int dac_allowed)
{
struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose;
- dma_addr_t max_dma = pdev ? pdev->dma_mask : 0x00ffffff;
+ dma_addr_t max_dma = pdev ? pdev->dma_mask : ISA_DMA_MASK;
struct pci_iommu_arena *arena;
long npages, dma_ofs, i;
unsigned long paddr;
@@ -232,7 +235,8 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
arena = hose->sg_isa;
npages = calc_npages((paddr & ~PAGE_MASK) + size);
- dma_ofs = iommu_arena_alloc(arena, npages);
+ /* Force allocation to 64KB boundary for all ISA devices. */
+ dma_ofs = iommu_arena_alloc(arena, npages, pdev ? 8 : 0);
if (dma_ofs < 0) {
printk(KERN_WARNING "pci_map_single failed: "
"could not allocate dma page tables\n");
@@ -499,7 +503,7 @@ sg_fill(struct scatterlist *leader, struct scatterlist *end,
paddr &= ~PAGE_MASK;
npages = calc_npages(paddr + size);
- dma_ofs = iommu_arena_alloc(arena, npages);
+ dma_ofs = iommu_arena_alloc(arena, npages, 0);
if (dma_ofs < 0) {
/* If we attempted a direct map above but failed, die. */
if (leader->dma_address == 0)
@@ -588,7 +592,7 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
/* Second, figure out where we're going to map things. */
if (alpha_mv.mv_pci_tbi) {
hose = pdev ? pdev->sysdata : pci_isa_hose;
- max_dma = pdev ? pdev->dma_mask : 0x00ffffff;
+ max_dma = pdev ? pdev->dma_mask : ISA_DMA_MASK;
arena = hose->sg_pci;
if (!arena || arena->dma_base + arena->size - 1 > max_dma)
arena = hose->sg_isa;
@@ -651,7 +655,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
return;
hose = pdev ? pdev->sysdata : pci_isa_hose;
- max_dma = pdev ? pdev->dma_mask : 0x00ffffff;
+ max_dma = pdev ? pdev->dma_mask : ISA_DMA_MASK;
arena = hose->sg_pci;
if (!arena || arena->dma_base + arena->size - 1 > max_dma)
arena = hose->sg_isa;
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index ae466ff90696..b0cd16ef9493 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -261,11 +261,13 @@ alpha_clone(unsigned long clone_flags, unsigned long usp,
struct switch_stack * swstack)
{
struct task_struct *p;
+ struct pt_regs *u_regs = (struct pt_regs *) (swstack+1);
+ int *user_tid = (int *)u_regs->r19;
+
if (!usp)
usp = rdusp();
- p = do_fork(clone_flags & ~CLONE_IDLETASK,
- usp, (struct pt_regs *) (swstack+1), 0);
+ p = do_fork(clone_flags & ~CLONE_IDLETASK, usp, u_regs, 0, user_tid);
return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
@@ -274,7 +276,7 @@ alpha_vfork(struct switch_stack * swstack)
{
struct task_struct *p;
p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(),
- (struct pt_regs *) (swstack+1), 0);
+ (struct pt_regs *) (swstack+1), 0, NULL);
return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index 746869cb1145..f27e767155c3 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -59,7 +59,7 @@ extern void polaris_machine_check(u64, u64, struct pt_regs *);
extern struct pci_ops t2_pci_ops;
extern void t2_init_arch(void);
extern void t2_machine_check(u64, u64, struct pt_regs *);
-#define t2_pci_tbi ((void *)0)
+extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_titan.c */
extern struct pci_ops titan_pci_ops;
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index b328c280aa95..160a9ba454ae 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -432,7 +432,7 @@ fork_by_hand(void)
/* Don't care about the contents of regs since we'll never
reschedule the forked task. */
struct pt_regs regs;
- return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0);
+ return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL);
}
/*
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index 1b17a6a0e364..fa32465ab44f 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -251,7 +251,7 @@ struct alpha_machine_vector alcor_mv __initmv = {
DO_CIA_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
- max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ max_dma_address: ALPHA_ALCOR_MAX_DMA_ADDRESS,
min_io_address: EISA_DEFAULT_IO_BASE,
min_mem_address: CIA_DEFAULT_MEM_BASE,
diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c
index 36aa640556e8..48214ff70abc 100644
--- a/arch/alpha/kernel/sys_rx164.c
+++ b/arch/alpha/kernel/sys_rx164.c
@@ -35,16 +35,15 @@
/* Note mask bit is true for ENABLED irqs. */
static unsigned long cached_irq_mask;
-/* Bus 0, Device 0. Nothing else matters, since we invoke the
- POLARIS routines directly. */
-static struct pci_dev rx164_system;
-
static inline void
rx164_update_irq_hw(unsigned long mask)
{
- unsigned int temp;
- polaris_write_config_dword(&rx164_system, 0x74, mask);
- polaris_read_config_dword(&rx164_system, 0x74, &temp);
+ volatile unsigned int *irq_mask;
+
+ irq_mask = (void *)(POLARIS_DENSE_CONFIG_BASE + 0x74);
+ *irq_mask = mask;
+ mb();
+ *irq_mask;
}
static inline void
@@ -86,14 +85,14 @@ static struct hw_interrupt_type rx164_irq_type = {
static void
rx164_device_interrupt(unsigned long vector, struct pt_regs *regs)
{
- unsigned int temp;
unsigned long pld;
+ volatile unsigned int *dirr;
long i;
/* Read the interrupt summary register. On Polaris, this is
the DIRR register in PCI config space (offset 0x84). */
- polaris_read_config_dword(&rx164_system, 0x84, &temp);
- pld = temp;
+ dirr = (void *)(POLARIS_DENSE_CONFIG_BASE + 0x84);
+ pld = *dirr;
/*
* Now for every possible bit set, work through them and call
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index 6255f9cab307..dc35fe7ea125 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -290,9 +290,9 @@ struct alpha_machine_vector sable_mv __initmv = {
DO_T2_IO,
DO_T2_BUS,
machine_check: t2_machine_check,
- max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ max_dma_address: ALPHA_SABLE_MAX_DMA_ADDRESS,
min_io_address: EISA_DEFAULT_IO_BASE,
- min_mem_address: DEFAULT_MEM_BASE,
+ min_mem_address: T2_DEFAULT_MEM_BASE,
nr_irqs: 40,
device_interrupt: sable_srm_device_interrupt,
@@ -322,9 +322,9 @@ struct alpha_machine_vector sable_gamma_mv __initmv = {
DO_T2_IO,
DO_T2_BUS,
machine_check: t2_machine_check,
- max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ max_dma_address: ALPHA_SABLE_MAX_DMA_ADDRESS,
min_io_address: EISA_DEFAULT_IO_BASE,
- min_mem_address: DEFAULT_MEM_BASE,
+ min_mem_address: T2_DEFAULT_MEM_BASE,
nr_irqs: 40,
device_interrupt: sable_srm_device_interrupt,
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 93a569828d70..00ee0c01b001 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -185,8 +185,8 @@ validate_cc_value(unsigned long cc)
unsigned int min, max;
} cpu_hz[] __initdata = {
[EV3_CPU] = { 50000000, 200000000 }, /* guess */
- [EV4_CPU] = { 150000000, 300000000 },
- [LCA4_CPU] = { 150000000, 300000000 }, /* guess */
+ [EV4_CPU] = { 100000000, 300000000 },
+ [LCA4_CPU] = { 100000000, 300000000 }, /* guess */
[EV45_CPU] = { 200000000, 300000000 },
[EV5_CPU] = { 250000000, 433000000 },
[EV56_CPU] = { 333000000, 667000000 },
@@ -257,12 +257,12 @@ calibrate_cc_with_pic(void)
cc = rpcc();
do {
- count++;
+ count+=100; /* by 1 takes too long to timeout from 0 */
} while ((inb(0x61) & 0x20) == 0 && count > 0);
cc = rpcc() - cc;
/* Error: ECTCNEVERSET or ECPUTOOFAST. */
- if (count <= 1)
+ if (count <= 100)
return 0;
/* Error: ECPUTOOSLOW. */
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index a7542ecac525..c90a631a8720 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -29,6 +29,7 @@
*/
static int opDEC_testing = 0;
static int opDEC_fix = 0;
+static int opDEC_checked = 0;
static unsigned long opDEC_test_pc = 0;
static void
@@ -36,6 +37,8 @@ opDEC_check(void)
{
unsigned long test_pc;
+ if (opDEC_checked) return;
+
lock_kernel();
opDEC_testing = 1;
@@ -48,6 +51,7 @@ opDEC_check(void)
: );
opDEC_testing = 0;
+ opDEC_checked = 1;
unlock_kernel();
}
diff --git a/arch/i386/kernel/init_task.c b/arch/i386/kernel/init_task.c
index f652f279b787..4eb40a9582c7 100644
--- a/arch/i386/kernel/init_task.c
+++ b/arch/i386/kernel/init_task.c
@@ -10,7 +10,7 @@
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
-static struct signal_struct init_signals = INIT_SIGNALS;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
struct mm_struct init_mm = INIT_MM(init_mm);
/*
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 7165d0fd549f..ca5e8fa1b9eb 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -166,6 +166,22 @@ static void __init pci_fixup_via_northbridge_bug(struct pci_dev *d)
}
}
+/*
+ * For some reasons Intel decided that certain parts of their
+ * 815, 845 and some other chipsets must look like PCI-to-PCI bridges
+ * while they are obviously not. The 82801 family (AA, AB, BAM/CAM,
+ * BA/CA/DB and E) PCI bridges are actually HUB-to-PCI ones, according
+ * to Intel terminology. These devices do forward all addresses from
+ * system to PCI bus no matter what are their window settings, so they are
+ * "transparent" (or subtractive decoding) from programmers point of view.
+ */
+static void __init pci_fixup_transparent_bridge(struct pci_dev *dev)
+{
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ (dev->device & 0xff00) == 0x2400)
+ dev->transparent = 1;
+}
+
struct pci_fixup pcibios_fixups[] = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx },
@@ -183,5 +199,6 @@ struct pci_fixup pcibios_fixups[] = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, pci_fixup_ncr53c810 },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixup_transparent_bridge },
{ 0 }
};
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 1d7c7eb5dcf4..65ed61f1344c 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -102,7 +102,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
#endif /* !CONFIG_4xx */
#endif /* CONFIG_XMON || CONFIG_KGDB */
- if (in_interrupt() || mm == NULL) {
+ if (in_atomic() || mm == NULL) {
bad_page_fault(regs, address, SIGSEGV);
return;
}
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 49eccf61be1d..e07d4d1017a9 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -233,7 +233,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
- if (in_interrupt() || !mm)
+ if (in_atomic() || !mm)
goto no_context;
down_read(&mm->mmap_sem);
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
index d1f952e1643b..55df18f1a484 100644
--- a/drivers/acorn/block/mfmhd.c
+++ b/drivers/acorn/block/mfmhd.c
@@ -193,8 +193,6 @@ struct mfm_info {
#define MFM_DRV_INFO mfm_info[raw_cmd.dev]
-static struct hd_struct mfm[MFM_MAXDRIVES << 6];
-
/* Stuff from the assembly routines */
extern unsigned int hdc63463_baseaddress; /* Controller base address */
extern unsigned int hdc63463_irqpolladdress; /* Address to read to test for int */
@@ -882,6 +880,20 @@ static void mfm_rerequest(void)
mfm_request();
}
+static struct gendisk mfm_gendisk[2] = {
+{
+ .major = MAJOR_NR,
+ .first_minor = 0,
+ .major_name = "mfma",
+ .minor_shift = 6,
+},
+{
+ .major = MAJOR_NR,
+ .first_minor = 64,
+ .major_name = "mfmb",
+ .minor_shift = 6,
+};
+
static void mfm_request(void)
{
DBG("mfm_request CURRENT=%p Busy=%d\n", CURRENT, Busy);
@@ -895,7 +907,7 @@ static void mfm_request(void)
Busy = 1;
while (1) {
- unsigned int dev, block, nsect;
+ unsigned int dev, block, nsect, unit;
DBG("mfm_request: loop start\n");
sti();
@@ -912,26 +924,26 @@ static void mfm_request(void)
DBG("mfm_request: before arg extraction\n");
dev = minor(CURRENT->rq_dev);
+ unit = dev>>6;
block = CURRENT->sector;
nsect = CURRENT->nr_sectors;
#ifdef DEBUG
- /*if ((dev>>6)==1) */ console_printf("mfm_request: raw vals: dev=%d (block=512 bytes) block=%d nblocks=%d\n", dev, block, nsect);
+ /*if (unit==1) */ console_printf("mfm_request: raw vals: dev=%d (block=512 bytes) block=%d nblocks=%d\n", dev, block, nsect);
#endif
- if (dev >= (mfm_drives << 6) ||
- block >= mfm[dev].nr_sects || ((block+nsect) > mfm[dev].nr_sects)) {
- if (dev >= (mfm_drives << 6))
+ if (unit >= mfm_drives ||
+ block >= get_capacity(mfm_gendisk + unit) ||
+ ((block+nsect) > get_capacity(mfm_gendisk + unit))) {
+ if (unit >= mfm_drives)
printk("mfm: bad minor number: device=%s\n", kdevname(CURRENT->rq_dev));
else
- printk("mfm%c: bad access: block=%d, count=%d, nr_sects=%ld\n", (dev >> 6)+'a',
- block, nsect, mfm[dev].nr_sects);
+ printk("mfm%c: bad access: block=%d, count=%d, nr_sects=%ld\n", unit+'a',
+ block, nsect, get_capacity(mfm_gendisk+unit));
printk("mfm: continue 1\n");
end_request(CURRENT, 0);
Busy = 0;
continue;
}
- block += mfm[dev].start_sect;
-
/* DAG: Linux doesn't cope with this - even though it has an array telling
it the hardware block size - silly */
block <<= 1; /* Now in 256 byte sectors */
@@ -1163,18 +1175,9 @@ static int mfm_initdrives(void)
static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg)
{
struct hd_geometry *geo = (struct hd_geometry *) arg;
- kdev_t dev;
- int device, minor, err;
-
- if (!inode || !(dev = inode->i_rdev))
- return -EINVAL;
-
- minor = minor(dev);
-
- device = DEVICE_NR(minor(inode->i_rdev)), err;
+ int device = DEVICE_NR(minor(inode->i_rdev));
if (device >= mfm_drives)
return -EINVAL;
-
if (cmd != HDIO_GETGEO)
return -EINVAL;
if (!arg)
@@ -1185,7 +1188,8 @@ static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long a
return -EFAULT;
if (put_user (mfm_info[device].cylinders, &geo->cylinders))
return -EFAULT;
- if (put_user (mfm[minor].start_sect, &geo->start))
+ start = get_start_sect(inode->i_bdev);
+ if (put_user (get_start_sect(inode->i_bdev), &geo->start))
return -EFAULT;
return 0;
}
@@ -1237,27 +1241,10 @@ void xd_set_geometry(struct block_device *bdev, unsigned char secsptrack,
if (raw_cmd.dev == drive)
mfm_specify ();
mfm_geometry (drive);
- mfm[drive << 6].start_sect = 0;
- mfm[drive << 6].nr_sects = mfm_info[drive].cylinders * mfm_info[drive].heads * mfm_info[drive].sectors / 2;
+ set_capacity(&mfm_gendisk[drive], mfm_info[drive].cylinders * mfm_info[drive].heads * mfm_info[drive].sectors / 2);
}
}
-static struct gendisk mfm_gendisk[2] = {
-{
- .major = MAJOR_NR,
- .first_minor = 0,
- .major_name = "mfma",
- .minor_shift = 6,
- .part = mfm,
-},
-{
- .major = MAJOR_NR,
- .first_minor = 64,
- .major_name = "mfmb",
- .minor_shift = 6,
- .part = mfm + 64,
-};
-
static struct block_device_operations mfm_fops =
{
.owner = THIS_MODULE,
@@ -1280,7 +1267,6 @@ static void mfm_geninit (void)
outw(0x80, mfm_irqenable); /* Required to enable IRQs from MFM podule */
for (i = 0; i < mfm_drives; i++) {
- mfm_gendisk[i].nr_real = 1;
add_gendisk(mfm_gendisk + i);
mfm_geometry (i);
register_disk(mfm_gendisk + i, mk_kdev(MAJOR_NR,i<<6), 1<<6,
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 4256cbb35e78..989f13e46e8f 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -1968,12 +1968,10 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
struct gendisk *disk = &Controller->disks[n];
memset(disk, 0, sizeof(struct gendisk));
sprintf(names + 9 * n, "rd/c%dd%d", Controller->ControllerNumber, n);
- disk->part = Controller->DiskPartitions + (n<<DAC960_MaxPartitionsBits);
disk->major = MajorNumber;
disk->first_minor = n << DAC960_MaxPartitionsBits;
disk->major_name = names + 9 * n;
disk->minor_shift = DAC960_MaxPartitionsBits;
- disk->nr_real = 1;
disk->fops = &DAC960_BlockDeviceOperations;
add_gendisk(disk);
}
@@ -2034,10 +2032,9 @@ static long disk_size(DAC960_Controller_T *Controller, int disk)
static void DAC960_ComputeGenericDiskInfo(DAC960_Controller_T *Controller)
{
- struct gendisk *disks = Controller->disks;
int disk;
for (disk = 0; disk < DAC960_MaxLogicalDrives; disk++)
- disks->part[0].nr_sects = disk_size(Controller, disk);
+ set_capacity(Controller->disks + disk, disk_size(Controller, disk));
}
static int DAC960_revalidate(kdev_t dev)
@@ -2045,7 +2042,7 @@ static int DAC960_revalidate(kdev_t dev)
int ctlr = DAC960_ControllerNumber(dev);
int disk = DAC960_LogicalDriveNumber(dev);
DAC960_Controller_T *p = DAC960_Controllers[ctlr];
- p->disks[disk].part[0].nr_sects = disk_size(p, disk);
+ set_capacity(&p->disks[disk], disk_size(p, disk));
return 0;
}
@@ -5277,7 +5274,7 @@ static int DAC960_Open(Inode_T *Inode, File_T *File)
DAC960_KernelDevice(Controller->ControllerNumber, LogicalDriveNumber, 0),
DAC960_MaxPartitions, &DAC960_BlockDeviceOperations, size);
}
- if (Controller->disks[LogicalDriveNumber].part[0].nr_sects == 0)
+ if (!get_capacity(&Controller->disks[LogicalDriveNumber]))
return -ENXIO;
/*
Increment Controller and Logical Drive Usage Counts.
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index 53b4bcb47d5a..33b2822520e3 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -2196,7 +2196,6 @@ typedef struct file File_T;
typedef struct block_device_operations BlockDeviceOperations_T;
typedef struct completion Completion_T;
typedef struct hd_geometry DiskGeometry_T;
-typedef struct hd_struct DiskPartition_T;
typedef struct inode Inode_T;
typedef struct inode_operations InodeOperations_T;
typedef kdev_t KernelDevice_T;
@@ -2472,7 +2471,6 @@ typedef struct DAC960_Controller
boolean LogicalDriveFoundDuringScan[DAC960_MaxLogicalDrives];
} V2;
} FW;
- DiskPartition_T DiskPartitions[DAC960_MinorCount];
unsigned char ProgressBuffer[DAC960_ProgressBufferSize];
unsigned char UserStatusBuffer[DAC960_UserMessageSize];
}
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
index ff0480293480..3313f7cb0a3c 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -245,7 +245,6 @@ char *acsi_buffer;
unsigned long phys_acsi_buffer;
static int NDevices;
-static struct hd_struct acsi_part[MAX_DEV<<4];
static char acsi_names[MAX_DEV*4];
static int access_count[MAX_DEV];
@@ -783,7 +782,7 @@ static void read_intr( void )
status = acsi_getstatus();
if (status != 0) {
- int dev = minor(CURRENT->rq_dev);
+ int dev = DEVICE_NR(CURRENT->rq_dev);
printk( KERN_ERR "ad%c: ", dev+'a' );
if (!acsi_reqsense( acsi_buffer, acsi_info[dev].target,
acsi_info[dev].lun))
@@ -814,7 +813,7 @@ static void write_intr(void)
status = acsi_getstatus();
if (status != 0) {
- int dev = minor(CURRENT->rq_dev);
+ int dev = DEVICE_NR(CURRENT->rq_dev);
printk( KERN_ERR "ad%c: ", dev+'a' );
if (!acsi_reqsense( acsi_buffer, acsi_info[dev].target,
acsi_info[dev].lun))
@@ -973,15 +972,15 @@ static void redo_acsi_request( void )
panic(DEVICE_NAME ": block not locked");
}
- dev = minor(CURRENT->rq_dev);
+ dev = DEVICE_NR(CURRENT->rq_dev);
block = CURRENT->sector;
if (dev >= NDevices ||
- block+CURRENT->nr_sectors >= acsi_part[dev].nr_sects) {
+ block+CURRENT->nr_sectors >= get_capacity(acsi_gendisk + dev)) {
#ifdef DEBUG
printk( "ad%c: attempted access for blocks %d...%ld past end of device at block %ld.\n",
dev+'a',
block, block + CURRENT->nr_sectors - 1,
- acsi_part[dev].nr_sects);
+ get_capacity(acsi_gendisk + dev));
#endif
end_request(CURRENT, 0);
goto repeat;
@@ -1088,11 +1087,7 @@ static void redo_acsi_request( void )
static int acsi_ioctl( struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg )
{
- dev_t dev;
-
- if (!inode)
- return -EINVAL;
- dev = minor(inode->i_rdev);
+ int dev = DEVICE_NR(inode->i_rdev);
if (dev >= NDevices)
return -EINVAL;
switch (cmd) {
@@ -1140,7 +1135,7 @@ static int acsi_open( struct inode * inode, struct file * filp )
int device;
struct acsi_info_struct *aip;
- device = minor(inode->i_rdev);
+ device = DEVICE_NR(inode->i_rdev);
if (device >= NDevices)
return -ENXIO;
aip = &acsi_info[device];
@@ -1176,7 +1171,7 @@ static int acsi_open( struct inode * inode, struct file * filp )
static int acsi_release( struct inode * inode, struct file * file )
{
- int device = minor(inode->i_rdev);
+ int device = DEVICE_NR(inode->i_rdev);
if (--access_count[device] == 0 && acsi_info[device].removable)
acsi_prevent_removal(device, 0);
return( 0 );
@@ -1204,7 +1199,7 @@ static void acsi_prevent_removal(int device, int flag)
static int acsi_media_change (kdev_t dev)
{
- int device = minor(dev);
+ int device = DEVICE_NR(dev);
struct acsi_info_struct *aip;
aip = &acsi_info[device];
@@ -1702,9 +1697,7 @@ static void acsi_geninit(void)
disk->first_minor = i << 4;
disk->major_name = acsi_names + 4*i;
disk->minor_shift = (acsi_info[i].type==HARDDISK)?4:0;
- disk->part = acsi_part + (i<<4);
disk->fops = &acsi_fops;
- disk->nr_real = 1;
add_gendisk(disk);
register_disk(disk, mk_kdev(disk->major, disk->first_minor),
1<<disk->minor_shift,
@@ -1808,7 +1801,7 @@ void cleanup_module(void)
static int acsi_revalidate(kdev_t dev)
{
- int unit = DEVICE_NR(minor(dev));
+ int unit = DEVICE_NR(dev);
struct acsi_info_struct *aip = &acsi_info[unit];
stdma_lock( NULL, NULL );
if (acsi_devinit(aip) != DEV_SUPPORTED) {
@@ -1822,6 +1815,6 @@ static int acsi_revalidate(kdev_t dev)
ENABLE_IRQ();
stdma_release();
- acsi_part[minor(dev)].nr_sects = aip->size;
+ set_capacity(acsi_gendisk + unit, aip->size);
return 0;
}
diff --git a/drivers/block/blkpg.c b/drivers/block/blkpg.c
index 1d13a84a9919..941d1051d894 100644
--- a/drivers/block/blkpg.c
+++ b/drivers/block/blkpg.c
@@ -71,7 +71,6 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
long pstart, plength;
int i;
kdev_t dev = to_kdev_t(bdev->bd_dev);
- struct hd_struct *part;
/* convert bytes to sectors, check for fit in a hd_struct */
ppstart = (p->start >> 9);
@@ -86,7 +85,6 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
g = get_gendisk(dev);
if (!g)
return -ENXIO;
- part = g->part + minor(dev) - g->first_minor;
/* existing drive? */
@@ -97,19 +95,19 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
return -EINVAL;
/* partition number in use? */
- if (part[p->pno].nr_sects != 0)
+ if (g->part[p->pno - 1].nr_sects != 0)
return -EBUSY;
/* overlap? */
- for (i = 1; i < (1<<g->minor_shift); i++)
- if (!(pstart+plength <= part[i].start_sect ||
- pstart >= part[i].start_sect + part[i].nr_sects))
+ for (i = 0; i < (1<<g->minor_shift) - 1; i++)
+ if (!(pstart+plength <= g->part[i].start_sect ||
+ pstart >= g->part[i].start_sect + g->part[i].nr_sects))
return -EBUSY;
/* all seems OK */
- part[p->pno].start_sect = pstart;
- part[p->pno].nr_sects = plength;
- devfs_register_partitions (g, minor(dev), 0);
+ g->part[p->pno - 1].start_sect = pstart;
+ g->part[p->pno - 1].nr_sects = plength;
+ update_partition(g, p->pno);
return 0;
}
@@ -128,22 +126,19 @@ int del_partition(struct block_device *bdev, struct blkpg_partition *p)
kdev_t dev = to_kdev_t(bdev->bd_dev);
struct gendisk *g;
struct block_device *bdevp;
- struct hd_struct *part;
int holder;
/* find the drive major */
g = get_gendisk(dev);
if (!g)
return -ENXIO;
- part = g->part + minor(dev) - g->first_minor;
-
if (bdev != bdev->bd_contains)
return -EINVAL;
if (p->pno <= 0 || p->pno >= (1 << g->minor_shift))
return -EINVAL;
/* existing drive and partition? */
- if (part[p->pno].nr_sects == 0)
+ if (g->part[p->pno - 1].nr_sects == 0)
return -ENXIO;
/* partition in use? Incomplete check for now. */
@@ -159,9 +154,9 @@ int del_partition(struct block_device *bdev, struct blkpg_partition *p)
fsync_bdev(bdevp);
invalidate_bdev(bdevp, 0);
- part[p->pno].start_sect = 0;
- part[p->pno].nr_sects = 0;
- devfs_register_partitions (g, minor(dev), 0);
+ g->part[p->pno - 1].start_sect = 0;
+ g->part[p->pno - 1].nr_sects = 0;
+ update_partition(g, p->pno);
bd_release(bdevp);
bdput(bdevp);
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index db3d25ebfd35..0b8fb9a5c7a5 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -407,8 +407,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
driver_geo.sectors = 0x3f;
driver_geo.cylinders = hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f);
}
- driver_geo.start=
- hba[ctlr]->hd[minor(inode->i_rdev)].start_sect;
+ driver_geo.start= get_start_sect(inode->i_bdev);
if (copy_to_user((void *) arg, &driver_geo,
sizeof( struct hd_geometry)))
return -EFAULT;
@@ -705,7 +704,7 @@ static int cciss_revalidate(kdev_t dev)
int ctlr = major(dev) - MAJOR_NR;
int target = minor(dev) >> NWD_SHIFT;
struct gendisk *disk = &hba[ctlr]->gendisk[target];
- disk->part[0].nr_sects = hba[ctlr]->drv[target].nr_blocks;
+ set_capacity(disk, hba[ctlr]->drv[target].nr_blocks);
return 0;
}
@@ -742,7 +741,6 @@ static int revalidate_allvol(kdev_t dev)
for(i=0; i< NWD; i++) {
struct gendisk *disk = &hba[ctlr]->gendisk[i];
if (disk->major_name) {
- wipe_partitions(mk_kdev(disk->major, disk->first_minor));
del_gendisk(disk);
disk->major_name = NULL;
}
@@ -752,7 +750,6 @@ static int revalidate_allvol(kdev_t dev)
* Set the partition and block size structures for all volumes
* on this controller to zero. We will reread all of this data
*/
- memset(hba[ctlr]->hd, 0, sizeof(struct hd_struct) * 256);
memset(hba[ctlr]->drv, 0, sizeof(drive_info_struct)
* CISS_MAX_LUN);
/*
@@ -802,7 +799,6 @@ static int deregister_disk(int ctlr, int logvol)
/* invalidate the devices and deregister the disk */
if (disk->major_name) {
- wipe_partitions(mk_kdev(disk->major, disk->first_minor));
del_gendisk(disk);
disk->major_name = NULL;
}
@@ -2448,8 +2444,6 @@ static int __init cciss_init_one(struct pci_dev *pdev,
disk->first_minor = j << NWD_SHIFT;
disk->major_name = NULL;
disk->minor_shift = NWD_SHIFT;
- disk->part = hba[i]->hd + (j << NWD_SHIFT);
- disk->nr_real = 1;
if( !(drv->nr_blocks))
continue;
(BLK_DEFAULT_QUEUE(MAJOR_NR + i))->hardsect_size = drv->block_size;
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 7192717a23fe..1baed4acef84 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -83,9 +83,6 @@ struct ctlr_info
// Disk structures we need to pass back
struct gendisk gendisk[NWD];
char names[12 * NWD];
- // indexed by minor numbers
- struct hd_struct hd[256];
- int sizes[256];
#ifdef CONFIG_CISS_SCSI_TAPE
void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
#endif
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index b9dfeb902e3c..aec445236fa0 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -75,7 +75,6 @@ MODULE_LICENSE("GPL");
static int nr_ctlr;
static ctlr_info_t *hba[MAX_CTLR];
-static devfs_handle_t de_arr[MAX_CTLR][NWD];
static int eisa[8];
@@ -103,7 +102,6 @@ static struct board_type products[] = {
{ 0x40580E11, "Smart Array 431", &smart4_access },
};
-static struct hd_struct * ida;
static char *ida_names;
static struct gendisk ida_gendisk[MAX_CTLR * NWD];
@@ -321,7 +319,6 @@ void cleanup_module(void)
}
devfs_find_and_unregister(NULL, "ida", 0, 0, 0, 0);
remove_proc_entry("cpqarray", proc_root_driver);
- kfree(ida);
kfree(ida_names);
}
#endif /* MODULE */
@@ -347,15 +344,12 @@ int __init cpqarray_init(void)
printk("Found %d controller(s)\n", nr_ctlr);
/* allocate space for disk structs */
- ida = kmalloc(sizeof(struct hd_struct)*nr_ctlr*NWD*16, GFP_KERNEL);
ida_names = kmalloc(nr_ctlr*NWD*10, GFP_KERNEL);
- if (!ida || !ida_names) {
+ if (!ida_names) {
printk( KERN_ERR "cpqarray: out of memory");
- kfree(ida);
kfree(ida_names);
return(num_cntlrs_reg);
}
- memset(ida, 0, sizeof(struct hd_struct)*nr_ctlr*NWD*16);
/*
* register block devices
* Find disks and fill in structs
@@ -408,7 +402,6 @@ int __init cpqarray_init(void)
if (num_cntlrs_reg == 0)
{
- kfree(ida);
kfree(ida_names);
}
return(num_cntlrs_reg);
@@ -450,9 +443,7 @@ int __init cpqarray_init(void)
disk->major = MAJOR_NR + i;
disk->first_minor = j<<NWD_SHIFT;
disk->minor_shift = NWD_SHIFT;
- disk->part = ida + i*256 + (j<<NWD_SHIFT);
- disk->nr_real = 1;
- disk->de_arr = &de_arr[i][j];
+ disk->flags = GENHD_FL_DEVFS;
disk->fops = &ida_fops;
if (!drv->nr_blks)
continue;
@@ -1461,11 +1452,9 @@ static int revalidate_allvol(kdev_t dev)
struct gendisk *disk = ida_gendisk + ctlr*NWD + i;
if (!disk->major_name)
continue;
- wipe_partitions(mk_kdev(disk->major, disk->first_minor));
del_gendisk(disk);
disk->major_name = NULL;
}
- memset(ida+(ctlr*256), 0, sizeof(struct hd_struct)*NWD*16);
memset(hba[ctlr]->drv, 0, sizeof(drv_info_t)*NWD);
/*
@@ -1500,7 +1489,7 @@ static int ida_revalidate(kdev_t dev)
int ctlr = major(dev) - MAJOR_NR;
int target = DEVICE_NR(dev);
struct gendisk *gdev = &ida_gendisk[ctlr*NWD+target];
- gdev->part[minor(dev)].nr_sects = hba[ctlr]->drv[target].nr_blks;
+ set_capacity(gdev, hba[ctlr]->drv[target].nr_blks);
return 0;
}
@@ -1667,6 +1656,7 @@ static void getgeometry(int ctlr)
(log_index < id_ctlr_buf->nr_drvs)
&& (log_unit < NWD);
log_unit++) {
+ struct gendisk *disk = ida_gendisk + ctlr * NWD + log_unit;
size = sizeof(sense_log_drv_stat_t);
@@ -1731,13 +1721,10 @@ static void getgeometry(int ctlr)
return;
}
- if (!de_arr[ctlr][log_unit]) {
+ if (!disk->de) {
char txt[16];
-
- sprintf(txt, "ida/c%dd%d", ctlr,
- log_unit);
- de_arr[ctlr][log_unit] =
- devfs_mk_dir(NULL, txt, NULL);
+ sprintf(txt,"ida/c%dd%d",ctlr,log_unit);
+ disk->de = devfs_mk_dir(NULL,txt,NULL);
}
info_p->phys_drives =
sense_config_buf->ctlr_phys_drv;
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index e17207282c98..51b77476e95f 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
static rwlock_t gendisk_lock;
@@ -43,6 +44,19 @@ void
add_gendisk(struct gendisk *gp)
{
struct gendisk *sgp;
+ struct hd_struct *p = NULL;
+
+ if (gp->minor_shift) {
+ size_t size = sizeof(struct hd_struct)*((1<<gp->minor_shift)-1);
+ p = kmalloc(size, GFP_KERNEL);
+ if (!p) {
+ printk(KERN_ERR "out of memory; no partitions for %s\n",
+ gp->major_name);
+ gp->minor_shift = 0;
+ } else
+ memset(p, 0, size);
+ }
+ gp->part = p;
write_lock(&gendisk_lock);
@@ -67,32 +81,20 @@ out:
}
EXPORT_SYMBOL(add_gendisk);
+EXPORT_SYMBOL(del_gendisk);
-
-/**
- * del_gendisk - remove partitioning information from kernel list
- * @gp: per-device partitioning information
- *
- * This function unregisters the partitioning information in @gp
- * with the kernel.
- */
-void
-del_gendisk(struct gendisk *gp)
+void unlink_gendisk(struct gendisk *disk)
{
- struct gendisk **gpp;
-
+ struct gendisk **p;
write_lock(&gendisk_lock);
- for (gpp = &gendisk_head; *gpp; gpp = &((*gpp)->next))
- if (*gpp == gp)
+ for (p = &gendisk_head; *p; p = &((*p)->next))
+ if (*p == disk)
break;
- if (*gpp)
- *gpp = (*gpp)->next;
+ if (*p)
+ *p = (*p)->next;
write_unlock(&gendisk_lock);
}
-EXPORT_SYMBOL(del_gendisk);
-
-
/**
* get_gendisk - get partitioning information for a given device
* @dev: device to get partitioning information for
@@ -160,14 +162,17 @@ static int show_partition(struct seq_file *part, void *v)
seq_puts(part, "major minor #blocks name\n\n");
/* show the full disk and all non-0 size partitions of it */
- for (n = 0; n < (sgp->nr_real << sgp->minor_shift); n++) {
- int minormask = (1<<sgp->minor_shift) - 1;
- if ((n & minormask) && sgp->part[n].nr_sects == 0)
+ seq_printf(part, "%4d %4d %10ld %s\n",
+ sgp->major, sgp->first_minor,
+ get_capacity(sgp) >> 1,
+ disk_name(sgp, 0, buf));
+ for (n = 0; n < (1<<sgp->minor_shift) - 1; n++) {
+ if (sgp->part[n].nr_sects == 0)
continue;
seq_printf(part, "%4d %4d %10ld %s\n",
- sgp->major, n + sgp->first_minor,
+ sgp->major, n + 1 + sgp->first_minor,
sgp->part[n].nr_sects >> 1 ,
- disk_name(sgp, n + sgp->first_minor, buf));
+ disk_name(sgp, n + 1, buf));
}
return 0;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index a66f21b8e348..318b1aa0092d 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -210,8 +210,7 @@ do_lo_send(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos)
goto fail;
if (aops->prepare_write(file, page, offset, offset+size))
goto unlock;
- kaddr = page_address(page);
- flush_dcache_page(page);
+ kaddr = kmap(page);
transfer_result = lo_do_transfer(lo, WRITE, kaddr + offset, data, size, IV);
if (transfer_result) {
/*
@@ -221,6 +220,8 @@ do_lo_send(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos)
printk(KERN_ERR "loop: transfer error block %ld\n", index);
memset(kaddr + offset, 0, size);
}
+ flush_dcache_page(page);
+ kunmap(page);
if (aops->commit_write(file, page, offset, offset+size))
goto unlock;
if (transfer_result)
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 25273d4ba1b8..de78fa2198b8 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -111,28 +111,21 @@
*/
-static int verbose = 0;
-static int major = PCD_MAJOR;
-static char *name = PCD_NAME;
-static int nice = 0;
-static int disable = 0;
-
-static int drive0[6] = {0,0,0,-1,-1,-1};
-static int drive1[6] = {0,0,0,-1,-1,-1};
-static int drive2[6] = {0,0,0,-1,-1,-1};
-static int drive3[6] = {0,0,0,-1,-1,-1};
-
-static int (*drives[4])[6] = {&drive0,&drive1,&drive2,&drive3};
+static int verbose = 0;
+static int major = PCD_MAJOR;
+static char *name = PCD_NAME;
+static int nice = 0;
+static int disable = 0;
+
+static int drive0[6] = { 0, 0, 0, -1, -1, -1 };
+static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
+static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
+static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
+
+static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
static int pcd_drive_count;
-#define D_PRT 0
-#define D_PRO 1
-#define D_UNI 2
-#define D_MOD 3
-#define D_SLV 4
-#define D_DLY 5
-
-#define DU (*drives[unit])
+enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
/* end of parameters */
@@ -153,28 +146,30 @@ static spinlock_t pcd_lock;
#include "setup.h"
-static STT pcd_stt[6] = {{"drive0",6,drive0},
- {"drive1",6,drive1},
- {"drive2",6,drive2},
- {"drive3",6,drive3},
- {"disable",1,&disable},
- {"nice",1,&nice}};
-
-void pcd_setup( char *str, int *ints)
+static STT pcd_stt[6] = {
+ {"drive0", 6, drive0},
+ {"drive1", 6, drive1},
+ {"drive2", 6, drive2},
+ {"drive3", 6, drive3},
+ {"disable", 1, &disable},
+ {"nice", 1, &nice}
+};
-{ generic_setup(pcd_stt,6,str);
+void pcd_setup(char *str, int *ints)
+{
+ generic_setup(pcd_stt, 6, str);
}
#endif
-MODULE_PARM(verbose,"i");
-MODULE_PARM(major,"i");
-MODULE_PARM(name,"s");
-MODULE_PARM(nice,"i");
-MODULE_PARM(drive0,"1-6i");
-MODULE_PARM(drive1,"1-6i");
-MODULE_PARM(drive2,"1-6i");
-MODULE_PARM(drive3,"1-6i");
+MODULE_PARM(verbose, "i");
+MODULE_PARM(major, "i");
+MODULE_PARM(name, "s");
+MODULE_PARM(nice, "i");
+MODULE_PARM(drive0, "1-6i");
+MODULE_PARM(drive1, "1-6i");
+MODULE_PARM(drive2, "1-6i");
+MODULE_PARM(drive3, "1-6i");
#include "paride.h"
@@ -189,10 +184,10 @@ MODULE_PARM(drive3,"1-6i");
#include "pseudo.h"
#define PCD_RETRIES 5
-#define PCD_TMO 800 /* timeout in jiffies */
-#define PCD_DELAY 50 /* spin delay in uS */
-#define PCD_READY_TMO 20 /* in seconds */
-#define PCD_RESET_TMO 100 /* in tenths of a second */
+#define PCD_TMO 800 /* timeout in jiffies */
+#define PCD_DELAY 50 /* spin delay in uS */
+#define PCD_READY_TMO 20 /* in seconds */
+#define PCD_RESET_TMO 100 /* in tenths of a second */
#define PCD_SPIN (1000000*PCD_TMO)/(HZ*PCD_DELAY)
@@ -208,127 +203,108 @@ 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_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);
+ unsigned int cmd, void *arg);
static int pcd_packet(struct cdrom_device_info *cdi,
- struct cdrom_generic_command *cgc);
+ struct cdrom_generic_command *cgc);
-static int pcd_detect(void);
-static void pcd_probe_capabilities(void);
-static void do_pcd_read_drq(void);
-static void do_pcd_request(request_queue_t * q);
-static void do_pcd_read(void);
+static int pcd_detect(void);
+static void pcd_probe_capabilities(void);
+static void do_pcd_read_drq(void);
+static void do_pcd_request(request_queue_t * q);
+static void do_pcd_read(void);
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 changed; /* media change seen */
- int present; /* does this unit exist ? */
- char *name; /* 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];
-/* 'unit' must be defined in all functions - either as a local or a param */
-
-#define PCD pcd[unit]
-#define PI PCD.pi
-
static char pcd_scratch[64];
-static char pcd_buffer[2048]; /* raw block buffer */
-static int pcd_bufblk = -1; /* block in buffer, in CD units,
- -1 for nothing there. See also
- pd_unit.
- */
+static char pcd_buffer[2048]; /* raw block buffer */
+static int pcd_bufblk = -1; /* block in buffer, in CD units,
+ -1 for nothing there. See also
+ pd_unit.
+ */
/* the variables below are used mainly in the I/O request engine, which
processes only one request at a time.
*/
-static int pcd_unit = -1; /* unit of current request & bufblk */
-static int pcd_retries; /* retries on current request */
-static int pcd_busy = 0; /* request being processed ? */
-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 struct pcd_unit *pcd_current; /* current request's drive */
+static int pcd_retries; /* retries on current request */
+static int pcd_busy; /* request being processed ? */
+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 ? */
+static int pcd_warned; /* Have we logged a phase warning ? */
/* kernel glue structures */
static struct block_device_operations pcd_bdops = {
- owner: THIS_MODULE,
- open: cdrom_open,
- release: cdrom_release,
- ioctl: cdrom_ioctl,
- check_media_change: cdrom_media_changed,
+ .owner = THIS_MODULE,
+ .open = cdrom_open,
+ .release = cdrom_release,
+ .ioctl = cdrom_ioctl,
+ .check_media_change = cdrom_media_changed,
};
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 |
- CDC_GENERIC_PACKET |
- CDC_CD_R |
- CDC_CD_RW,
- 0,
- pcd_packet,
+ .open = pcd_open,
+ .release = pcd_release,
+ .drive_status = pcd_drive_status,
+ .media_changed = pcd_media_changed,
+ .tray_move = pcd_tray_move,
+ .lock_door = pcd_lock_door,
+ .get_mcn = pcd_get_mcn,
+ .reset = pcd_drive_reset,
+ .audio_ioctl = pcd_audio_ioctl,
+ .generic_packet = pcd_packet,
+ .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
+ CDC_MCN | CDC_MEDIA_CHANGED | CDC_RESET |
+ CDC_PLAY_AUDIO | CDC_GENERIC_PACKET | CDC_CD_R |
+ CDC_CD_RW,
};
-static void pcd_init_units( void )
-
-{ int unit, j;
+static void pcd_init_units(void)
+{
+ struct pcd_unit *cd;
+ int unit;
- pcd_drive_count = 0;
- for (unit=0;unit<PCD_UNITS;unit++) {
- PCD.pi = & PCD.pia;
- PCD.present = 0;
- PCD.last_sense = 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 = mk_kdev(major,unit);
- PCD.info.speed = 0;
- PCD.info.capacity = 1;
- PCD.info.mask = 0;
- }
+ pcd_drive_count = 0;
+ for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
+ cd->pi = &cd->pia;
+ cd->present = 0;
+ cd->last_sense = 0;
+ cd->changed = 1;
+ cd->drive = (*drives[unit])[D_SLV];
+ if ((*drives[unit])[D_PRT])
+ pcd_drive_count++;
+
+ cd->name = &cd->info.name[0];
+ snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit);
+ cd->info.ops = &pcd_dops;
+ cd->info.handle = cd;
+ cd->info.dev = mk_kdev(major, unit);
+ cd->info.speed = 0;
+ cd->info.capacity = 1;
+ cd->info.mask = 0;
+ }
}
static int pcd_open(struct cdrom_device_info *cdi, int purpose)
{
- int unit = DEVICE_NR(cdi->dev);
- if ((unit >= PCD_UNITS) || (!PCD.present))
+ struct pcd_unit *cd = cdi->handle;
+ if (!cd->present)
return -ENODEV;
return 0;
}
@@ -337,554 +313,598 @@ static void pcd_release(struct cdrom_device_info *cdi)
{
}
-#define WR(c,r,v) pi_write_regr(PI,c,r,v)
-#define RR(c,r) (pi_read_regr(PI,c,r))
+static inline int status_reg(struct pcd_unit *cd)
+{
+ return pi_read_regr(cd->pi, 1, 6);
+}
+
+static inline int read_reg(struct pcd_unit *cd, int reg)
+{
+ return pi_read_regr(cd->pi, 0, reg);
+}
-static int pcd_wait( int unit, int go, int stop, char * fun, char * msg )
+static inline void write_reg(struct pcd_unit *cd, int reg, int val)
+{
+ pi_write_regr(cd->pi, 0, reg, val);
+}
-{ int j, r, e, s, p;
+static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg)
+{
+ int j, r, e, s, p;
j = 0;
- while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(j++<PCD_SPIN))
+ while ((((r = status_reg(cd)) & go) || (stop && (!(r & stop))))
+ && (j++ < PCD_SPIN))
udelay(PCD_DELAY);
- if ((r&(IDE_ERR&stop))||(j>=PCD_SPIN)) {
- s = RR(0,7);
- e = RR(0,1);
- p = RR(0,2);
- if (j >= PCD_SPIN) e |= 0x100;
- if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
- " loop=%d phase=%d\n",
- PCD.name,fun,msg,r,s,e,j,p);
- return (s<<8)+r;
+ if ((r & (IDE_ERR & stop)) || (j >= PCD_SPIN)) {
+ s = read_reg(cd, 7);
+ e = read_reg(cd, 1);
+ p = read_reg(cd, 2);
+ if (j >= PCD_SPIN)
+ e |= 0x100;
+ if (fun)
+ printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
+ " loop=%d phase=%d\n",
+ cd->name, fun, msg, r, s, e, j, p);
+ return (s << 8) + r;
}
return 0;
}
-static int pcd_command( int unit, char * cmd, int dlen, char * fun )
-
-{ pi_connect(PI);
+static int pcd_command(struct pcd_unit *cd, char *cmd, int dlen, char *fun)
+{
+ pi_connect(cd->pi);
- WR(0,6,0xa0 + 0x10*PCD.drive);
+ write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
- if (pcd_wait(unit,IDE_BUSY|IDE_DRQ,0,fun,"before command")) {
- pi_disconnect(PI);
+ if (pcd_wait(cd, IDE_BUSY | IDE_DRQ, 0, fun, "before command")) {
+ pi_disconnect(cd->pi);
return -1;
}
- WR(0,4,dlen % 256);
- WR(0,5,dlen / 256);
- WR(0,7,0xa0); /* ATAPI packet command */
+ write_reg(cd, 4, dlen % 256);
+ write_reg(cd, 5, dlen / 256);
+ write_reg(cd, 7, 0xa0); /* ATAPI packet command */
- if (pcd_wait(unit,IDE_BUSY,IDE_DRQ,fun,"command DRQ")) {
- pi_disconnect(PI);
+ if (pcd_wait(cd, IDE_BUSY, IDE_DRQ, fun, "command DRQ")) {
+ pi_disconnect(cd->pi);
return -1;
}
- if (RR(0,2) != 1) {
- printk("%s: %s: command phase error\n",PCD.name,fun);
- pi_disconnect(PI);
- return -1;
- }
+ if (read_reg(cd, 2) != 1) {
+ printk("%s: %s: command phase error\n", cd->name, fun);
+ pi_disconnect(cd->pi);
+ return -1;
+ }
- pi_write_block(PI,cmd,12);
+ pi_write_block(cd->pi, cmd, 12);
return 0;
}
-static int pcd_completion( int unit, char * buf, char * fun )
-
-{ 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);
+static int pcd_completion(struct pcd_unit *cd, char *buf, char *fun)
+{
+ int r, d, p, n, k, j;
+
+ r = -1;
+ k = 0;
+ j = 0;
+
+ if (!pcd_wait(cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR,
+ fun, "completion")) {
+ r = 0;
+ while (read_reg(cd, 7) & IDE_DRQ) {
+ d = read_reg(cd, 4) + 256 * read_reg(cd, 5);
+ n = (d + 3) & 0xfffc;
+ p = read_reg(cd, 2) & 3;
+
+ if ((p == 2) && (n > 0) && (j == 0)) {
+ pi_read_block(cd->pi, buf, n);
+ if (verbose > 1)
+ printk("%s: %s: Read %d bytes\n",
+ cd->name, fun, n);
+ r = 0;
+ j++;
+ } else {
+ if (verbose > 1)
+ printk
+ ("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
+ cd->name, fun, p, d, k);
+ if ((verbose < 2) && !pcd_warned) {
+ pcd_warned = 1;
+ printk
+ ("%s: WARNING: ATAPI phase errors\n",
+ cd->name);
+ }
+ mdelay(1);
+ }
+ if (k++ > PCD_TMO) {
+ printk("%s: Stuck DRQ\n", cd->name);
+ break;
+ }
+ if (pcd_wait
+ (cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR, fun,
+ "completion")) {
+ r = -1;
+ break;
}
- 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;
}
- }
}
-
- pi_disconnect(PI);
+
+ pi_disconnect(cd->pi);
return r;
}
-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, c;
+static void pcd_req_sense(struct pcd_unit *cd, char *fun)
+{
+ char rs_cmd[12] = { 0x03, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
+ char buf[16];
+ int r, c;
- r = pcd_command(unit,rs_cmd,16,"Request sense");
+ r = pcd_command(cd, rs_cmd, 16, "Request sense");
mdelay(1);
- if (!r) pcd_completion(unit,buf,"Request sense");
+ if (!r)
+ pcd_completion(cd, buf, "Request sense");
- PCD.last_sense = -1; c = 2;
+ cd->last_sense = -1;
+ c = 2;
if (!r) {
- 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;
+ if (fun)
+ printk("%s: %s: Sense key: %x, ASC: %x, ASQ: %x\n",
+ cd->name, fun, buf[2] & 0xf, buf[12], buf[13]);
+ c = buf[2] & 0xf;
+ cd->last_sense =
+ c | ((buf[12] & 0xff) << 8) | ((buf[13] & 0xff) << 16);
+ }
+ if ((c == 2) || (c == 6))
+ cd->changed = 1;
}
-static int pcd_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
-
-{ int r;
+static int pcd_atapi(struct pcd_unit *cd, char *cmd, int dlen, char *buf, char *fun)
+{
+ int r;
- r = pcd_command(unit,cmd,dlen,fun);
+ r = pcd_command(cd, cmd, dlen, fun);
mdelay(1);
- if (!r) r = pcd_completion(unit,buf,fun);
- if (r) pcd_req_sense(unit,fun);
-
+ if (!r)
+ r = pcd_completion(cd, buf, fun);
+ if (r)
+ pcd_req_sense(cd, fun);
+
return r;
}
-static int pcd_packet(struct cdrom_device_info *cdi,
- struct cdrom_generic_command *cgc)
+static int pcd_packet(struct cdrom_device_info *cdi, struct cdrom_generic_command *cgc)
{
- char *un_cmd;
- int unit = DEVICE_NR(cdi->dev);
-
- un_cmd = cgc->cmd;
- return pcd_atapi(unit,un_cmd,cgc->buflen,cgc->buffer, "generic packet");
+ return pcd_atapi(cdi->handle, cgc->cmd, cgc->buflen, cgc->buffer,
+ "generic packet");
}
#define DBMSG(msg) ((verbose>1)?(msg):NULL)
static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr)
-
-{ int r;
- int unit = DEVICE_NR(cdi->dev);
-
- r = PCD.changed;
- PCD.changed = 0;
-
- return r;
+{
+ struct pcd_unit *cd = cdi->handle;
+ int res = cd->changed;
+ if (res)
+ cd->changed = 0;
+ return res;
}
static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
+{
+ char un_cmd[12] = { 0x1e, 0, 0, 0, lock, 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);
-
- return pcd_atapi(unit,un_cmd,0,pcd_scratch,
- lock?"lock door":"unlock door");
+ return pcd_atapi(cdi->handle, un_cmd, 0, pcd_scratch,
+ lock ? "lock door" : "unlock door");
}
static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
+{
+ char ej_cmd[12] = { 0x1b, 0, 0, 0, 3 - position, 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);
-
- return pcd_atapi(unit,ej_cmd,0,pcd_scratch,
- position?"eject":"close tray");
+ return pcd_atapi(cdi->handle, ej_cmd, 0, pcd_scratch,
+ position ? "eject" : "close tray");
}
-static void pcd_sleep( int cs )
-
-{ current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(cs);
+static void pcd_sleep(int cs)
+{
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(cs);
}
-static int pcd_reset( int unit )
-
-{ int i, k, flg;
- int expect[5] = {1,1,1,0x14,0xeb};
+static int pcd_reset(struct pcd_unit *cd)
+{
+ int i, k, flg;
+ int expect[5] = { 1, 1, 1, 0x14, 0xeb };
- pi_connect(PI);
- WR(0,6,0xa0 + 0x10*PCD.drive);
- WR(0,7,8);
+ pi_connect(cd->pi);
+ write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
+ write_reg(cd, 7, 8);
- pcd_sleep(20*HZ/1000); /* delay a bit */
+ pcd_sleep(20 * HZ / 1000); /* delay a bit */
k = 0;
- while ((k++ < PCD_RESET_TMO) && (RR(1,6)&IDE_BUSY))
- pcd_sleep(HZ/10);
+ while ((k++ < PCD_RESET_TMO) && (status_reg(cd) & IDE_BUSY))
+ pcd_sleep(HZ / 10);
flg = 1;
- for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
+ for (i = 0; i < 5; i++)
+ flg &= (read_reg(cd, i + 1) == expect[i]);
if (verbose) {
- printk("%s: Reset (%d) signature = ",PCD.name,k);
- for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
- if (!flg) printk(" (incorrect)");
+ printk("%s: Reset (%d) signature = ", cd->name, k);
+ for (i = 0; i < 5; i++)
+ printk("%3x", read_reg(cd, i + 1));
+ if (!flg)
+ printk(" (incorrect)");
printk("\n");
}
-
- pi_disconnect(PI);
- return flg-1;
+
+ pi_disconnect(cd->pi);
+ return flg - 1;
}
static int pcd_drive_reset(struct cdrom_device_info *cdi)
-
-{ return pcd_reset(DEVICE_NR(cdi->dev));
+{
+ return pcd_reset(cdi->handle);
}
-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};
- int k, p;
+static int pcd_ready_wait(struct pcd_unit *cd, int tmo)
+{
+ char tr_cmd[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ int k, p;
- k = 0;
- while (k < tmo) {
- PCD.last_sense = 0;
- pcd_atapi(unit,tr_cmd,0,NULL,DBMSG("test unit ready"));
- p = PCD.last_sense;
- if (!p) return 0;
- if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;
- k++;
- pcd_sleep(HZ);
- }
- return 0x000020; /* timeout */
+ k = 0;
+ while (k < tmo) {
+ cd->last_sense = 0;
+ pcd_atapi(cd, tr_cmd, 0, NULL, DBMSG("test unit ready"));
+ p = cd->last_sense;
+ if (!p)
+ return 0;
+ if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
+ return p;
+ k++;
+ pcd_sleep(HZ);
+ }
+ return 0x000020; /* timeout */
}
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 };
+ struct pcd_unit *cd = cdi->handle;
-{ char rc_cmd[12] = { 0x25,0,0,0,0,0,0,0,0,0,0,0};
- int unit = DEVICE_NR(cdi->dev);
-
- if (pcd_ready_wait(unit,PCD_READY_TMO))
+ if (pcd_ready_wait(cd, PCD_READY_TMO))
return CDS_DRIVE_NOT_READY;
- if (pcd_atapi(unit,rc_cmd,8,pcd_scratch,DBMSG("check media")))
+ if (pcd_atapi(cd, rc_cmd, 8, pcd_scratch, DBMSG("check media")))
return CDS_NO_DISC;
return CDS_DISC_OK;
}
-static int pcd_identify( int unit, char * id )
-
-{ int k, s;
- char id_cmd[12] = {0x12,0,0,0,36,0,0,0,0,0,0,0};
+static int pcd_identify(struct pcd_unit *cd, char *id)
+{
+ int k, s;
+ char id_cmd[12] = { 0x12, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
pcd_bufblk = -1;
- s = pcd_atapi(unit,id_cmd,36,pcd_buffer,"identify");
+ s = pcd_atapi(cd, id_cmd, 36, pcd_buffer, "identify");
- if (s) return -1;
+ if (s)
+ return -1;
if ((pcd_buffer[0] & 0x1f) != 5) {
- if (verbose) printk("%s: %s is not a CD-ROM\n",
- PCD.name,PCD.drive?"Slave":"Master");
- return -1;
+ if (verbose)
+ printk("%s: %s is not a CD-ROM\n",
+ cd->name, cd->drive ? "Slave" : "Master");
+ return -1;
+ }
+ memcpy(id, pcd_buffer + 16, 16);
+ id[16] = 0;
+ k = 16;
+ while ((k >= 0) && (id[k] <= 0x20)) {
+ id[k] = 0;
+ k--;
}
- for (k=0;k<16;k++) id[k] = pcd_buffer[16+k]; id[16] = 0;
- k = 16; while ((k >= 0) && (id[k] <= 0x20)) { id[k] = 0; k--; }
- printk("%s: %s: %s\n",PCD.name,PCD.drive?"Slave":"Master",id);
+ printk("%s: %s: %s\n", cd->name, cd->drive ? "Slave" : "Master", id);
return 0;
}
-static int pcd_probe( int unit, int ms, char * id )
-
-/* returns 0, with id set if drive is detected
- -1, if drive detection failed
-*/
-
-{ if (ms == -1) {
- for (PCD.drive=0;PCD.drive<=1;PCD.drive++)
- if (!pcd_reset(unit) && !pcd_identify(unit,id))
- return 0;
+/*
+ * returns 0, with id set if drive is detected
+ * -1, if drive detection failed
+ */
+static int pcd_probe(struct pcd_unit *cd, int ms, char *id)
+{
+ if (ms == -1) {
+ for (cd->drive = 0; cd->drive <= 1; cd->drive++)
+ if (!pcd_reset(cd) && !pcd_identify(cd, id))
+ return 0;
} else {
- PCD.drive = ms;
- if (!pcd_reset(unit) && !pcd_identify(unit,id))
- return 0;
+ cd->drive = ms;
+ if (!pcd_reset(cd) && !pcd_identify(cd, id))
+ return 0;
}
return -1;
}
-static void pcd_probe_capabilities( void )
-
-{ int unit, r;
- char buffer[32];
- char cmd[12]={0x5a,1<<3,0x2a,0,0,0,0,18,0,0,0,0};
-
- for (unit=0;unit<PCD_UNITS;unit++) {
- if (!PCD.present) continue;
- r = pcd_atapi(unit,cmd,18, buffer,"mode sense capabilities");
- if (r) continue;
+static void pcd_probe_capabilities(void)
+{
+ int unit, r;
+ char buffer[32];
+ char cmd[12] = { 0x5a, 1 << 3, 0x2a, 0, 0, 0, 0, 18, 0, 0, 0, 0 };
+ struct pcd_unit *cd;
+
+ for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
+ if (!cd->present)
+ continue;
+ r = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities");
+ if (r)
+ continue;
/* we should now have the cap page */
if ((buffer[11] & 1) == 0)
- PCD.info.mask |= CDC_CD_R;
+ cd->info.mask |= CDC_CD_R;
if ((buffer[11] & 2) == 0)
- PCD.info.mask |= CDC_CD_RW;
+ cd->info.mask |= CDC_CD_RW;
if ((buffer[12] & 1) == 0)
- PCD.info.mask |= CDC_PLAY_AUDIO;
+ cd->info.mask |= CDC_PLAY_AUDIO;
if ((buffer[14] & 1) == 0)
- PCD.info.mask |= CDC_LOCK;
+ cd->info.mask |= CDC_LOCK;
if ((buffer[14] & 8) == 0)
- PCD.info.mask |= CDC_OPEN_TRAY;
+ cd->info.mask |= CDC_OPEN_TRAY;
if ((buffer[14] >> 6) == 0)
- PCD.info.mask |= CDC_CLOSE_TRAY;
+ cd->info.mask |= CDC_CLOSE_TRAY;
}
}
-static int pcd_detect( void )
-
-{ char id[18];
- int k, unit;
+static int pcd_detect(void)
+{
+ char id[18];
+ int k, unit;
+ struct pcd_unit *cd;
printk("%s: %s version %s, major %d, nice %d\n",
- name,name,PCD_VERSION,major,nice);
+ name, name, PCD_VERSION, major, nice);
k = 0;
- if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
- unit = 0;
- if (pi_init(PI,1,-1,-1,-1,-1,-1,pcd_buffer,
- PI_PCD,verbose,PCD.name)) {
- if (!pcd_probe(unit,-1,id)) {
- PCD.present = 1;
- k++;
- } else pi_release(PI);
- }
-
- } else for (unit=0;unit<PCD_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],pcd_buffer,PI_PCD,verbose,
- PCD.name)) {
- if (!pcd_probe(unit,DU[D_SLV],id)) {
- PCD.present = 1;
- k++;
- } else pi_release(PI);
- }
-
- if (k) return 0;
-
- printk("%s: No CD-ROM drive found\n",name);
+ if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
+ cd = pcd;
+ if (pi_init(cd->pi, 1, -1, -1, -1, -1, -1, pcd_buffer,
+ PI_PCD, verbose, cd->name)) {
+ if (!pcd_probe(cd, -1, id)) {
+ cd->present = 1;
+ k++;
+ } else
+ pi_release(cd->pi);
+ }
+ } else {
+ for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
+ int *conf = *drives[unit];
+ if (!conf[D_PRT])
+ continue;
+ if (!pi_init(cd->pi, 0, conf[D_PRT], conf[D_MOD],
+ conf[D_UNI], conf[D_PRO], conf[D_DLY],
+ pcd_buffer, PI_PCD, verbose, cd->name))
+ continue;
+ if (!pcd_probe(cd, conf[D_SLV], id)) {
+ cd->present = 1;
+ k++;
+ } else
+ pi_release(cd->pi);
+ }
+ }
+ if (k)
+ return 0;
+
+ printk("%s: No CD-ROM drive found\n", name);
return -1;
}
/* I/O request processing */
-static void do_pcd_request (request_queue_t * q)
-
-{ int unit;
-
- if (pcd_busy) return;
- while (1) {
- if (blk_queue_empty(QUEUE))
- return;
-
- if (rq_data_dir(CURRENT) == READ) {
- unit = minor(CURRENT->rq_dev);
- if (unit != pcd_unit) {
- pcd_bufblk = -1;
- pcd_unit = unit;
- }
- pcd_sector = CURRENT->sector;
- pcd_count = CURRENT->current_nr_sectors;
- pcd_buf = CURRENT->buffer;
- pcd_busy = 1;
- ps_set_intr(do_pcd_read,0,0,nice);
+static void do_pcd_request(request_queue_t * q)
+{
+ if (pcd_busy)
return;
- }
- else end_request(CURRENT, 0);
+ while (1) {
+ struct request *req;
+ if (blk_queue_empty(QUEUE))
+ return;
+ req = CURRENT;
+ if (rq_data_dir(req) == READ) {
+ struct pcd_unit *cd = pcd + minor(req->rq_dev);
+ if (cd != pcd_current)
+ pcd_bufblk = -1;
+ pcd_current = cd;
+ pcd_sector = req->sector;
+ pcd_count = req->current_nr_sectors;
+ pcd_buf = req->buffer;
+ pcd_busy = 1;
+ ps_set_intr(do_pcd_read, 0, 0, nice);
+ return;
+ } else
+ end_request(req, 0);
}
}
-static int pcd_ready( void )
-
-{ int unit = pcd_unit;
-
- return (((RR(1,6)&(IDE_BUSY|IDE_DRQ))==IDE_DRQ)) ;
+static int pcd_ready(void)
+{
+ return (((status_reg(pcd_current) & (IDE_BUSY | IDE_DRQ)) == IDE_DRQ));
}
-static void pcd_transfer( void )
-
-{ int k, o;
+static void pcd_transfer(void)
+{
- while (pcd_count && (pcd_sector/4 == pcd_bufblk)) {
- o = (pcd_sector % 4) * 512;
- for(k=0;k<512;k++) pcd_buf[k] = pcd_buffer[o+k];
+ while (pcd_count && (pcd_sector / 4 == pcd_bufblk)) {
+ int o = (pcd_sector % 4) * 512;
+ memcpy(pcd_buf, pcd_buffer + o, 512);
pcd_count--;
pcd_buf += 512;
pcd_sector++;
}
}
-static void pcd_start( void )
-
-{ int unit = pcd_unit;
- int b, i;
- char rd_cmd[12] = {0xa8,0,0,0,0,0,0,0,0,1,0,0};
- long saved_flags;
+static void pcd_start(void)
+{
+ int b, i;
+ char rd_cmd[12] = { 0xa8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };
+ long saved_flags;
pcd_bufblk = pcd_sector / 4;
- b = pcd_bufblk;
- for(i=0;i<4;i++) {
- rd_cmd[5-i] = b & 0xff;
- b = b >> 8;
+ b = pcd_bufblk;
+ for (i = 0; i < 4; i++) {
+ rd_cmd[5 - i] = b & 0xff;
+ b = b >> 8;
}
- if (pcd_command(unit,rd_cmd,2048,"read block")) {
- pcd_bufblk = -1;
- spin_lock_irqsave(&pcd_lock,saved_flags);
+ if (pcd_command(pcd_current, rd_cmd, 2048, "read block")) {
+ pcd_bufblk = -1;
+ spin_lock_irqsave(&pcd_lock, saved_flags);
pcd_busy = 0;
end_request(CURRENT, 0);
do_pcd_request(NULL);
- spin_unlock_irqrestore(&pcd_lock,saved_flags);
+ spin_unlock_irqrestore(&pcd_lock, saved_flags);
return;
}
mdelay(1);
- ps_set_intr(do_pcd_read_drq,pcd_ready,PCD_TMO,nice);
-
+ ps_set_intr(do_pcd_read_drq, pcd_ready, PCD_TMO, nice);
}
-static void do_pcd_read( void )
-
-
-{ int unit = pcd_unit;
- long saved_flags;
-
+static void do_pcd_read(void)
+{
pcd_busy = 1;
pcd_retries = 0;
pcd_transfer();
if (!pcd_count) {
- spin_lock_irqsave(&pcd_lock,saved_flags);
+ long saved_flags;
+ spin_lock_irqsave(&pcd_lock, saved_flags);
end_request(CURRENT, 1);
pcd_busy = 0;
do_pcd_request(NULL);
- spin_unlock_irqrestore(&pcd_lock,saved_flags);
+ spin_unlock_irqrestore(&pcd_lock, saved_flags);
return;
}
- pi_do_claimed(PI,pcd_start);
+ pi_do_claimed(pcd_current->pi, pcd_start);
}
-static void do_pcd_read_drq( void )
-
-{ int unit = pcd_unit;
- long saved_flags;
-
- if (pcd_completion(unit,pcd_buffer,"read block")) {
- if (pcd_retries < PCD_RETRIES) {
- mdelay(1);
- pcd_retries++;
- pi_do_claimed(PI,pcd_start);
- return;
- }
- spin_lock_irqsave(&pcd_lock,saved_flags);
+static void do_pcd_read_drq(void)
+{
+ long saved_flags;
+
+ if (pcd_completion(pcd_current, pcd_buffer, "read block")) {
+ if (pcd_retries < PCD_RETRIES) {
+ mdelay(1);
+ pcd_retries++;
+ pi_do_claimed(pcd_current->pi, pcd_start);
+ return;
+ }
+ spin_lock_irqsave(&pcd_lock, saved_flags);
pcd_busy = 0;
pcd_bufblk = -1;
end_request(CURRENT, 0);
do_pcd_request(NULL);
- spin_unlock_irqrestore(&pcd_lock,saved_flags);
+ spin_unlock_irqrestore(&pcd_lock, saved_flags);
return;
}
do_pcd_read();
- spin_lock_irqsave(&pcd_lock,saved_flags);
+ spin_lock_irqsave(&pcd_lock, saved_flags);
do_pcd_request(NULL);
- spin_unlock_irqrestore(&pcd_lock,saved_flags);
+ spin_unlock_irqrestore(&pcd_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)
+static int pcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
+{
+ struct pcd_unit *cd = cdi->handle;
-{ int unit = DEVICE_NR(cdi->dev);
-
- switch (cmd) {
-
- case CDROMREADTOCHDR:
-
- { char cmd[12]={GPCMD_READ_TOC_PMA_ATIP,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]={GPCMD_READ_TOC_PMA_ATIP,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;
- }
-
- default:
-
- return -ENOSYS;
- }
-}
-
-static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
-
-{ char cmd[12]={GPCMD_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];
+ switch (cmd) {
+
+ case CDROMREADTOCHDR:
+
+ {
+ char cmd[12] =
+ { GPCMD_READ_TOC_PMA_ATIP, 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(cd, cmd, 12, buffer, "read toc header");
+
+ tochdr->cdth_trk0 = buffer[2];
+ tochdr->cdth_trk1 = buffer[3];
+
+ return r ? -EIO : 0;
+ }
+
+ case CDROMREADTOCENTRY:
+
+ {
+ char cmd[12] =
+ { GPCMD_READ_TOC_PMA_ATIP, 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(cd, 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 : 0;
+ }
+
+ default:
+
+ return -ENOSYS;
+ }
+}
+
+static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
+{
+ char cmd[12] =
+ { GPCMD_READ_SUBCHANNEL, 0, 0x40, 2, 0, 0, 0, 0, 24, 0, 0, 0 };
+ char buffer[32];
+
+ if (pcd_atapi(cdi->handle, cmd, 24, buffer, "get mcn"))
+ return -EIO;
+
+ memcpy(mcn->medium_catalog_number, buffer + 9, 13);
mcn->medium_catalog_number[13] = 0;
-
+
return 0;
}
-
static int __init pcd_init(void)
{
+ struct pcd_unit *cd;
int unit;
if (disable)
@@ -898,15 +918,15 @@ static int __init pcd_init(void)
/* get the atapi capabilities page */
pcd_probe_capabilities();
- if (register_blkdev(MAJOR_NR,name,&pcd_bdops)) {
- printk("pcd: unable to get major number %d\n",MAJOR_NR);
+ if (register_blkdev(MAJOR_NR, name, &pcd_bdops)) {
+ 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);
- devfs_plain_cdrom(&PCD.info, &pcd_bdops);
+ for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
+ if (cd->present) {
+ register_cdrom(&cd->info);
+ devfs_plain_cdrom(&cd->info, &pcd_bdops);
}
}
@@ -917,13 +937,16 @@ static int __init pcd_init(void)
static void __exit pcd_exit(void)
{
+ struct pcd_unit *cd;
int unit;
- for (unit=0;unit<PCD_UNITS;unit++)
- if (PCD.present) {
- pi_release(PI);
- unregister_cdrom(&PCD.info);
+
+ for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
+ if (cd->present) {
+ pi_release(cd->pi);
+ unregister_cdrom(&cd->info);
}
- unregister_blkdev(MAJOR_NR,name);
+ }
+ unregister_blkdev(MAJOR_NR, name);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 6d6b1ab6a7c4..66e3300028a2 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -271,8 +271,6 @@ static void pd_doorlock(int unit, int func);
static int pd_check_media(kdev_t dev);
static void pd_eject( int unit);
-static struct hd_struct pd_hd[PD_DEVS];
-
#define PD_NAMELEN 8
struct pd_unit {
@@ -438,9 +436,9 @@ static int pd_revalidate(kdev_t dev)
if ((unit >= PD_UNITS) || !PD.present)
return -ENODEV;
if (pd_identify(unit))
- pd_hd[minor(dev)].nr_sects = PD.capacity;
+ set_capacity(&PD.gd, PD.capacity);
else
- pd_hd[minor(dev)].nr_sects = 0;
+ set_capacity(&PD.gd, 0);
return 0;
}
@@ -687,10 +685,8 @@ static int pd_detect( void )
PD.gd.major_name = PD.name;
PD.gd.minor_shift = PD_BITS;
PD.gd.fops = &pd_fops;
- PD.gd.nr_real = 1;
PD.gd.major = major;
PD.gd.first_minor = unit << PD_BITS;
- PD.gd.part = pd_hd + (unit << PD_BITS);
add_gendisk(&PD.gd);
register_disk(&PD.gd,mk_kdev(MAJOR_NR,unit<<PD_BITS),
PD_PARTNS,&pd_fops,
@@ -728,7 +724,7 @@ repeat:
pd_count = CURRENT->current_nr_sectors;
if ((pd_dev >= PD_DEVS) ||
- ((pd_block+pd_count) > pd_hd[pd_dev].nr_sects)) {
+ ((pd_block+pd_count) > get_capacity(&pd[unit].gd))) {
end_request(CURRENT, 0);
goto repeat;
}
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
index c1076b2b65d0..2b4d18cd054d 100644
--- a/drivers/block/ps2esdi.c
+++ b/drivers/block/ps2esdi.c
@@ -109,7 +109,6 @@ static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
static int no_int_yet;
static int ps2esdi_drives;
-static struct hd_struct ps2esdi[MAX_HD << 6];
static u_short io_base;
static struct timer_list esdi_timer = { function: ps2esdi_reset_timer };
static int reset_status;
@@ -152,17 +151,13 @@ static struct gendisk ps2esdi_gendisk[2] = {
major_name: "eda",
first_minor: 0,
minor_shift: 6,
- part: ps2esdi,
fops: &ps2esdi_fops,
- nr_real: 1
},{
major: MAJOR_NR,
first_minor: 64,
major_name: "edb",
minor_shift: 6,
- part: ps2esdi+64,
fops: &ps2esdi_fops,
- nr_real: 1
}
};
@@ -489,6 +484,7 @@ static void __init ps2esdi_get_device_cfg(void)
static void do_ps2esdi_request(request_queue_t * q)
{
u_int block, count;
+ int unit;
/* since, this routine is called with interrupts cleared - they
must be before it finishes */
@@ -505,18 +501,19 @@ static void do_ps2esdi_request(request_queue_t * q)
if (blk_queue_empty(QUEUE))
return;
+ unit = DEVICE_NR(CURRENT->rq_dev);
if (isa_virt_to_bus(CURRENT->buffer + CURRENT->current_nr_sectors * 512) > 16 * MB) {
printk("%s: DMA above 16MB not supported\n", DEVICE_NAME);
end_request(CURRENT, FAIL);
} /* check for above 16Mb dmas */
- else if ((DEVICE_NR(CURRENT->rq_dev) < ps2esdi_drives) &&
+ else if ((unit < ps2esdi_drives) &&
(CURRENT->sector + CURRENT->current_nr_sectors <=
- ps2esdi[minor(CURRENT->rq_dev)].nr_sects) &&
+ get_capacity(&ps2esdi_gendisk[unit])) &&
CURRENT->flags & REQ_CMD) {
#if 0
printk("%s:got request. device : %d minor : %d command : %d sector : %ld count : %ld\n",
DEVICE_NAME,
- DEVICE_NR(CURRENT->rq_dev), minor(CURRENT->rq_dev),
+ unit, minor(CURRENT->rq_dev),
CURRENT->cmd, CURRENT->sector,
CURRENT->current_nr_sectors);
#endif
@@ -526,10 +523,10 @@ static void do_ps2esdi_request(request_queue_t * q)
switch (rq_data_dir(CURRENT)) {
case READ:
- ps2esdi_readwrite(READ, DEVICE_NR(CURRENT->rq_dev), block, count);
+ ps2esdi_readwrite(READ, unit, block, count);
break;
case WRITE:
- ps2esdi_readwrite(WRITE, DEVICE_NR(CURRENT->rq_dev), block, count);
+ ps2esdi_readwrite(WRITE, unit, block, count);
break;
default:
printk("%s: Unknown command\n", DEVICE_NAME);
@@ -540,7 +537,7 @@ static void do_ps2esdi_request(request_queue_t * q)
/* is request is valid */
else {
printk("Grrr. error. ps2esdi_drives: %d, %lu %lu\n", ps2esdi_drives,
- CURRENT->sector, ps2esdi[minor(CURRENT->rq_dev)].nr_sects);
+ CURRENT->sector, get_capacity(&ps2esdi_gendisk[unit]));
end_request(CURRENT, FAIL);
}
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 587d432d4ac0..b36f3ccfd81a 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -109,9 +109,11 @@ int rd_blocksize = BLOCK_SIZE; /* blocksize of the RAM disks */
static int ramdisk_readpage(struct file *file, struct page * page)
{
if (!PageUptodate(page)) {
- memset(kmap(page), 0, PAGE_CACHE_SIZE);
- kunmap(page);
+ void *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr, 0, PAGE_CACHE_SIZE);
flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
SetPageUptodate(page);
}
unlock_page(page);
@@ -121,9 +123,11 @@ static int ramdisk_readpage(struct file *file, struct page * page)
static int ramdisk_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
{
if (!PageUptodate(page)) {
- void *addr = page_address(page);
- memset(addr, 0, PAGE_CACHE_SIZE);
+ void *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr, 0, PAGE_CACHE_SIZE);
flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
SetPageUptodate(page);
}
SetPageDirty(page);
@@ -178,8 +182,11 @@ static int rd_blkdev_pagecache_IO(int rw, struct bio_vec *vec,
err = 0;
if (!PageUptodate(page)) {
- memset(kmap(page), 0, PAGE_CACHE_SIZE);
- kunmap(page);
+ void *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr, 0, PAGE_CACHE_SIZE);
+ flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
SetPageUptodate(page);
}
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 482aa8634984..b714494b67d1 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -159,9 +159,6 @@ static struct cardinfo cards[MM_MAXCARDS];
static struct block_device_operations mm_fops;
static struct timer_list battery_timer;
-
-static struct hd_struct mm_partitions[MM_MAXCARDS << MM_SHIFT];
-
static int num_cards = 0;
static struct gendisk mm_gendisk[MM_MAXCARDS];
@@ -812,7 +809,7 @@ static void del_battery_timer(void)
static int mm_revalidate(kdev_t i_rdev)
{
int card_number = DEVICE_NR(i_rdev);
- mm_partitions[minor(i_rdev)].nr_sects = cards[card_number].mm_size << 1;
+ set_capacity(mm_gendisk + card_number, cards[card_number].mm_size << 1);
return 0;
}
/*
@@ -1192,8 +1189,6 @@ int __init mm_init(void)
struct gendisk *disk = mm_gendisk + i;
sprintf(mm_names + i*6, "umem%c", 'a'+i);
spin_lock_init(&cards[i].lock);
- disk->part = mm_partitions + (i << MM_SHIFT);
- disk->nr_real = 1;
disk->major = major_nr;
disk->first_minor = i << MM_SHIFT;
disk->major_name = mm_names + i*6;
@@ -1222,10 +1217,8 @@ void __exit mm_cleanup(void)
del_battery_timer();
- for (i=0; i < num_cards ; i++) {
- devfs_register_partitions(mm_gendisk + i, i<<MM_SHIFT, 1);
+ for (i=0; i < num_cards ; i++)
del_gendisk(mm_gendisk + i);
- }
if (devfs_handle)
devfs_unregister(devfs_handle);
devfs_handle = NULL;
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 6dc939a7a055..97ec536e4756 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -121,8 +121,6 @@ static unsigned int xd_bases[] __initdata =
0xE0000
};
-static struct hd_struct xd_struct[XD_MAXDRIVES << 6];
-
static spinlock_t xd_lock = SPIN_LOCK_UNLOCKED;
extern struct block_device_operations xd_fops;
@@ -133,17 +131,13 @@ static struct gendisk xd_gendisk[2] = {
.first_minor = 0,
.major_name = "xda",
.minor_shift = 6,
- .part = xd_struct,
.fops = &xd_fops,
- .nr_real = 1
},{
.major = MAJOR_NR,
.first_minor = 64,
.major_name = "xdb",
.minor_shift = 6,
- .part = xd_struct + 64,
.fops = &xd_fops,
- .nr_real = 1
}
};
@@ -281,15 +275,17 @@ static void do_xd_request (request_queue_t * q)
return;
while (1) {
+ int unit;
code = 0;
/* do some checking on the request structure */
if (blk_queue_empty(QUEUE))
return;
- if (DEVICE_NR(CURRENT->rq_dev) < xd_drives
+ unit = DEVICE_NR(CURRENT->rq_dev);
+ if (unit < xd_drives
&& (CURRENT->flags & REQ_CMD)
&& CURRENT->sector + CURRENT->nr_sectors
- <= xd_struct[minor(CURRENT->rq_dev)].nr_sects) {
+ <= get_capacity(xd_gendisk + unit)) {
block = CURRENT->sector;
count = CURRENT->nr_sectors;
@@ -297,7 +293,7 @@ static void do_xd_request (request_queue_t * q)
case READ:
case WRITE:
for (retry = 0; (retry < XD_RETRIES) && !code; retry++)
- code = xd_readwrite(rq_data_dir(CURRENT),DEVICE_NR(CURRENT->rq_dev),
+ code = xd_readwrite(rq_data_dir(CURRENT),unit,
CURRENT->buffer,block,count);
break;
default:
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 3520403e3f1d..6101e17ebe13 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -254,6 +254,7 @@
#include <linux/config.h>
#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/buffer_head.h>
#include <linux/major.h>
#include <linux/types.h>
#include <linux/errno.h>
@@ -1608,6 +1609,7 @@ int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
cdinfo(CD_DO_IOCTL, "entering CDROM_RESET\n");
if (!CDROM_CAN(CDC_RESET))
return -ENOSYS;
+ invalidate_buffers(dev);
return cdo->reset(cdi);
}
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
index ab5136e92896..b969e36e69b0 100644
--- a/drivers/cdrom/cdu31a.c
+++ b/drivers/cdrom/cdu31a.c
@@ -331,12 +331,11 @@ static struct timer_list cdu31a_abort_timer;
from the abort read. */
static int abort_read_started = 0;
-
/*
- * This routine returns 1 if the disk has been changed since the last
- * check or 0 if it hasn't.
+ * Uniform cdrom interface function
+ * report back, if disc has changed from time of last request.
*/
-static int scd_disk_change(kdev_t full_dev)
+static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
{
int retval;
@@ -348,15 +347,6 @@ static int scd_disk_change(kdev_t full_dev)
/*
* Uniform cdrom interface function
- * report back, if disc has changed from time of last request.
- */
-static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
-{
- return scd_disk_change(cdi->dev);
-}
-
-/*
- * Uniform cdrom interface function
* report back, if drive is ready
*/
static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
index 7567fb2a6dc1..527286c08584 100644
--- a/drivers/cdrom/mcdx.c
+++ b/drivers/cdrom/mcdx.c
@@ -73,7 +73,6 @@ static const char *mcdx_c_version
#include <linux/major.h>
#define MAJOR_NR MITSUMI_X_CDROM_MAJOR
-#define DEVICE_NR(device) (minor(device))
#include <linux/blk.h>
#include <linux/devfs_fs_kernel.h>
@@ -197,7 +196,6 @@ struct s_drive_stuff {
void *rreg_status; /* r status */
int irq; /* irq used by this drive */
- int minor; /* minor number of this drive */
int present; /* drive present and its capabilities */
unsigned char readcmd; /* read cmd depends on single/double speed */
unsigned char playcmd; /* play should always be single speed */
@@ -207,6 +205,7 @@ struct s_drive_stuff {
int lastsector; /* last block accessible */
int status; /* last operation's error / status */
int readerrs; /* # of blocks read w/o error */
+ struct cdrom_device_info info;
};
@@ -305,21 +304,13 @@ static struct cdrom_device_ops mcdx_dops = {
CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
};
-static struct cdrom_device_info mcdx_info = {
- ops:&mcdx_dops,
- speed:2,
- capacity:1,
- name:"mcdx",
-};
-
-
/* KERNEL INTERFACE FUNCTIONS **************************************/
static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
unsigned int cmd, void *arg)
{
- struct s_drive_stuff *stuffp = mcdx_stuffp[minor(cdi->dev)];
+ struct s_drive_stuff *stuffp = cdi->handle;
if (!stuffp->present)
return -ENXIO;
@@ -627,7 +618,7 @@ static int mcdx_open(struct cdrom_device_info *cdi, int purpose)
{
struct s_drive_stuff *stuffp;
xtrace(OPENCLOSE, "open()\n");
- stuffp = mcdx_stuffp[minor(cdi->dev)];
+ stuffp = cdi->handle;
if (!stuffp->present)
return -ENXIO;
@@ -776,7 +767,7 @@ static void mcdx_close(struct cdrom_device_info *cdi)
xtrace(OPENCLOSE, "close()\n");
- stuffp = mcdx_stuffp[minor(cdi->dev)];
+ stuffp = cdi->handle;
--stuffp->users;
}
@@ -787,10 +778,9 @@ static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr)
{
struct s_drive_stuff *stuffp;
- xinfo("mcdx_media_changed called for device %s\n",
- kdevname(cdi->dev));
+ xinfo("mcdx_media_changed called for device %s\n", cdi->name);
- stuffp = mcdx_stuffp[minor(cdi->dev)];
+ stuffp = cdi->handle;
mcdx_getstatus(stuffp, 1);
if (stuffp->yyy == 0)
@@ -1027,14 +1017,13 @@ void __exit mcdx_exit(void)
xinfo("cleanup_module called\n");
for (i = 0; i < MCDX_NDRIVES; i++) {
- struct s_drive_stuff *stuffp;
- if (unregister_cdrom(&mcdx_info)) {
+ struct s_drive_stuff *stuffp = mcdx_stuffp[i];
+ if (!stuffp)
+ continue;
+ if (unregister_cdrom(&stuffp->info)) {
printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
return;
}
- stuffp = mcdx_stuffp[i];
- if (!stuffp)
- continue;
release_region((unsigned long) stuffp->wreg_data,
MCDX_IO_SIZE);
free_irq(stuffp->irq, NULL);
@@ -1208,15 +1197,19 @@ int __init mcdx_init_drive(int drive)
xtrace(INIT, "init() set non dma but irq mode\n");
mcdx_config(stuffp, 1);
- stuffp->minor = drive;
+ stuffp->info.ops = &mcdx_dops;
+ stuffp->info.speed = 2;
+ stuffp->info.capacity = 1;
+ stuffp->info.handle = stuffp;
+ sprintf(stuffp->info.name, "mcdx%d", drive);
+ stuffp->info.dev = mk_kdev(MAJOR_NR, drive);
sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%3p, irq %d."
" (Firmware version %c %x)\n",
stuffp->wreg_data, stuffp->irq, version.code, version.ver);
mcdx_stuffp[drive] = stuffp;
xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp);
- mcdx_info.dev = mk_kdev(MAJOR_NR, 0);
- if (register_cdrom(&mcdx_info) != 0) {
+ if (register_cdrom(&stuffp->info) != 0) {
printk("Cannot register Mitsumi CD-ROM!\n");
release_region((unsigned long) stuffp->wreg_data,
MCDX_IO_SIZE);
@@ -1227,7 +1220,7 @@ int __init mcdx_init_drive(int drive)
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
return 2;
}
- devfs_plain_cdrom(&mcdx_info, &mcdx_bdops);
+ devfs_plain_cdrom(&stuffp->info, &mcdx_bdops);
printk(msg);
return 0;
}
@@ -1685,7 +1678,7 @@ mcdx_playtrk(struct s_drive_stuff *stuffp, const struct cdrom_ti *ti)
static int mcdx_tray_move(struct cdrom_device_info *cdi, int position)
{
- struct s_drive_stuff *stuffp = mcdx_stuffp[minor(cdi->dev)];
+ struct s_drive_stuff *stuffp = cdi->handle;
if (!stuffp->present)
return -ENXIO;
@@ -1875,7 +1868,7 @@ static int mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tr
static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock)
{
- struct s_drive_stuff *stuffp = mcdx_stuffp[minor(cdi->dev)];
+ struct s_drive_stuff *stuffp = cdi->handle;
char cmd[2] = { 0xfe };
if (!(stuffp->present & DOOR))
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
index 2b2625b5ba2f..1dae164fdcee 100644
--- a/drivers/cdrom/sbpcd.c
+++ b/drivers/cdrom/sbpcd.c
@@ -480,7 +480,6 @@ static void sbp_read_cmd(struct request *req);
static int sbp_data(struct request *req);
static int cmd_out(void);
static int DiskInfo(void);
-static int sbpcd_chk_disk_change(kdev_t);
/*==========================================================================*/
@@ -623,9 +622,7 @@ static u_char drv_pattern[NR_SBPCD]={speed_auto,speed_auto,speed_auto,speed_auto
/*
* drive space begins here (needed separate for each unit)
*/
-static int d; /* DriveStruct index: drive number */
-
-static struct {
+static struct sbpcd_drive {
char drv_id; /* "jumpered" drive ID or -1 */
char drv_sel; /* drive select lines bits */
@@ -728,6 +725,8 @@ static struct {
} D_S[NR_SBPCD];
+static struct sbpcd_drive *current_drive = D_S;
+
/*
* drive space ends here (needed separate for each unit)
*/
@@ -760,7 +759,7 @@ static void msg(int level, const char *fmt, ...)
msgnum++;
if (msgnum>99) msgnum=0;
- sprintf(buf, MSG_LEVEL "%s-%d [%02d]: ", major_name, d, msgnum);
+ sprintf(buf, MSG_LEVEL "%s-%d [%02d]: ", major_name, current_drive - D_S, msgnum);
va_start(args, fmt);
vsprintf(&buf[18], fmt, args);
va_end(args);
@@ -1103,51 +1102,51 @@ static int ResponseInfo(void)
/*==========================================================================*/
static void EvaluateStatus(int st)
{
- D_S[d].status_bits=0;
- if (fam1_drive) D_S[d].status_bits=st|p_success;
+ current_drive->status_bits=0;
+ if (fam1_drive) current_drive->status_bits=st|p_success;
else if (fam0_drive)
{
- if (st&p_caddin_old) D_S[d].status_bits |= p_door_closed|p_caddy_in;
- if (st&p_spinning) D_S[d].status_bits |= p_spinning;
- if (st&p_check) D_S[d].status_bits |= p_check;
- if (st&p_success_old) D_S[d].status_bits |= p_success;
- if (st&p_busy_old) D_S[d].status_bits |= p_busy_new;
- if (st&p_disk_ok) D_S[d].status_bits |= p_disk_ok;
+ if (st&p_caddin_old) current_drive->status_bits |= p_door_closed|p_caddy_in;
+ if (st&p_spinning) current_drive->status_bits |= p_spinning;
+ if (st&p_check) current_drive->status_bits |= p_check;
+ if (st&p_success_old) current_drive->status_bits |= p_success;
+ if (st&p_busy_old) current_drive->status_bits |= p_busy_new;
+ if (st&p_disk_ok) current_drive->status_bits |= p_disk_ok;
}
else if (famLV_drive)
{
- D_S[d].status_bits |= p_success;
- if (st&p_caddin_old) D_S[d].status_bits |= p_disk_ok|p_caddy_in;
- if (st&p_spinning) D_S[d].status_bits |= p_spinning;
- if (st&p_check) D_S[d].status_bits |= p_check;
- if (st&p_busy_old) D_S[d].status_bits |= p_busy_new;
- if (st&p_lcs_door_closed) D_S[d].status_bits |= p_door_closed;
- if (st&p_lcs_door_locked) D_S[d].status_bits |= p_door_locked;
+ current_drive->status_bits |= p_success;
+ if (st&p_caddin_old) current_drive->status_bits |= p_disk_ok|p_caddy_in;
+ if (st&p_spinning) current_drive->status_bits |= p_spinning;
+ if (st&p_check) current_drive->status_bits |= p_check;
+ if (st&p_busy_old) current_drive->status_bits |= p_busy_new;
+ if (st&p_lcs_door_closed) current_drive->status_bits |= p_door_closed;
+ if (st&p_lcs_door_locked) current_drive->status_bits |= p_door_locked;
}
else if (fam2_drive)
{
- D_S[d].status_bits |= p_success;
- if (st&p2_check) D_S[d].status_bits |= p1_check;
- if (st&p2_door_closed) D_S[d].status_bits |= p1_door_closed;
- if (st&p2_disk_in) D_S[d].status_bits |= p1_disk_in;
- if (st&p2_busy1) D_S[d].status_bits |= p1_busy;
- if (st&p2_busy2) D_S[d].status_bits |= p1_busy;
- if (st&p2_spinning) D_S[d].status_bits |= p1_spinning;
- if (st&p2_door_locked) D_S[d].status_bits |= p1_door_locked;
- if (st&p2_disk_ok) D_S[d].status_bits |= p1_disk_ok;
+ current_drive->status_bits |= p_success;
+ if (st&p2_check) current_drive->status_bits |= p1_check;
+ if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed;
+ if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in;
+ if (st&p2_busy1) current_drive->status_bits |= p1_busy;
+ if (st&p2_busy2) current_drive->status_bits |= p1_busy;
+ if (st&p2_spinning) current_drive->status_bits |= p1_spinning;
+ if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked;
+ if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok;
}
else if (famT_drive)
{
return; /* still needs to get coded */
- D_S[d].status_bits |= p_success;
- if (st&p2_check) D_S[d].status_bits |= p1_check;
- if (st&p2_door_closed) D_S[d].status_bits |= p1_door_closed;
- if (st&p2_disk_in) D_S[d].status_bits |= p1_disk_in;
- if (st&p2_busy1) D_S[d].status_bits |= p1_busy;
- if (st&p2_busy2) D_S[d].status_bits |= p1_busy;
- if (st&p2_spinning) D_S[d].status_bits |= p1_spinning;
- if (st&p2_door_locked) D_S[d].status_bits |= p1_door_locked;
- if (st&p2_disk_ok) D_S[d].status_bits |= p1_disk_ok;
+ current_drive->status_bits |= p_success;
+ if (st&p2_check) current_drive->status_bits |= p1_check;
+ if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed;
+ if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in;
+ if (st&p2_busy1) current_drive->status_bits |= p1_busy;
+ if (st&p2_busy2) current_drive->status_bits |= p1_busy;
+ if (st&p2_spinning) current_drive->status_bits |= p1_spinning;
+ if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked;
+ if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok;
}
return;
}
@@ -1159,7 +1158,7 @@ static int get_state_T(void)
static int cmd_out_T(void);
clr_cmdbuf();
- D_S[d].n_bytes=1;
+ current_drive->n_bytes=1;
drvcmd[0]=CMDT_STATUS;
i=cmd_out_T();
if (i>=0) i=infobuf[0];
@@ -1170,33 +1169,33 @@ static int get_state_T(void)
}
if (i>=0)
/* 2: closed, disk in */
- D_S[d].status_bits=p1_door_closed|p1_disk_in|p1_spinning|p1_disk_ok;
- else if (D_S[d].error_state==6)
+ current_drive->status_bits=p1_door_closed|p1_disk_in|p1_spinning|p1_disk_ok;
+ else if (current_drive->error_state==6)
{
/* 3: closed, disk in, changed ("06 xx xx") */
- D_S[d].status_bits=p1_door_closed|p1_disk_in;
- D_S[d].CD_changed=0xFF;
- D_S[d].diskstate_flags &= ~toc_bit;
+ current_drive->status_bits=p1_door_closed|p1_disk_in;
+ current_drive->CD_changed=0xFF;
+ current_drive->diskstate_flags &= ~toc_bit;
}
- else if ((D_S[d].error_state!=2)||(D_S[d].b3!=0x3A)||(D_S[d].b4==0x00))
+ else if ((current_drive->error_state!=2)||(current_drive->b3!=0x3A)||(current_drive->b4==0x00))
{
/* 1: closed, no disk ("xx yy zz"or "02 3A 00") */
- D_S[d].status_bits=p1_door_closed;
- D_S[d].open_count=0;
+ current_drive->status_bits=p1_door_closed;
+ current_drive->open_count=0;
}
- else if (D_S[d].b4==0x01)
+ else if (current_drive->b4==0x01)
{
/* 0: open ("02 3A 01") */
- D_S[d].status_bits=0;
- D_S[d].open_count=0;
+ current_drive->status_bits=0;
+ current_drive->open_count=0;
}
else
{
/* 1: closed, no disk ("02 3A xx") */
- D_S[d].status_bits=p1_door_closed;
- D_S[d].open_count=0;
+ current_drive->status_bits=p1_door_closed;
+ current_drive->open_count=0;
}
- return (D_S[d].status_bits);
+ return (current_drive->status_bits);
}
/*==========================================================================*/
static int ResponseStatus(void)
@@ -1226,14 +1225,14 @@ static int ResponseStatus(void)
{
if ((flags_cmd_out & f_respo3) == 0)
msg(DBG_STA,"ResponseStatus: timeout.\n");
- D_S[d].status_bits=0;
+ current_drive->status_bits=0;
return (-401);
}
i=inb(CDi_info);
msg(DBG_STA,"ResponseStatus: response %02X.\n", i);
EvaluateStatus(i);
- msg(DBG_STA,"status_bits=%02X, i=%02X\n",D_S[d].status_bits,i);
- return (D_S[d].status_bits);
+ msg(DBG_STA,"status_bits=%02X, i=%02X\n",current_drive->status_bits,i);
+ return (current_drive->status_bits);
}
/*==========================================================================*/
static void cc_ReadStatus(void)
@@ -1283,18 +1282,18 @@ static int cc_ReadError(void)
drvcmd[0]=CMDT_READ_ERR;
}
i=cmd_out();
- D_S[d].error_byte=0;
+ current_drive->error_byte=0;
msg(DBG_ERR,"cc_ReadError: cmd_out(CMDx_READ_ERR) returns %d (%02X)\n",i,i);
if (i<0) return (i);
if (fam0V_drive) i=1;
else i=2;
- D_S[d].error_byte=infobuf[i];
- msg(DBG_ERR,"cc_ReadError: infobuf[%d] is %d (%02X)\n",i,D_S[d].error_byte,D_S[d].error_byte);
+ current_drive->error_byte=infobuf[i];
+ msg(DBG_ERR,"cc_ReadError: infobuf[%d] is %d (%02X)\n",i,current_drive->error_byte,current_drive->error_byte);
i=sta2err(infobuf[i]);
if (i==-ERR_DISKCHANGE)
{
- D_S[d].CD_changed=0xFF;
- D_S[d].diskstate_flags &= ~toc_bit;
+ current_drive->CD_changed=0xFF;
+ current_drive->diskstate_flags &= ~toc_bit;
}
return (i);
}
@@ -1309,16 +1308,16 @@ static int cmd_out_T(void)
int i, j, l=0, m, ntries;
unsigned long flags;
- D_S[d].error_state=0;
- D_S[d].b3=0;
- D_S[d].b4=0;
- D_S[d].f_drv_error=0;
+ current_drive->error_state=0;
+ current_drive->b3=0;
+ current_drive->b4=0;
+ current_drive->f_drv_error=0;
for (i=0;i<10;i++) sprintf(&msgbuf[i*3]," %02X",drvcmd[i]);
msgbuf[i*3]=0;
msg(DBG_CMD,"cmd_out_T:%s\n",msgbuf);
OUT(CDo_sel_i_d,0);
- OUT(CDo_enable,D_S[d].drv_sel);
+ OUT(CDo_enable,current_drive->drv_sel);
i=inb(CDi_status);
do_16bit=0;
if ((f_16bit)&&(!(i&0x80)))
@@ -1435,16 +1434,16 @@ static int cmd_out_T(void)
sbp_sleep(1);
}
while (j<0);
- D_S[d].error_state=infobuf[2];
- D_S[d].b3=infobuf[3];
- D_S[d].b4=infobuf[4];
- if (D_S[d].f_drv_error)
+ current_drive->error_state=infobuf[2];
+ current_drive->b3=infobuf[3];
+ current_drive->b4=infobuf[4];
+ if (current_drive->f_drv_error)
{
- D_S[d].f_drv_error=0;
+ current_drive->f_drv_error=0;
cc_DriveReset();
- D_S[d].error_state=2;
+ current_drive->error_state=2;
}
- return (-D_S[d].error_state-400);
+ return (-current_drive->error_state-400);
}
if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
if ((teac==0)||(ntries<(CMDT_TRIES-5))) sbp_sleep(HZ/10);
@@ -1452,9 +1451,9 @@ static int cmd_out_T(void)
if (ntries>(CMDT_TRIES-50)) continue;
msg(DBG_TEA,"cmd_out_T: next CMDT_TRIES (%02X): %d.\n", drvcmd[0], ntries-1);
}
- D_S[d].f_drv_error=1;
+ current_drive->f_drv_error=1;
cc_DriveReset();
- D_S[d].error_state=2;
+ current_drive->error_state=2;
return (-99);
}
/*==========================================================================*/
@@ -1487,7 +1486,7 @@ static int cmd_out(void)
else i=ResponseInfo();
if (i<0) return (i);
}
- if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to CDi_stat_loop.\n");
+ if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to CDi_stat_loop.\n");
if (flags_cmd_out&f_lopsta)
{
i=CDi_stat_loop();
@@ -1496,13 +1495,13 @@ static int cmd_out(void)
if (!(flags_cmd_out&f_getsta)) goto LOC_229;
LOC_228:
- if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadStatus.\n");
+ if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadStatus.\n");
cc_ReadStatus();
LOC_229:
if (flags_cmd_out&f_ResponseStatus)
{
- if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to ResponseStatus.\n");
+ if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to ResponseStatus.\n");
i=ResponseStatus();
/* builds status_bits, returns orig. status or p_busy_new */
if (i<0) return (i);
@@ -1518,9 +1517,9 @@ static int cmd_out(void)
LOC_232:
if (!(flags_cmd_out&f_obey_p_check)) return (0);
if (!st_check) return (0);
- if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadError.\n");
+ if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadError.\n");
i=cc_ReadError();
- if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cmd_out OK.\n");
+ if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cmd_out OK.\n");
msg(DBG_000,"cmd_out: cc_ReadError=%d\n", i);
return (i);
}
@@ -1574,7 +1573,7 @@ static int cc_Seek(u_int pos, char f_blk_msf)
drvcmd[3]=(pos>>16)&0x00FF;
drvcmd[4]=(pos>>8)&0x00FF;
drvcmd[5]=pos&0x00FF;
- D_S[d].n_bytes=1;
+ current_drive->n_bytes=1;
}
response_count=0;
i=cmd_out();
@@ -1586,7 +1585,7 @@ static int cc_SpinUp(void)
int i;
msg(DBG_SPI,"SpinUp.\n");
- D_S[d].in_SpinUp = 1;
+ current_drive->in_SpinUp = 1;
clr_cmdbuf();
if (fam0LV_drive)
{
@@ -1615,7 +1614,7 @@ static int cc_SpinUp(void)
}
response_count=0;
i=cmd_out();
- D_S[d].in_SpinUp = 0;
+ current_drive->in_SpinUp = 0;
return (i);
}
/*==========================================================================*/
@@ -1676,15 +1675,15 @@ static int cc_set_mode_T(void)
clr_cmdbuf();
response_count=1;
drvcmd[0]=CMDT_SETMODE;
- drvcmd[1]=D_S[d].speed_byte;
- drvcmd[2]=D_S[d].frmsiz>>8;
- drvcmd[3]=D_S[d].frmsiz&0x0FF;
- drvcmd[4]=D_S[d].f_XA; /* 1: XA */
- drvcmd[5]=D_S[d].type_byte; /* 0, 1, 3 */
- drvcmd[6]=D_S[d].mode_xb_6;
- drvcmd[7]=D_S[d].mode_yb_7|D_S[d].volume_control;
- drvcmd[8]=D_S[d].mode_xb_8;
- drvcmd[9]=D_S[d].delay;
+ drvcmd[1]=current_drive->speed_byte;
+ drvcmd[2]=current_drive->frmsiz>>8;
+ drvcmd[3]=current_drive->frmsiz&0x0FF;
+ drvcmd[4]=current_drive->f_XA; /* 1: XA */
+ drvcmd[5]=current_drive->type_byte; /* 0, 1, 3 */
+ drvcmd[6]=current_drive->mode_xb_6;
+ drvcmd[7]=current_drive->mode_yb_7|current_drive->volume_control;
+ drvcmd[8]=current_drive->mode_xb_8;
+ drvcmd[9]=current_drive->delay;
i=cmd_out_T();
return (i);
}
@@ -1699,15 +1698,15 @@ static int cc_prep_mode_T(void)
sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
msgbuf[i*3]=0;
msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf);
- D_S[d].speed_byte=0x02; /* 0x02: auto quad, 0x82: quad, 0x81: double, 0x80: single */
- D_S[d].frmsiz=make16(infobuf[2],infobuf[3]);
- D_S[d].f_XA=infobuf[4];
- if (D_S[d].f_XA==0) D_S[d].type_byte=0;
- else D_S[d].type_byte=1;
- D_S[d].mode_xb_6=infobuf[6];
- D_S[d].mode_yb_7=1;
- D_S[d].mode_xb_8=infobuf[8];
- D_S[d].delay=0; /* 0, 1, 2, 3 */
+ current_drive->speed_byte=0x02; /* 0x02: auto quad, 0x82: quad, 0x81: double, 0x80: single */
+ current_drive->frmsiz=make16(infobuf[2],infobuf[3]);
+ current_drive->f_XA=infobuf[4];
+ if (current_drive->f_XA==0) current_drive->type_byte=0;
+ else current_drive->type_byte=1;
+ current_drive->mode_xb_6=infobuf[6];
+ current_drive->mode_yb_7=1;
+ current_drive->mode_xb_8=infobuf[8];
+ current_drive->delay=0; /* 0, 1, 2, 3 */
j=cc_set_mode_T();
i=cc_get_mode_T();
for (i=0;i<10;i++)
@@ -1762,17 +1761,17 @@ static int cc_SetVolume(void)
u_char channel0,channel1,volume0,volume1;
u_char control0,value0,control1,value1;
- D_S[d].diskstate_flags &= ~volume_bit;
+ current_drive->diskstate_flags &= ~volume_bit;
clr_cmdbuf();
- channel0=D_S[d].vol_chan0;
- volume0=D_S[d].vol_ctrl0;
- channel1=control1=D_S[d].vol_chan1;
- volume1=value1=D_S[d].vol_ctrl1;
+ channel0=current_drive->vol_chan0;
+ volume0=current_drive->vol_ctrl0;
+ channel1=control1=current_drive->vol_chan1;
+ volume1=value1=current_drive->vol_ctrl1;
control0=value0=0;
if (famV_drive) return (0);
- if (((D_S[d].drv_options&audio_mono)!=0)&&(D_S[d].drv_type>=drv_211))
+ if (((current_drive->drv_options&audio_mono)!=0)&&(current_drive->drv_type>=drv_211))
{
if ((volume0!=0)&&(volume1==0))
{
@@ -1841,7 +1840,7 @@ static int cc_SetVolume(void)
}
else if (fam0_drive) /* different firmware levels */
{
- if (D_S[d].drv_type>=drv_300)
+ if (current_drive->drv_type>=drv_300)
{
control0=volume0&0xFC;
value0=volume1&0xFC;
@@ -1853,7 +1852,7 @@ static int cc_SetVolume(void)
else
{
value0=(volume0>volume1)?volume0:volume1;
- if (D_S[d].drv_type<drv_211)
+ if (current_drive->drv_type<drv_211)
{
if (channel0!=0)
{
@@ -1886,14 +1885,14 @@ static int cc_SetVolume(void)
if (volume0==0xFF) volume1=0xFF;
else if (volume1==0xFF) volume0=0xFF;
}
- else if (D_S[d].drv_type<drv_201) volume0=volume1=value0;
+ else if (current_drive->drv_type<drv_201) volume0=volume1=value0;
- if (D_S[d].drv_type>=drv_201)
+ if (current_drive->drv_type>=drv_201)
{
if (volume0==0) control0 |= 0x80;
if (volume1==0) control0 |= 0x40;
}
- if (D_S[d].drv_type>=drv_211)
+ if (current_drive->drv_type>=drv_211)
{
if (channel0!=0) control0 |= 0x20;
if (channel1!=1) control0 |= 0x10;
@@ -1907,9 +1906,9 @@ static int cc_SetVolume(void)
}
else if (famT_drive)
{
- D_S[d].volume_control=0;
- if (!volume0) D_S[d].volume_control|=0x10;
- if (!volume1) D_S[d].volume_control|=0x20;
+ current_drive->volume_control=0;
+ if (!volume0) current_drive->volume_control|=0x10;
+ if (!volume1) current_drive->volume_control|=0x20;
i=cc_prep_mode_T();
if (i<0) return (i);
}
@@ -1919,7 +1918,7 @@ static int cc_SetVolume(void)
i=cmd_out();
if (i<0) return (i);
}
- D_S[d].diskstate_flags |= volume_bit;
+ current_drive->diskstate_flags |= volume_bit;
return (0);
}
/*==========================================================================*/
@@ -1959,7 +1958,7 @@ static int cc_DriveReset(void)
else if (famT_drive)
{
OUT(CDo_sel_i_d,0);
- OUT(CDo_enable,D_S[d].drv_sel);
+ OUT(CDo_enable,current_drive->drv_sel);
OUT(CDo_command,CMDT_RESET);
for (i=1;i<10;i++) OUT(CDo_command,0);
}
@@ -1976,7 +1975,7 @@ static int cc_DriveReset(void)
i=GetStatus();
if (i<0) return i;
if (!famT_drive)
- if (D_S[d].error_byte!=aud_12) return -501;
+ if (current_drive->error_byte!=aud_12) return -501;
return (0);
}
@@ -1985,27 +1984,26 @@ static int SetSpeed(void)
{
int i, speed;
- if (!(D_S[d].drv_options&(speed_auto|speed_300|speed_150))) return (0);
+ if (!(current_drive->drv_options&(speed_auto|speed_300|speed_150))) return (0);
speed=speed_auto;
- if (!(D_S[d].drv_options&speed_auto))
+ if (!(current_drive->drv_options&speed_auto))
{
speed |= speed_300;
- if (!(D_S[d].drv_options&speed_300)) speed=0;
+ if (!(current_drive->drv_options&speed_300)) speed=0;
}
i=cc_SetSpeed(speed,0,0);
return (i);
}
-static void switch_drive(int i);
+static void switch_drive(struct sbpcd_drive *);
static int sbpcd_select_speed(struct cdrom_device_info *cdi, int speed)
{
- int i = minor(cdi->dev);
+ struct sbpcd_drive *p = cdi->handle;
+ if (p != current_drive)
+ switch_drive(p);
- if (i != d)
- switch_drive(i);
-
- return cc_SetSpeed(speed == 2 ? speed_300 : speed_150, 0, 0);
+ return cc_SetSpeed(speed == 2 ? speed_300 : speed_150, 0, 0);
}
/*==========================================================================*/
@@ -2026,7 +2024,7 @@ static int DriveReset(void)
}
while (!st_diskok);
#if 000
- D_S[d].CD_changed=1;
+ current_drive->CD_changed=1;
#endif
if ((st_door_closed) && (st_caddy_in))
{
@@ -2038,12 +2036,10 @@ static int DriveReset(void)
static int sbpcd_reset(struct cdrom_device_info *cdi)
{
- int i = minor(cdi->dev);
-
- if (i != d)
- switch_drive(i);
-
- return DriveReset();
+ struct sbpcd_drive *p = cdi->handle;
+ if (p != current_drive)
+ switch_drive(p);
+ return DriveReset();
}
/*==========================================================================*/
@@ -2051,7 +2047,7 @@ static int cc_PlayAudio(int pos_audio_start,int pos_audio_end)
{
int i, j, n;
- if (D_S[d].audio_state==audio_playing) return (-EINVAL);
+ if (current_drive->audio_state==audio_playing) return (-EINVAL);
clr_cmdbuf();
response_count=0;
if (famLV_drive)
@@ -2141,7 +2137,7 @@ static int cc_Pause_Resume(int pau_res)
}
else if (famT_drive)
{
- if (pau_res==3) return (cc_PlayAudio(D_S[d].pos_audio_start,D_S[d].pos_audio_end));
+ if (pau_res==3) return (cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end));
else if (pau_res==1) drvcmd[0]=CMDT_PAUSE;
else return (-56);
}
@@ -2154,7 +2150,7 @@ static int cc_LockDoor(char lock)
int i;
if (fam0_drive) return (0);
- msg(DBG_LCK,"cc_LockDoor: %d (drive %d)\n", lock, d);
+ msg(DBG_LCK,"cc_LockDoor: %d (drive %d)\n", lock, current_drive - D_S);
msg(DBG_LCS,"p_door_locked bit %d before\n", st_door_locked);
clr_cmdbuf();
response_count=0;
@@ -2248,7 +2244,7 @@ static int cc_CloseTray(void)
int i;
if (fam0_drive) return (0);
- msg(DBG_LCK,"cc_CloseTray (drive %d)\n", d);
+ msg(DBG_LCK,"cc_CloseTray (drive %d)\n", current_drive - D_S);
msg(DBG_LCS,"p_door_closed bit %d before\n", st_door_closed);
clr_cmdbuf();
@@ -2317,14 +2313,12 @@ static int cc_CloseTray(void)
static int sbpcd_tray_move(struct cdrom_device_info *cdi, int position)
{
- int i;
int retval=0;
- i = minor(cdi->dev);
- switch_drive(i);
+ switch_drive(cdi->handle);
/* DUH! --AJK */
- if(D_S[d].CD_changed != 0xFF) {
- D_S[d].CD_changed=0xFF;
- D_S[d].diskstate_flags &= ~cd_size_bit;
+ if(current_drive->CD_changed != 0xFF) {
+ current_drive->CD_changed=0xFF;
+ current_drive->diskstate_flags &= ~cd_size_bit;
}
if (position == 1) {
cc_SpinDown();
@@ -2339,7 +2333,7 @@ static int cc_ReadSubQ(void)
{
int i,j;
- D_S[d].diskstate_flags &= ~subq_bit;
+ current_drive->diskstate_flags &= ~subq_bit;
for (j=255;j>0;j--)
{
clr_cmdbuf();
@@ -2388,26 +2382,26 @@ static int cc_ReadSubQ(void)
if (infobuf[0]!=0) break;
if ((!st_spinning) || (j==1))
{
- D_S[d].SubQ_ctl_adr=D_S[d].SubQ_trk=D_S[d].SubQ_pnt_idx=D_S[d].SubQ_whatisthis=0;
- D_S[d].SubQ_run_tot=D_S[d].SubQ_run_trk=0;
+ current_drive->SubQ_ctl_adr=current_drive->SubQ_trk=current_drive->SubQ_pnt_idx=current_drive->SubQ_whatisthis=0;
+ current_drive->SubQ_run_tot=current_drive->SubQ_run_trk=0;
return (0);
}
}
- if (famT_drive) D_S[d].SubQ_ctl_adr=infobuf[1];
- else D_S[d].SubQ_ctl_adr=swap_nibbles(infobuf[1]);
- D_S[d].SubQ_trk=byt2bcd(infobuf[2]);
- D_S[d].SubQ_pnt_idx=byt2bcd(infobuf[3]);
+ if (famT_drive) current_drive->SubQ_ctl_adr=infobuf[1];
+ else current_drive->SubQ_ctl_adr=swap_nibbles(infobuf[1]);
+ current_drive->SubQ_trk=byt2bcd(infobuf[2]);
+ current_drive->SubQ_pnt_idx=byt2bcd(infobuf[3]);
if (fam0LV_drive) i=5;
else if (fam12_drive) i=4;
else if (famT_drive) i=8;
- D_S[d].SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
+ current_drive->SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
i=7;
if (fam0LV_drive) i=9;
else if (fam12_drive) i=7;
else if (famT_drive) i=4;
- D_S[d].SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
- D_S[d].SubQ_whatisthis=infobuf[i+3];
- D_S[d].diskstate_flags |= subq_bit;
+ current_drive->SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
+ current_drive->SubQ_whatisthis=infobuf[i+3];
+ current_drive->diskstate_flags |= subq_bit;
return (0);
}
/*==========================================================================*/
@@ -2417,7 +2411,7 @@ static int cc_ModeSense(void)
if (fam2_drive) return (0);
if (famV_drive) return (0);
- D_S[d].diskstate_flags &= ~frame_size_bit;
+ current_drive->diskstate_flags &= ~frame_size_bit;
clr_cmdbuf();
if (fam1_drive)
{
@@ -2441,21 +2435,21 @@ static int cc_ModeSense(void)
i=cmd_out();
if (i<0) return (i);
i=0;
- D_S[d].sense_byte=0;
- if (fam1_drive) D_S[d].sense_byte=infobuf[i++];
+ current_drive->sense_byte=0;
+ if (fam1_drive) current_drive->sense_byte=infobuf[i++];
else if (famT_drive)
{
- if (infobuf[4]==0x01) D_S[d].xa_byte=0x20;
- else D_S[d].xa_byte=0;
+ if (infobuf[4]==0x01) current_drive->xa_byte=0x20;
+ else current_drive->xa_byte=0;
i=2;
}
- D_S[d].frame_size=make16(infobuf[i],infobuf[i+1]);
+ current_drive->frame_size=make16(infobuf[i],infobuf[i+1]);
for (i=0;i<response_count;i++)
sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
msgbuf[i*3]=0;
msg(DBG_XA1,"cc_ModeSense:%s\n", msgbuf);
- D_S[d].diskstate_flags |= frame_size_bit;
+ current_drive->diskstate_flags |= frame_size_bit;
return (0);
}
/*==========================================================================*/
@@ -2466,30 +2460,30 @@ static int cc_ModeSelect(int framesize)
if (fam2_drive) return (0);
if (famV_drive) return (0);
- D_S[d].diskstate_flags &= ~frame_size_bit;
+ current_drive->diskstate_flags &= ~frame_size_bit;
clr_cmdbuf();
- D_S[d].frame_size=framesize;
- if (framesize==CD_FRAMESIZE_RAW) D_S[d].sense_byte=0x82;
- else D_S[d].sense_byte=0x00;
+ current_drive->frame_size=framesize;
+ if (framesize==CD_FRAMESIZE_RAW) current_drive->sense_byte=0x82;
+ else current_drive->sense_byte=0x00;
msg(DBG_XA1,"cc_ModeSelect: %02X %04X\n",
- D_S[d].sense_byte, D_S[d].frame_size);
+ current_drive->sense_byte, current_drive->frame_size);
if (fam1_drive)
{
drvcmd[0]=CMD1_SETMODE;
drvcmd[1]=0x00;
- drvcmd[2]=D_S[d].sense_byte;
- drvcmd[3]=(D_S[d].frame_size>>8)&0xFF;
- drvcmd[4]=D_S[d].frame_size&0xFF;
+ drvcmd[2]=current_drive->sense_byte;
+ drvcmd[3]=(current_drive->frame_size>>8)&0xFF;
+ drvcmd[4]=current_drive->frame_size&0xFF;
flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
}
else if (fam0L_drive)
{
drvcmd[0]=CMD0_SETMODE;
drvcmd[1]=0x00;
- drvcmd[2]=(D_S[d].frame_size>>8)&0xFF;
- drvcmd[3]=D_S[d].frame_size&0xFF;
+ drvcmd[2]=(current_drive->frame_size>>8)&0xFF;
+ drvcmd[3]=current_drive->frame_size&0xFF;
drvcmd[4]=0x00;
if(famL_drive)
flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check;
@@ -2503,7 +2497,7 @@ static int cc_ModeSelect(int framesize)
response_count=0;
i=cmd_out();
if (i<0) return (i);
- D_S[d].diskstate_flags |= frame_size_bit;
+ current_drive->diskstate_flags |= frame_size_bit;
return (0);
}
/*==========================================================================*/
@@ -2517,7 +2511,7 @@ static int cc_GetVolume(void)
u_char vol1=0;
if (famV_drive) return (0);
- D_S[d].diskstate_flags &= ~volume_bit;
+ current_drive->diskstate_flags &= ~volume_bit;
clr_cmdbuf();
if (fam1_drive)
{
@@ -2593,14 +2587,14 @@ static int cc_GetVolume(void)
chan0=0;
chan1=1;
vol0=vol1=infobuf[1];
- if (D_S[d].drv_type>=drv_201)
+ if (current_drive->drv_type>=drv_201)
{
- if (D_S[d].drv_type<drv_300)
+ if (current_drive->drv_type<drv_300)
{
switches=infobuf[0];
if ((switches&0x80)!=0) vol0=0;
if ((switches&0x40)!=0) vol1=0;
- if (D_S[d].drv_type>=drv_211)
+ if (current_drive->drv_type>=drv_211)
{
if ((switches&0x20)!=0) chan0=1;
if ((switches&0x10)!=0) chan1=0;
@@ -2620,25 +2614,25 @@ static int cc_GetVolume(void)
}
else if (famT_drive)
{
- D_S[d].volume_control=infobuf[7];
+ current_drive->volume_control=infobuf[7];
chan0=0;
chan1=1;
- if (D_S[d].volume_control&0x10) vol0=0;
+ if (current_drive->volume_control&0x10) vol0=0;
else vol0=0xff;
- if (D_S[d].volume_control&0x20) vol1=0;
+ if (current_drive->volume_control&0x20) vol1=0;
else vol1=0xff;
}
- D_S[d].vol_chan0=chan0;
- D_S[d].vol_ctrl0=vol0;
- D_S[d].vol_chan1=chan1;
- D_S[d].vol_ctrl1=vol1;
+ current_drive->vol_chan0=chan0;
+ current_drive->vol_ctrl0=vol0;
+ current_drive->vol_chan1=chan1;
+ current_drive->vol_ctrl1=vol1;
#if 000
- D_S[d].vol_chan2=2;
- D_S[d].vol_ctrl2=0xFF;
- D_S[d].vol_chan3=3;
- D_S[d].vol_ctrl3=0xFF;
+ current_drive->vol_chan2=2;
+ current_drive->vol_ctrl2=0xFF;
+ current_drive->vol_chan3=3;
+ current_drive->vol_ctrl3=0xFF;
#endif /* 000 */
- D_S[d].diskstate_flags |= volume_bit;
+ current_drive->diskstate_flags |= volume_bit;
return (0);
}
/*==========================================================================*/
@@ -2649,7 +2643,7 @@ static int cc_ReadCapacity(void)
if (fam2_drive) return (0); /* some firmware lacks this command */
if (famLV_drive) return (0); /* some firmware lacks this command */
if (famT_drive) return (0); /* done with cc_ReadTocDescr() */
- D_S[d].diskstate_flags &= ~cd_size_bit;
+ current_drive->diskstate_flags &= ~cd_size_bit;
for (j=3;j>0;j--)
{
clr_cmdbuf();
@@ -2679,13 +2673,13 @@ static int cc_ReadCapacity(void)
cc_ReadError();
}
if (j==0) return (i);
- if (fam1_drive) D_S[d].CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_MSF_OFFSET;
- else if (fam0_drive) D_S[d].CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
+ if (fam1_drive) current_drive->CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_MSF_OFFSET;
+ else if (fam0_drive) current_drive->CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
#if 00
- else if (fam2_drive) D_S[d].CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
+ else if (fam2_drive) current_drive->CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
#endif
- D_S[d].diskstate_flags |= cd_size_bit;
- msg(DBG_000,"cc_ReadCapacity: %d frames.\n", D_S[d].CDsize_frm);
+ current_drive->diskstate_flags |= cd_size_bit;
+ msg(DBG_000,"cc_ReadCapacity: %d frames.\n", current_drive->CDsize_frm);
return (0);
}
/*==========================================================================*/
@@ -2693,7 +2687,7 @@ static int cc_ReadTocDescr(void)
{
int i;
- D_S[d].diskstate_flags &= ~toc_bit;
+ current_drive->diskstate_flags &= ~toc_bit;
clr_cmdbuf();
if (fam1_drive)
{
@@ -2713,7 +2707,7 @@ static int cc_ReadTocDescr(void)
else if (fam2_drive)
{
/* possibly longer timeout periods necessary */
- D_S[d].f_multisession=0;
+ current_drive->f_multisession=0;
drvcmd[0]=CMD2_DISKINFO;
drvcmd[1]=0x02;
drvcmd[2]=0xAB;
@@ -2723,7 +2717,7 @@ static int cc_ReadTocDescr(void)
}
else if (famT_drive)
{
- D_S[d].f_multisession=0;
+ current_drive->f_multisession=0;
response_count=12;
drvcmd[0]=CMDT_DISKINFO;
drvcmd[1]=0x02;
@@ -2735,25 +2729,25 @@ static int cc_ReadTocDescr(void)
if (i<0) return (i);
if ((famT_drive)&&(i<response_count)) return (-100-i);
if ((fam1_drive)||(fam2_drive)||(fam0LV_drive))
- D_S[d].xa_byte=infobuf[0];
+ current_drive->xa_byte=infobuf[0];
if (fam2_drive)
{
- D_S[d].first_session=infobuf[1];
- D_S[d].last_session=infobuf[2];
- D_S[d].n_first_track=infobuf[3];
- D_S[d].n_last_track=infobuf[4];
- if (D_S[d].first_session!=D_S[d].last_session)
+ current_drive->first_session=infobuf[1];
+ current_drive->last_session=infobuf[2];
+ current_drive->n_first_track=infobuf[3];
+ current_drive->n_last_track=infobuf[4];
+ if (current_drive->first_session!=current_drive->last_session)
{
- D_S[d].f_multisession=1;
- D_S[d].lba_multi=msf2blk(make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7])));
+ current_drive->f_multisession=1;
+ current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7])));
}
#if 0
- if (D_S[d].first_session!=D_S[d].last_session)
+ if (current_drive->first_session!=current_drive->last_session)
{
- if (D_S[d].last_session<=20)
- zwanzig=D_S[d].last_session+1;
+ if (current_drive->last_session<=20)
+ zwanzig=current_drive->last_session+1;
else zwanzig=20;
- for (count=D_S[d].first_session;count<zwanzig;count++)
+ for (count=current_drive->first_session;count<zwanzig;count++)
{
drvcmd[0]=CMD2_DISKINFO;
drvcmd[1]=0x02;
@@ -2763,9 +2757,9 @@ static int cc_ReadTocDescr(void)
flags_cmd_out=f_putcmd;
i=cmd_out();
if (i<0) return (i);
- D_S[d].msf_multi_n[count]=make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7]));
+ current_drive->msf_multi_n[count]=make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7]));
}
- D_S[d].diskstate_flags |= multisession_bit;
+ current_drive->diskstate_flags |= multisession_bit;
}
#endif
drvcmd[0]=CMD2_DISKINFO;
@@ -2776,34 +2770,34 @@ static int cc_ReadTocDescr(void)
flags_cmd_out=f_putcmd;
i=cmd_out();
if (i<0) return (i);
- D_S[d].size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
- D_S[d].size_blk=msf2blk(D_S[d].size_msf);
- D_S[d].CDsize_frm=D_S[d].size_blk+1;
+ current_drive->size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
+ current_drive->size_blk=msf2blk(current_drive->size_msf);
+ current_drive->CDsize_frm=current_drive->size_blk+1;
}
else if (famT_drive)
{
- D_S[d].size_msf=make32(make16(infobuf[8],infobuf[9]),make16(infobuf[10],infobuf[11]));
- D_S[d].size_blk=msf2blk(D_S[d].size_msf);
- D_S[d].CDsize_frm=D_S[d].size_blk+1;
- D_S[d].n_first_track=infobuf[2];
- D_S[d].n_last_track=infobuf[3];
+ current_drive->size_msf=make32(make16(infobuf[8],infobuf[9]),make16(infobuf[10],infobuf[11]));
+ current_drive->size_blk=msf2blk(current_drive->size_msf);
+ current_drive->CDsize_frm=current_drive->size_blk+1;
+ current_drive->n_first_track=infobuf[2];
+ current_drive->n_last_track=infobuf[3];
}
else
{
- D_S[d].n_first_track=infobuf[1];
- D_S[d].n_last_track=infobuf[2];
- D_S[d].size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
- D_S[d].size_blk=msf2blk(D_S[d].size_msf);
- if (famLV_drive) D_S[d].CDsize_frm=D_S[d].size_blk+1;
+ current_drive->n_first_track=infobuf[1];
+ current_drive->n_last_track=infobuf[2];
+ current_drive->size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
+ current_drive->size_blk=msf2blk(current_drive->size_msf);
+ if (famLV_drive) current_drive->CDsize_frm=current_drive->size_blk+1;
}
- D_S[d].diskstate_flags |= toc_bit;
+ current_drive->diskstate_flags |= toc_bit;
msg(DBG_TOC,"TocDesc: xa %02X firstt %02X lastt %02X size %08X firstses %02X lastsess %02X\n",
- D_S[d].xa_byte,
- D_S[d].n_first_track,
- D_S[d].n_last_track,
- D_S[d].size_msf,
- D_S[d].first_session,
- D_S[d].last_session);
+ current_drive->xa_byte,
+ current_drive->n_first_track,
+ current_drive->n_last_track,
+ current_drive->size_msf,
+ current_drive->first_session,
+ current_drive->last_session);
return (0);
}
/*==========================================================================*/
@@ -2853,36 +2847,36 @@ static int cc_ReadTocEntry(int num)
if ((famT_drive)&&(i<response_count)) return (-100-i);
if ((fam1_drive)||(fam0LV_drive))
{
- D_S[d].TocEnt_nixbyte=infobuf[0];
+ current_drive->TocEnt_nixbyte=infobuf[0];
i=1;
}
else if (fam2_drive) i=0;
else if (famT_drive) i=5;
- D_S[d].TocEnt_ctl_adr=swap_nibbles(infobuf[i++]);
+ current_drive->TocEnt_ctl_adr=swap_nibbles(infobuf[i++]);
if ((fam1_drive)||(fam0L_drive))
{
- D_S[d].TocEnt_number=infobuf[i++];
- D_S[d].TocEnt_format=infobuf[i];
+ current_drive->TocEnt_number=infobuf[i++];
+ current_drive->TocEnt_format=infobuf[i];
}
else
{
- D_S[d].TocEnt_number=num;
- D_S[d].TocEnt_format=0;
+ current_drive->TocEnt_number=num;
+ current_drive->TocEnt_format=0;
}
if (fam1_drive) i=4;
else if (fam0LV_drive) i=5;
else if (fam2_drive) i=2;
else if (famT_drive) i=9;
- D_S[d].TocEnt_address=make32(make16(0,infobuf[i]),
+ current_drive->TocEnt_address=make32(make16(0,infobuf[i]),
make16(infobuf[i+1],infobuf[i+2]));
for (i=0;i<response_count;i++)
sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
msgbuf[i*3]=0;
msg(DBG_ECS,"TocEntry:%s\n", msgbuf);
msg(DBG_TOC,"TocEntry: %02X %02X %02X %02X %08X\n",
- D_S[d].TocEnt_nixbyte, D_S[d].TocEnt_ctl_adr,
- D_S[d].TocEnt_number, D_S[d].TocEnt_format,
- D_S[d].TocEnt_address);
+ current_drive->TocEnt_nixbyte, current_drive->TocEnt_ctl_adr,
+ current_drive->TocEnt_number, current_drive->TocEnt_format,
+ current_drive->TocEnt_address);
return (0);
}
/*==========================================================================*/
@@ -2913,11 +2907,11 @@ static int convert_UPC(u_char *p)
if (fam0L_drive) p[13]=0;
for (i=0;i<7;i++)
{
- if (fam1_drive) D_S[d].UPC_buf[i]=swap_nibbles(*p++);
+ if (fam1_drive) current_drive->UPC_buf[i]=swap_nibbles(*p++);
else if (fam0L_drive)
{
- D_S[d].UPC_buf[i]=((*p++)<<4)&0xFF;
- D_S[d].UPC_buf[i] |= *p++;
+ current_drive->UPC_buf[i]=((*p++)<<4)&0xFF;
+ current_drive->UPC_buf[i] |= *p++;
}
else if (famT_drive)
{
@@ -2928,7 +2922,7 @@ static int convert_UPC(u_char *p)
return (-1);
}
}
- D_S[d].UPC_buf[6] &= 0xF0;
+ current_drive->UPC_buf[6] &= 0xF0;
return (0);
}
/*==========================================================================*/
@@ -2946,7 +2940,7 @@ static int cc_ReadUPC(void)
if (fam0_drive) return (0); /* but it should work */
#endif
- D_S[d].diskstate_flags &= ~upc_bit;
+ current_drive->diskstate_flags &= ~upc_bit;
#if TEST_UPC
for (block=CD_MSF_OFFSET+1;block<CD_MSF_OFFSET+200;block++)
{
@@ -3015,20 +3009,20 @@ static int cc_ReadUPC(void)
if ((checksum&0x7F)!=0) break;
}
#endif /* TEST_UPC */
- D_S[d].UPC_ctl_adr=0;
+ current_drive->UPC_ctl_adr=0;
if (fam1_drive) i=0;
else i=2;
if ((infobuf[i]&0x80)!=0)
{
convert_UPC(&infobuf[i]);
- D_S[d].UPC_ctl_adr = (D_S[d].TocEnt_ctl_adr & 0xF0) | 0x02;
+ current_drive->UPC_ctl_adr = (current_drive->TocEnt_ctl_adr & 0xF0) | 0x02;
}
for (i=0;i<7;i++)
- sprintf(&msgbuf[i*3], " %02X", D_S[d].UPC_buf[i]);
- sprintf(&msgbuf[i*3], " (%02X)", D_S[d].UPC_ctl_adr);
+ sprintf(&msgbuf[i*3], " %02X", current_drive->UPC_buf[i]);
+ sprintf(&msgbuf[i*3], " (%02X)", current_drive->UPC_ctl_adr);
msgbuf[i*3+5]=0;
msg(DBG_UPC,"UPC code:%s\n", msgbuf);
- D_S[d].diskstate_flags |= upc_bit;
+ current_drive->diskstate_flags |= upc_bit;
return (0);
}
@@ -3038,7 +3032,7 @@ static int sbpcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
unsigned char *mcnp = mcn->medium_catalog_number;
unsigned char *resp;
- D_S[d].diskstate_flags &= ~upc_bit;
+ current_drive->diskstate_flags &= ~upc_bit;
clr_cmdbuf();
if (fam1_drive)
{
@@ -3077,7 +3071,7 @@ static int sbpcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
return (i);
}
}
- D_S[d].UPC_ctl_adr=0;
+ current_drive->UPC_ctl_adr=0;
if (fam1_drive) i=0;
else i=2;
@@ -3100,7 +3094,7 @@ static int sbpcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
}
*mcnp = '\0';
- D_S[d].diskstate_flags |= upc_bit;
+ current_drive->diskstate_flags |= upc_bit;
return (0);
}
@@ -3110,8 +3104,8 @@ static int cc_CheckMultiSession(void)
int i;
if (fam2_drive) return (0);
- D_S[d].f_multisession=0;
- D_S[d].lba_multi=0;
+ current_drive->f_multisession=0;
+ current_drive->lba_multi=0;
if (fam0_drive) return (0);
clr_cmdbuf();
if (fam1_drive)
@@ -3123,8 +3117,8 @@ static int cc_CheckMultiSession(void)
if (i<0) return (i);
if ((infobuf[0]&0x80)!=0)
{
- D_S[d].f_multisession=1;
- D_S[d].lba_multi=msf2blk(make32(make16(0,infobuf[1]),
+ current_drive->f_multisession=1;
+ current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[1]),
make16(infobuf[2],infobuf[3])));
}
}
@@ -3137,7 +3131,7 @@ static int cc_CheckMultiSession(void)
flags_cmd_out=f_putcmd;
i=cmd_out();
if (i<0) return (i);
- D_S[d].lba_multi=msf2blk(make32(make16(0,infobuf[5]),
+ current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]),
make16(infobuf[6],infobuf[7])));
}
else if (famT_drive)
@@ -3151,23 +3145,23 @@ static int cc_CheckMultiSession(void)
i=cmd_out();
if (i<0) return (i);
if (i<response_count) return (-100-i);
- D_S[d].first_session=infobuf[2];
- D_S[d].last_session=infobuf[3];
- D_S[d].track_of_last_session=infobuf[6];
- if (D_S[d].first_session!=D_S[d].last_session)
+ current_drive->first_session=infobuf[2];
+ current_drive->last_session=infobuf[3];
+ current_drive->track_of_last_session=infobuf[6];
+ if (current_drive->first_session!=current_drive->last_session)
{
- D_S[d].f_multisession=1;
- D_S[d].lba_multi=msf2blk(make32(make16(0,infobuf[9]),make16(infobuf[10],infobuf[11])));
+ current_drive->f_multisession=1;
+ current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[9]),make16(infobuf[10],infobuf[11])));
}
}
for (i=0;i<response_count;i++)
sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
msgbuf[i*3]=0;
- msg(DBG_MUL,"MultiSession Info:%s (%d)\n", msgbuf, D_S[d].lba_multi);
- if (D_S[d].lba_multi>200)
+ msg(DBG_MUL,"MultiSession Info:%s (%d)\n", msgbuf, current_drive->lba_multi);
+ if (current_drive->lba_multi>200)
{
- D_S[d].f_multisession=1;
- msg(DBG_MUL,"MultiSession base: %06X\n", D_S[d].lba_multi);
+ current_drive->f_multisession=1;
+ msg(DBG_MUL,"MultiSession base: %06X\n", current_drive->lba_multi);
}
return (0);
}
@@ -3184,7 +3178,7 @@ static int cc_SubChanInfo(int frame, int count, u_char *buffer)
return (-1);
}
#if 0
- if (D_S[d].audio_state!=audio_playing) return (-ENODATA);
+ if (current_drive->audio_state!=audio_playing) return (-ENODATA);
#endif
clr_cmdbuf();
drvcmd[0]=CMD1_SUBCHANINF;
@@ -3195,7 +3189,7 @@ static int cc_SubChanInfo(int frame, int count, u_char *buffer)
drvcmd[6]=count&0xFF;
flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
cmd_type=READ_SC;
- D_S[d].frame_size=CD_FRAMESIZE_SUB;
+ current_drive->frame_size=CD_FRAMESIZE_SUB;
i=cmd_out(); /* which buffer to use? */
return (i);
}
@@ -3279,7 +3273,7 @@ static void __init ask_mail(void)
msg(DBG_INF, "(don't mail if you are not using the actual kernel):\n");
msg(DBG_INF, "%s\n", VERSION);
msg(DBG_INF, "address %03X, type %s, drive %s (ID %d)\n",
- CDo_command, type, D_S[d].drive_model, D_S[d].drv_id);
+ CDo_command, type, current_drive->drive_model, current_drive->drv_id);
for (i=0;i<12;i++)
sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
msgbuf[i*3]=0;
@@ -3295,8 +3289,8 @@ static int __init check_version(void)
int i, j, l;
int teac_possible=0;
- msg(DBG_INI,"check_version: id=%d, d=%d.\n", D_S[d].drv_id, d);
- D_S[d].drv_type=0;
+ msg(DBG_INI,"check_version: id=%d, d=%d.\n", current_drive->drv_id, current_drive - D_S);
+ current_drive->drv_type=0;
/* check for CR-52x, CR-56x, LCS-7260 and ECS-AT */
/* clear any pending error state */
@@ -3331,54 +3325,54 @@ static int __init check_version(void)
for (i=0;i<4;i++) if (infobuf[i]!=family1[i]) break;
if (i==4)
{
- D_S[d].drive_model[0]='C';
- D_S[d].drive_model[1]='R';
- D_S[d].drive_model[2]='-';
- D_S[d].drive_model[3]='5';
- D_S[d].drive_model[4]=infobuf[i++];
- D_S[d].drive_model[5]=infobuf[i++];
- D_S[d].drive_model[6]=0;
- D_S[d].drv_type=drv_fam1;
+ current_drive->drive_model[0]='C';
+ current_drive->drive_model[1]='R';
+ current_drive->drive_model[2]='-';
+ current_drive->drive_model[3]='5';
+ current_drive->drive_model[4]=infobuf[i++];
+ current_drive->drive_model[5]=infobuf[i++];
+ current_drive->drive_model[6]=0;
+ current_drive->drv_type=drv_fam1;
}
- if (!D_S[d].drv_type)
+ if (!current_drive->drv_type)
{
for (i=0;i<8;i++) if (infobuf[i]!=family0[i]) break;
if (i==8)
{
- D_S[d].drive_model[0]='C';
- D_S[d].drive_model[1]='R';
- D_S[d].drive_model[2]='-';
- D_S[d].drive_model[3]='5';
- D_S[d].drive_model[4]='2';
- D_S[d].drive_model[5]='x';
- D_S[d].drive_model[6]=0;
- D_S[d].drv_type=drv_fam0;
+ current_drive->drive_model[0]='C';
+ current_drive->drive_model[1]='R';
+ current_drive->drive_model[2]='-';
+ current_drive->drive_model[3]='5';
+ current_drive->drive_model[4]='2';
+ current_drive->drive_model[5]='x';
+ current_drive->drive_model[6]=0;
+ current_drive->drv_type=drv_fam0;
}
}
- if (!D_S[d].drv_type)
+ if (!current_drive->drv_type)
{
for (i=0;i<8;i++) if (infobuf[i]!=familyL[i]) break;
if (i==8)
{
for (j=0;j<8;j++)
- D_S[d].drive_model[j]=infobuf[j];
- D_S[d].drive_model[8]=0;
- D_S[d].drv_type=drv_famL;
+ current_drive->drive_model[j]=infobuf[j];
+ current_drive->drive_model[8]=0;
+ current_drive->drv_type=drv_famL;
}
}
- if (!D_S[d].drv_type)
+ if (!current_drive->drv_type)
{
for (i=0;i<6;i++) if (infobuf[i]!=familyV[i]) break;
if (i==6)
{
for (j=0;j<6;j++)
- D_S[d].drive_model[j]=infobuf[j];
- D_S[d].drive_model[6]=0;
- D_S[d].drv_type=drv_famV;
+ current_drive->drive_model[j]=infobuf[j];
+ current_drive->drive_model[6]=0;
+ current_drive->drv_type=drv_famV;
i+=2; /* 2 blanks before version */
}
}
- if (!D_S[d].drv_type)
+ if (!current_drive->drv_type)
{
/* check for CD200 */
clr_cmdbuf();
@@ -3395,7 +3389,7 @@ static int __init check_version(void)
#if 0
OUT(CDo_reset,0);
sbp_sleep(6*HZ);
- OUT(CDo_enable,D_S[d].drv_sel);
+ OUT(CDo_enable,current_drive->drv_sel);
#endif
drvcmd[0]=CMD2_READ_VER;
response_count=12;
@@ -3421,37 +3415,37 @@ static int __init check_version(void)
for (i=0;i<5;i++) if (infobuf[i]!=family2[i]) break;
if (i==5)
{
- D_S[d].drive_model[0]='C';
- D_S[d].drive_model[1]='D';
- D_S[d].drive_model[2]='2';
- D_S[d].drive_model[3]='0';
- D_S[d].drive_model[4]='0';
- D_S[d].drive_model[5]=infobuf[i++];
- D_S[d].drive_model[6]=infobuf[i++];
- D_S[d].drive_model[7]=0;
- D_S[d].drv_type=drv_fam2;
+ current_drive->drive_model[0]='C';
+ current_drive->drive_model[1]='D';
+ current_drive->drive_model[2]='2';
+ current_drive->drive_model[3]='0';
+ current_drive->drive_model[4]='0';
+ current_drive->drive_model[5]=infobuf[i++];
+ current_drive->drive_model[6]=infobuf[i++];
+ current_drive->drive_model[7]=0;
+ current_drive->drv_type=drv_fam2;
}
}
}
- if (!D_S[d].drv_type)
+ if (!current_drive->drv_type)
{
/* check for TEAC CD-55A */
msg(DBG_TEA,"teac_possible: %d\n",teac_possible);
- for (j=1;j<=((D_S[d].drv_id==0)?3:1);j++)
+ for (j=1;j<=((current_drive->drv_id==0)?3:1);j++)
{
- for (l=1;l<=((D_S[d].drv_id==0)?10:1);l++)
+ for (l=1;l<=((current_drive->drv_id==0)?10:1);l++)
{
msg(DBG_TEA,"TEAC reset #%d-%d.\n", j, l);
if (sbpro_type==1) OUT(CDo_reset,0);
else
{
- OUT(CDo_enable,D_S[d].drv_sel);
+ OUT(CDo_enable,current_drive->drv_sel);
OUT(CDo_sel_i_d,0);
OUT(CDo_command,CMDT_RESET);
for (i=0;i<9;i++) OUT(CDo_command,0);
}
sbp_sleep(5*HZ/10);
- OUT(CDo_enable,D_S[d].drv_sel);
+ OUT(CDo_enable,current_drive->drv_sel);
OUT(CDo_sel_i_d,0);
i=inb(CDi_status);
msg(DBG_TEA,"TEAC CDi_status: %02X.\n",i);
@@ -3478,82 +3472,82 @@ static int __init check_version(void)
for (i=1;i<6;i++) if (infobuf[i]!=familyT[i-1]) break;
if (i==6)
{
- D_S[d].drive_model[0]='C';
- D_S[d].drive_model[1]='D';
- D_S[d].drive_model[2]='-';
- D_S[d].drive_model[3]='5';
- D_S[d].drive_model[4]='5';
- D_S[d].drive_model[5]=0;
- D_S[d].drv_type=drv_famT;
+ current_drive->drive_model[0]='C';
+ current_drive->drive_model[1]='D';
+ current_drive->drive_model[2]='-';
+ current_drive->drive_model[3]='5';
+ current_drive->drive_model[4]='5';
+ current_drive->drive_model[5]=0;
+ current_drive->drv_type=drv_famT;
}
}
}
- if (!D_S[d].drv_type)
+ if (!current_drive->drv_type)
{
- msg(DBG_TEA,"no drive found at address %03X under ID %d.\n",CDo_command,D_S[d].drv_id);
+ msg(DBG_TEA,"no drive found at address %03X under ID %d.\n",CDo_command,current_drive->drv_id);
return (-522);
}
- for (j=0;j<4;j++) D_S[d].firmware_version[j]=infobuf[i+j];
+ for (j=0;j<4;j++) current_drive->firmware_version[j]=infobuf[i+j];
if (famL_drive)
{
u_char lcs_firm_e1[]="A E1";
u_char lcs_firm_f4[]="A4F4";
for (j=0;j<4;j++)
- if (D_S[d].firmware_version[j]!=lcs_firm_e1[j]) break;
- if (j==4) D_S[d].drv_type=drv_e1;
+ if (current_drive->firmware_version[j]!=lcs_firm_e1[j]) break;
+ if (j==4) current_drive->drv_type=drv_e1;
for (j=0;j<4;j++)
- if (D_S[d].firmware_version[j]!=lcs_firm_f4[j]) break;
- if (j==4) D_S[d].drv_type=drv_f4;
+ if (current_drive->firmware_version[j]!=lcs_firm_f4[j]) break;
+ if (j==4) current_drive->drv_type=drv_f4;
- if (D_S[d].drv_type==drv_famL) ask_mail();
+ if (current_drive->drv_type==drv_famL) ask_mail();
}
else if (famT_drive)
{
j=infobuf[4]; /* one-byte version??? - here: 0x15 */
if (j=='5')
{
- D_S[d].firmware_version[0]=infobuf[7];
- D_S[d].firmware_version[1]=infobuf[8];
- D_S[d].firmware_version[2]=infobuf[10];
- D_S[d].firmware_version[3]=infobuf[11];
+ current_drive->firmware_version[0]=infobuf[7];
+ current_drive->firmware_version[1]=infobuf[8];
+ current_drive->firmware_version[2]=infobuf[10];
+ current_drive->firmware_version[3]=infobuf[11];
}
else
{
if (j!=0x15) ask_mail();
- D_S[d].firmware_version[0]='0';
- D_S[d].firmware_version[1]='.';
- D_S[d].firmware_version[2]='0'+(j>>4);
- D_S[d].firmware_version[3]='0'+(j&0x0f);
+ current_drive->firmware_version[0]='0';
+ current_drive->firmware_version[1]='.';
+ current_drive->firmware_version[2]='0'+(j>>4);
+ current_drive->firmware_version[3]='0'+(j&0x0f);
}
}
else /* CR-52x, CR-56x, CD200, ECS-AT */
{
- j = (D_S[d].firmware_version[0] & 0x0F) * 100 +
- (D_S[d].firmware_version[2] & 0x0F) *10 +
- (D_S[d].firmware_version[3] & 0x0F);
+ j = (current_drive->firmware_version[0] & 0x0F) * 100 +
+ (current_drive->firmware_version[2] & 0x0F) *10 +
+ (current_drive->firmware_version[3] & 0x0F);
if (fam0_drive)
{
- if (j<200) D_S[d].drv_type=drv_199;
- else if (j<201) D_S[d].drv_type=drv_200;
- else if (j<210) D_S[d].drv_type=drv_201;
- else if (j<211) D_S[d].drv_type=drv_210;
- else if (j<300) D_S[d].drv_type=drv_211;
- else if (j>=300) D_S[d].drv_type=drv_300;
+ if (j<200) current_drive->drv_type=drv_199;
+ else if (j<201) current_drive->drv_type=drv_200;
+ else if (j<210) current_drive->drv_type=drv_201;
+ else if (j<211) current_drive->drv_type=drv_210;
+ else if (j<300) current_drive->drv_type=drv_211;
+ else if (j>=300) current_drive->drv_type=drv_300;
}
else if (fam1_drive)
{
- if (j<100) D_S[d].drv_type=drv_099;
+ if (j<100) current_drive->drv_type=drv_099;
else
{
- D_S[d].drv_type=drv_100;
+ current_drive->drv_type=drv_100;
if ((j!=500)&&(j!=102)) ask_mail();
}
}
else if (fam2_drive)
{
- if (D_S[d].drive_model[5]=='F')
+ if (current_drive->drive_model[5]=='F')
{
if ((j!=1)&&(j!=35)&&(j!=200)&&(j!=210))
ask_mail(); /* unknown version at time */
@@ -3567,20 +3561,21 @@ static int __init check_version(void)
}
else if (famV_drive)
{
- if ((j==100)||(j==150)) D_S[d].drv_type=drv_at;
+ if ((j==100)||(j==150)) current_drive->drv_type=drv_at;
ask_mail(); /* hopefully we get some feedback by this */
}
}
- msg(DBG_LCS,"drive type %02X\n",D_S[d].drv_type);
+ msg(DBG_LCS,"drive type %02X\n",current_drive->drv_type);
msg(DBG_INI,"check_version done.\n");
return (0);
}
/*==========================================================================*/
-static void switch_drive(int i)
+static void switch_drive(struct sbpcd_drive *p)
{
- d=i;
- OUT(CDo_enable,D_S[d].drv_sel);
- msg(DBG_DID,"drive %d (ID=%d) activated.\n", i, D_S[d].drv_id);
+ current_drive = p;
+ OUT(CDo_enable,current_drive->drv_sel);
+ msg(DBG_DID,"drive %d (ID=%d) activated.\n",
+ current_drive - D_S, current_drive->drv_id);
return;
}
/*==========================================================================*/
@@ -3700,23 +3695,24 @@ static int __init check_drives(void)
ndrives=0;
for (j=0;j<max_drives;j++)
{
- D_S[ndrives].drv_id=j;
- if (sbpro_type==1) D_S[ndrives].drv_sel=(j&0x01)<<1|(j&0x02)>>1;
- else D_S[ndrives].drv_sel=j;
- switch_drive(ndrives);
+ struct sbpcd_drive *p = D_S + ndrives;
+ p->drv_id=j;
+ if (sbpro_type==1) p->drv_sel=(j&0x01)<<1|(j&0x02)>>1;
+ else p->drv_sel=j;
+ switch_drive(p);
msg(DBG_INI,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
msg(DBG_000,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
i=check_version();
if (i<0) msg(DBG_INI,"check_version returns %d.\n",i);
else
{
- D_S[d].drv_options=drv_pattern[j];
- if (fam0L_drive) D_S[d].drv_options&=~(speed_auto|speed_300|speed_150);
+ current_drive->drv_options=drv_pattern[j];
+ if (fam0L_drive) current_drive->drv_options&=~(speed_auto|speed_300|speed_150);
msg(DBG_INF, "Drive %d (ID=%d): %.9s (%.4s) at 0x%03X (type %d)\n",
- d,
- D_S[d].drv_id,
- D_S[d].drive_model,
- D_S[d].firmware_version,
+ current_drive - D_S,
+ current_drive->drv_id,
+ current_drive->drive_model,
+ current_drive->firmware_version,
CDo_command,
sbpro_type);
ndrives++;
@@ -3852,7 +3848,7 @@ static int seek_pos_audio_end(void)
{
int i;
- i=msf2blk(D_S[d].pos_audio_end)-1;
+ i=msf2blk(current_drive->pos_audio_end)-1;
if (i<0) return (-1);
i=cc_Seek(i,0);
return (i);
@@ -3862,24 +3858,24 @@ static int seek_pos_audio_end(void)
static int ReadToC(void)
{
int i, j;
- D_S[d].diskstate_flags &= ~toc_bit;
- D_S[d].ored_ctl_adr=0;
+ current_drive->diskstate_flags &= ~toc_bit;
+ current_drive->ored_ctl_adr=0;
/* special handling of CD-I HE */
- if ((D_S[d].n_first_track == 2 && D_S[d].n_last_track == 2) ||
- D_S[d].xa_byte == 0x10)
+ if ((current_drive->n_first_track == 2 && current_drive->n_last_track == 2) ||
+ current_drive->xa_byte == 0x10)
{
- D_S[d].TocBuffer[1].nixbyte=0;
- D_S[d].TocBuffer[1].ctl_adr=0x40;
- D_S[d].TocBuffer[1].number=1;
- D_S[d].TocBuffer[1].format=0;
- D_S[d].TocBuffer[1].address=blk2msf(0);
- D_S[d].ored_ctl_adr |= 0x40;
- D_S[d].n_first_track = 1;
- D_S[d].n_last_track = 1;
- D_S[d].xa_byte = 0x10;
+ current_drive->TocBuffer[1].nixbyte=0;
+ current_drive->TocBuffer[1].ctl_adr=0x40;
+ current_drive->TocBuffer[1].number=1;
+ current_drive->TocBuffer[1].format=0;
+ current_drive->TocBuffer[1].address=blk2msf(0);
+ current_drive->ored_ctl_adr |= 0x40;
+ current_drive->n_first_track = 1;
+ current_drive->n_last_track = 1;
+ current_drive->xa_byte = 0x10;
j = 2;
} else
- for (j=D_S[d].n_first_track;j<=D_S[d].n_last_track;j++)
+ for (j=current_drive->n_first_track;j<=current_drive->n_last_track;j++)
{
i=cc_ReadTocEntry(j);
if (i<0)
@@ -3887,21 +3883,21 @@ static int ReadToC(void)
msg(DBG_INF,"cc_ReadTocEntry(%d) returns %d.\n",j,i);
return (i);
}
- D_S[d].TocBuffer[j].nixbyte=D_S[d].TocEnt_nixbyte;
- D_S[d].TocBuffer[j].ctl_adr=D_S[d].TocEnt_ctl_adr;
- D_S[d].TocBuffer[j].number=D_S[d].TocEnt_number;
- D_S[d].TocBuffer[j].format=D_S[d].TocEnt_format;
- D_S[d].TocBuffer[j].address=D_S[d].TocEnt_address;
- D_S[d].ored_ctl_adr |= D_S[d].TocEnt_ctl_adr;
+ current_drive->TocBuffer[j].nixbyte=current_drive->TocEnt_nixbyte;
+ current_drive->TocBuffer[j].ctl_adr=current_drive->TocEnt_ctl_adr;
+ current_drive->TocBuffer[j].number=current_drive->TocEnt_number;
+ current_drive->TocBuffer[j].format=current_drive->TocEnt_format;
+ current_drive->TocBuffer[j].address=current_drive->TocEnt_address;
+ current_drive->ored_ctl_adr |= current_drive->TocEnt_ctl_adr;
}
/* fake entry for LeadOut Track */
- D_S[d].TocBuffer[j].nixbyte=0;
- D_S[d].TocBuffer[j].ctl_adr=0;
- D_S[d].TocBuffer[j].number=CDROM_LEADOUT;
- D_S[d].TocBuffer[j].format=0;
- D_S[d].TocBuffer[j].address=D_S[d].size_msf;
+ current_drive->TocBuffer[j].nixbyte=0;
+ current_drive->TocBuffer[j].ctl_adr=0;
+ current_drive->TocBuffer[j].number=CDROM_LEADOUT;
+ current_drive->TocBuffer[j].format=0;
+ current_drive->TocBuffer[j].address=current_drive->size_msf;
- D_S[d].diskstate_flags |= toc_bit;
+ current_drive->diskstate_flags |= toc_bit;
return (0);
}
/*==========================================================================*/
@@ -3909,7 +3905,7 @@ static int DiskInfo(void)
{
int i, j;
- D_S[d].mode=READ_M1;
+ current_drive->mode=READ_M1;
#undef LOOP_COUNT
#define LOOP_COUNT 10 /* needed for some "old" drives */
@@ -3959,9 +3955,9 @@ static int DiskInfo(void)
msg(DBG_INF,"DiskInfo: cc_CheckMultiSession returns %d\n", i);
return (i);
}
- if (D_S[d].f_multisession) D_S[d].sbp_bufsiz=1; /* possibly a weird PhotoCD */
- else D_S[d].sbp_bufsiz=buffers;
- i=cc_ReadTocEntry(D_S[d].n_first_track);
+ if (current_drive->f_multisession) current_drive->sbp_bufsiz=1; /* possibly a weird PhotoCD */
+ else current_drive->sbp_bufsiz=buffers;
+ i=cc_ReadTocEntry(current_drive->n_first_track);
if (i<0)
{
msg(DBG_INF,"DiskInfo: cc_ReadTocEntry(1) returns %d\n", i);
@@ -3969,7 +3965,7 @@ static int DiskInfo(void)
}
i=cc_ReadUPC();
if (i<0) msg(DBG_INF,"DiskInfo: cc_ReadUPC returns %d\n", i);
- if ((fam0L_drive) && (D_S[d].xa_byte==0x20 || D_S[d].xa_byte == 0x10))
+ if ((fam0L_drive) && (current_drive->xa_byte==0x20 || current_drive->xa_byte == 0x10))
{
/* XA disk with old drive */
cc_ModeSelect(CD_FRAMESIZE_RAW1);
@@ -3982,6 +3978,7 @@ static int DiskInfo(void)
static int sbpcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
{
+ struct sbpcd_drive *p = cdi->handle;
int st;
if (CDSL_CURRENT != slot_nr) {
@@ -4004,13 +4001,13 @@ static int sbpcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
#if 0
- if (!(D_S[minor(cdi->dev)].status_bits & p_door_closed)) return CDS_TRAY_OPEN;
- if (D_S[minor(cdi->dev)].status_bits & p_disk_ok) return CDS_DISC_OK;
- if (D_S[minor(cdi->dev)].status_bits & p_disk_in) return CDS_DRIVE_NOT_READY;
+ if (!(p->status_bits & p_door_closed)) return CDS_TRAY_OPEN;
+ if (p->status_bits & p_disk_ok) return CDS_DISC_OK;
+ if (p->status_bits & p_disk_in) return CDS_DRIVE_NOT_READY;
return CDS_NO_DISC;
#else
- if (D_S[minor(cdi->dev)].status_bits & p_spinning) return CDS_DISC_OK;
+ if (p->status_bits & p_spinning) return CDS_DISC_OK;
/* return CDS_TRAY_OPEN; */
return CDS_NO_DISC;
@@ -4037,10 +4034,10 @@ static int prepare(u_char func, u_char subfunc)
else if (fam1_drive) GetStatus();
else if (fam2_drive) GetStatus();
else if (famT_drive) GetStatus();
- if (D_S[d].CD_changed==0xFF)
+ if (current_drive->CD_changed==0xFF)
{
- D_S[d].diskstate_flags=0;
- D_S[d].audio_state=0;
+ current_drive->diskstate_flags=0;
+ current_drive->audio_state=0;
if (!st_diskok)
{
i=check_allowed1(func,subfunc);
@@ -4051,7 +4048,7 @@ static int prepare(u_char func, u_char subfunc)
i=check_allowed3(func,subfunc);
if (i<0)
{
- D_S[d].CD_changed=1;
+ current_drive->CD_changed=1;
return (-15);
}
}
@@ -4060,8 +4057,8 @@ static int prepare(u_char func, u_char subfunc)
{
if (!st_diskok)
{
- D_S[d].diskstate_flags=0;
- D_S[d].audio_state=0;
+ current_drive->diskstate_flags=0;
+ current_drive->audio_state=0;
i=check_allowed1(func,subfunc);
if (i<0) return (-2);
}
@@ -4069,7 +4066,7 @@ static int prepare(u_char func, u_char subfunc)
{
if (st_busy)
{
- if (D_S[d].audio_state!=audio_pausing)
+ if (current_drive->audio_state!=audio_pausing)
{
i=check_allowed2(func,subfunc);
if (i<0) return (-2);
@@ -4077,16 +4074,16 @@ static int prepare(u_char func, u_char subfunc)
}
else
{
- if (D_S[d].audio_state==audio_playing) seek_pos_audio_end();
- D_S[d].audio_state=0;
+ if (current_drive->audio_state==audio_playing) seek_pos_audio_end();
+ current_drive->audio_state=0;
}
if (!frame_size_valid)
{
i=DiskInfo();
if (i<0)
{
- D_S[d].diskstate_flags=0;
- D_S[d].audio_state=0;
+ current_drive->diskstate_flags=0;
+ current_drive->audio_state=0;
i=check_allowed1(func,subfunc);
if (i<0) return (-2);
}
@@ -4145,9 +4142,10 @@ static int sbp_status(void)
static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_multisession *ms_infp)
{
+ struct sbpcd_drive *p = cdi->handle;
ms_infp->addr_format = CDROM_LBA;
- ms_infp->addr.lba = D_S[minor(cdi->dev)].lba_multi;
- if (D_S[minor(cdi->dev)].f_multisession)
+ ms_infp->addr.lba = p->lba_multi;
+ if (p->f_multisession)
ms_infp->xa_flag=1; /* valid redirection address */
else
ms_infp->xa_flag=0; /* invalid redirection address */
@@ -4163,20 +4161,19 @@ static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_mu
static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
u_long arg)
{
+ struct sbpcd_drive *p = cdi->handle;
int i;
- msg(DBG_IO2,"ioctl(%d, 0x%08lX, 0x%08lX)\n",
- minor(cdi->dev), cmd, arg);
- i=minor(cdi->dev);
- if ((i<0) || (i>=NR_SBPCD) || (D_S[i].drv_id==-1))
- {
- msg(DBG_INF, "ioctl: bad device: %04X\n", cdi->dev);
+ msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg);
+ if (p->drv_id==-1) {
+ msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
return (-ENXIO); /* no such drive */
}
down(&ioctl_read_sem);
- if (d!=i) switch_drive(i);
+ if (p != current_drive)
+ switch_drive(p);
- msg(DBG_IO2,"ioctl: device %d, request %04X\n",i,cmd);
+ msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
switch (cmd) /* Sun-compatible */
{
case DDIOCSDBG: /* DDI Debug */
@@ -4186,52 +4183,52 @@ static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
case CDROMRESET: /* hard reset the drive */
msg(DBG_IOC,"ioctl: CDROMRESET entered.\n");
i=DriveReset();
- D_S[d].audio_state=0;
+ current_drive->audio_state=0;
RETURN_UP(i);
case CDROMREADMODE1:
msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");
#if SAFE_MIXED
- if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
+ if (current_drive->has_data>1) RETURN_UP(-EBUSY);
#endif /* SAFE_MIXED */
cc_ModeSelect(CD_FRAMESIZE);
cc_ModeSense();
- D_S[d].mode=READ_M1;
+ current_drive->mode=READ_M1;
RETURN_UP(0);
case CDROMREADMODE2: /* not usable at the moment */
msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");
#if SAFE_MIXED
- if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
+ if (current_drive->has_data>1) RETURN_UP(-EBUSY);
#endif /* SAFE_MIXED */
cc_ModeSelect(CD_FRAMESIZE_RAW1);
cc_ModeSense();
- D_S[d].mode=READ_M2;
+ current_drive->mode=READ_M2;
RETURN_UP(0);
case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
- if (D_S[d].sbp_audsiz>0) vfree(D_S[d].aud_buf);
- D_S[d].aud_buf=NULL;
- D_S[d].sbp_audsiz=arg;
+ if (current_drive->sbp_audsiz>0) vfree(current_drive->aud_buf);
+ current_drive->aud_buf=NULL;
+ current_drive->sbp_audsiz=arg;
- if (D_S[d].sbp_audsiz>16)
+ if (current_drive->sbp_audsiz>16)
{
- D_S[d].sbp_audsiz = 0;
- RETURN_UP(D_S[d].sbp_audsiz);
+ current_drive->sbp_audsiz = 0;
+ RETURN_UP(current_drive->sbp_audsiz);
}
- if (D_S[d].sbp_audsiz>0)
+ if (current_drive->sbp_audsiz>0)
{
- D_S[d].aud_buf=(u_char *) vmalloc(D_S[d].sbp_audsiz*CD_FRAMESIZE_RAW);
- if (D_S[d].aud_buf==NULL)
+ current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW);
+ if (current_drive->aud_buf==NULL)
{
- msg(DBG_INF,"audio buffer (%d frames) not available.\n",D_S[d].sbp_audsiz);
- D_S[d].sbp_audsiz=0;
+ msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz);
+ current_drive->sbp_audsiz=0;
}
- else msg(DBG_INF,"audio buffer size: %d frames.\n",D_S[d].sbp_audsiz);
+ else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz);
}
- RETURN_UP(D_S[d].sbp_audsiz);
+ RETURN_UP(current_drive->sbp_audsiz);
case CDROMREADAUDIO:
{ /* start of CDROMREADAUDIO */
@@ -4251,13 +4248,13 @@ static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
if (famV_drive) RETURN_UP(-EINVAL);
if (famT_drive) RETURN_UP(-EINVAL);
#if SAFE_MIXED
- if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
+ if (current_drive->has_data>1) RETURN_UP(-EBUSY);
#endif /* SAFE_MIXED */
- if (D_S[d].aud_buf==NULL) RETURN_UP(-EINVAL);
+ if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL);
if (copy_from_user(&read_audio, (void *)arg,
sizeof(struct cdrom_read_audio)))
RETURN_UP(-EFAULT);
- if (read_audio.nframes < 0 || read_audio.nframes>D_S[d].sbp_audsiz) RETURN_UP(-EINVAL);
+ if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL);
i=verify_area(VERIFY_WRITE, read_audio.buf,
read_audio.nframes*CD_FRAMESIZE_RAW);
if (i) RETURN_UP(i);
@@ -4282,7 +4279,7 @@ static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
for (data_tries=5; data_tries>0; data_tries--)
{
msg(DBG_AUD,"data_tries=%d ...\n", data_tries);
- D_S[d].mode=READ_AU;
+ current_drive->mode=READ_AU;
cc_ModeSelect(CD_FRAMESIZE_RAW);
cc_ModeSense();
for (status_tries=3; status_tries > 0; status_tries--)
@@ -4372,13 +4369,13 @@ static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
}
msg(DBG_AUD,"read_audio: before reading data.\n");
error_flag=0;
- p = D_S[d].aud_buf;
+ p = current_drive->aud_buf;
if (sbpro_type==1) OUT(CDo_sel_i_d,1);
if (do_16bit)
{
u_short *p2 = (u_short *) p;
- for (; (u_char *) p2 < D_S[d].aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
+ for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
{
if ((inb_p(CDi_status)&s_not_data_ready)) continue;
@@ -4387,7 +4384,7 @@ static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
*p2++ = inw_p(CDi_data);
}
} else {
- for (; p < D_S[d].aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
+ for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
{
if ((inb_p(CDi_status)&s_not_data_ready)) continue;
@@ -4442,7 +4439,7 @@ static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */
if (i<0) { msg(DBG_AUD,
"read_audio: cc_ReadStatus error after read: %02X\n",
- D_S[d].status_bits);
+ current_drive->status_bits);
continue; /* FIXME */
}
}
@@ -4454,7 +4451,7 @@ static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
continue;
}
if (copy_to_user((u_char *)read_audio.buf,
- (u_char *) D_S[d].aud_buf,
+ (u_char *) current_drive->aud_buf,
read_audio.nframes * CD_FRAMESIZE_RAW))
RETURN_UP(-EFAULT);
msg(DBG_AUD,"read_audio: copy_to_user done.\n");
@@ -4462,7 +4459,7 @@ static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
}
cc_ModeSelect(CD_FRAMESIZE);
cc_ModeSense();
- D_S[d].mode=READ_M1;
+ current_drive->mode=READ_M1;
#if OLD_BUSY
busy_audio=0;
#endif /* OLD_BUSY */
@@ -4484,20 +4481,19 @@ static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
void * arg)
{
+ struct sbpcd_drive *p = cdi->handle;
int i, st, j;
- msg(DBG_IO2,"ioctl(%d, 0x%08lX, 0x%08p)\n",
- minor(cdi->dev), cmd, arg);
- i=minor(cdi->dev);
- if ((i<0) || (i>=NR_SBPCD) || (D_S[i].drv_id==-1))
- {
- msg(DBG_INF, "ioctl: bad device: %04X\n", cdi->dev);
+ msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08p)\n", cdi->name, cmd, arg);
+ if (p->drv_id==-1) {
+ msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
return (-ENXIO); /* no such drive */
}
down(&ioctl_read_sem);
- if (d!=i) switch_drive(i);
+ if (p != current_drive)
+ switch_drive(p);
- msg(DBG_IO2,"ioctl: device %d, request %04X\n",i,cmd);
+ msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
switch (cmd) /* Sun-compatible */
{
@@ -4507,7 +4503,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
/* or reset the starting and ending locations when in PAUSED mode. */
/* If applicable, at the next stopping point it reaches */
/* the drive will discontinue playing. */
- switch (D_S[d].audio_state)
+ switch (current_drive->audio_state)
{
case audio_playing:
if (famL_drive) i=cc_ReadSubQ();
@@ -4516,11 +4512,11 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
if (famL_drive) i=cc_Pause_Resume(1);
else i=cc_ReadSubQ();
if (i<0) RETURN_UP(-EIO);
- D_S[d].pos_audio_start=D_S[d].SubQ_run_tot;
- D_S[d].audio_state=audio_pausing;
+ current_drive->pos_audio_start=current_drive->SubQ_run_tot;
+ current_drive->audio_state=audio_pausing;
RETURN_UP(0);
case audio_pausing:
- i=cc_Seek(D_S[d].pos_audio_start,1);
+ i=cc_Seek(current_drive->pos_audio_start,1);
if (i<0) RETURN_UP(-EIO);
RETURN_UP(0);
default:
@@ -4532,56 +4528,56 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
/* resume playing audio tracks when a previous PLAY AUDIO call has */
/* been paused with a PAUSE command. */
/* It will resume playing from the location saved in SubQ_run_tot. */
- if (D_S[d].audio_state!=audio_pausing) RETURN_UP(-EINVAL);
+ if (current_drive->audio_state!=audio_pausing) RETURN_UP(-EINVAL);
if (famL_drive)
- i=cc_PlayAudio(D_S[d].pos_audio_start,
- D_S[d].pos_audio_end);
+ i=cc_PlayAudio(current_drive->pos_audio_start,
+ current_drive->pos_audio_end);
else i=cc_Pause_Resume(3);
if (i<0) RETURN_UP(-EIO);
- D_S[d].audio_state=audio_playing;
+ current_drive->audio_state=audio_playing;
RETURN_UP(0);
case CDROMPLAYMSF:
msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n");
#if SAFE_MIXED
- if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
+ if (current_drive->has_data>1) RETURN_UP(-EBUSY);
#endif /* SAFE_MIXED */
- if (D_S[d].audio_state==audio_playing)
+ if (current_drive->audio_state==audio_playing)
{
i=cc_Pause_Resume(1);
if (i<0) RETURN_UP(-EIO);
i=cc_ReadSubQ();
if (i<0) RETURN_UP(-EIO);
- D_S[d].pos_audio_start=D_S[d].SubQ_run_tot;
- i=cc_Seek(D_S[d].pos_audio_start,1);
+ current_drive->pos_audio_start=current_drive->SubQ_run_tot;
+ i=cc_Seek(current_drive->pos_audio_start,1);
}
memcpy(&msf, (void *) arg, sizeof(struct cdrom_msf));
/* values come as msf-bin */
- D_S[d].pos_audio_start = (msf.cdmsf_min0<<16) |
+ current_drive->pos_audio_start = (msf.cdmsf_min0<<16) |
(msf.cdmsf_sec0<<8) |
msf.cdmsf_frame0;
- D_S[d].pos_audio_end = (msf.cdmsf_min1<<16) |
+ current_drive->pos_audio_end = (msf.cdmsf_min1<<16) |
(msf.cdmsf_sec1<<8) |
msf.cdmsf_frame1;
msg(DBG_IOX,"ioctl: CDROMPLAYMSF %08X %08X\n",
- D_S[d].pos_audio_start,D_S[d].pos_audio_end);
- i=cc_PlayAudio(D_S[d].pos_audio_start,D_S[d].pos_audio_end);
+ current_drive->pos_audio_start,current_drive->pos_audio_end);
+ i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end);
if (i<0)
{
msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
DriveReset();
- D_S[d].audio_state=0;
+ current_drive->audio_state=0;
RETURN_UP(-EIO);
}
- D_S[d].audio_state=audio_playing;
+ current_drive->audio_state=audio_playing;
RETURN_UP(0);
case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n");
#if SAFE_MIXED
- if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
+ if (current_drive->has_data>1) RETURN_UP(-EBUSY);
#endif /* SAFE_MIXED */
- if (D_S[d].audio_state==audio_playing)
+ if (current_drive->audio_state==audio_playing)
{
msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n");
#if 1
@@ -4593,27 +4589,27 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
memcpy(&ti,(void *) arg,sizeof(struct cdrom_ti));
msg(DBG_IOX,"ioctl: trk0: %d, ind0: %d, trk1:%d, ind1:%d\n",
ti.cdti_trk0,ti.cdti_ind0,ti.cdti_trk1,ti.cdti_ind1);
- if (ti.cdti_trk0<D_S[d].n_first_track) RETURN_UP(-EINVAL);
- if (ti.cdti_trk0>D_S[d].n_last_track) RETURN_UP(-EINVAL);
+ if (ti.cdti_trk0<current_drive->n_first_track) RETURN_UP(-EINVAL);
+ if (ti.cdti_trk0>current_drive->n_last_track) RETURN_UP(-EINVAL);
if (ti.cdti_trk1<ti.cdti_trk0) ti.cdti_trk1=ti.cdti_trk0;
- if (ti.cdti_trk1>D_S[d].n_last_track) ti.cdti_trk1=D_S[d].n_last_track;
- D_S[d].pos_audio_start=D_S[d].TocBuffer[ti.cdti_trk0].address;
- D_S[d].pos_audio_end=D_S[d].TocBuffer[ti.cdti_trk1+1].address;
- i=cc_PlayAudio(D_S[d].pos_audio_start,D_S[d].pos_audio_end);
+ if (ti.cdti_trk1>current_drive->n_last_track) ti.cdti_trk1=current_drive->n_last_track;
+ current_drive->pos_audio_start=current_drive->TocBuffer[ti.cdti_trk0].address;
+ current_drive->pos_audio_end=current_drive->TocBuffer[ti.cdti_trk1+1].address;
+ i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end);
if (i<0)
{
msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
DriveReset();
- D_S[d].audio_state=0;
+ current_drive->audio_state=0;
RETURN_UP(-EIO);
}
- D_S[d].audio_state=audio_playing;
+ current_drive->audio_state=audio_playing;
RETURN_UP(0);
case CDROMREADTOCHDR: /* Read the table of contents header */
msg(DBG_IOC,"ioctl: CDROMREADTOCHDR entered.\n");
- tochdr.cdth_trk0=D_S[d].n_first_track;
- tochdr.cdth_trk1=D_S[d].n_last_track;
+ tochdr.cdth_trk0=current_drive->n_first_track;
+ tochdr.cdth_trk1=current_drive->n_last_track;
memcpy((void *) arg, &tochdr, sizeof(struct cdrom_tochdr));
RETURN_UP(0);
@@ -4621,20 +4617,20 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
msg(DBG_IOC,"ioctl: CDROMREADTOCENTRY entered.\n");
memcpy(&tocentry, (void *) arg, sizeof(struct cdrom_tocentry));
i=tocentry.cdte_track;
- if (i==CDROM_LEADOUT) i=D_S[d].n_last_track+1;
- else if (i<D_S[d].n_first_track||i>D_S[d].n_last_track)
+ if (i==CDROM_LEADOUT) i=current_drive->n_last_track+1;
+ else if (i<current_drive->n_first_track||i>current_drive->n_last_track)
RETURN_UP(-EINVAL);
- tocentry.cdte_adr=D_S[d].TocBuffer[i].ctl_adr&0x0F;
- tocentry.cdte_ctrl=(D_S[d].TocBuffer[i].ctl_adr>>4)&0x0F;
- tocentry.cdte_datamode=D_S[d].TocBuffer[i].format;
+ tocentry.cdte_adr=current_drive->TocBuffer[i].ctl_adr&0x0F;
+ tocentry.cdte_ctrl=(current_drive->TocBuffer[i].ctl_adr>>4)&0x0F;
+ tocentry.cdte_datamode=current_drive->TocBuffer[i].format;
if (tocentry.cdte_format==CDROM_MSF) /* MSF-bin required */
{
- tocentry.cdte_addr.msf.minute=(D_S[d].TocBuffer[i].address>>16)&0x00FF;
- tocentry.cdte_addr.msf.second=(D_S[d].TocBuffer[i].address>>8)&0x00FF;
- tocentry.cdte_addr.msf.frame=D_S[d].TocBuffer[i].address&0x00FF;
+ tocentry.cdte_addr.msf.minute=(current_drive->TocBuffer[i].address>>16)&0x00FF;
+ tocentry.cdte_addr.msf.second=(current_drive->TocBuffer[i].address>>8)&0x00FF;
+ tocentry.cdte_addr.msf.frame=current_drive->TocBuffer[i].address&0x00FF;
}
else if (tocentry.cdte_format==CDROM_LBA) /* blk required */
- tocentry.cdte_addr.lba=msf2blk(D_S[d].TocBuffer[i].address);
+ tocentry.cdte_addr.lba=msf2blk(current_drive->TocBuffer[i].address);
else RETURN_UP(-EINVAL);
memcpy((void *) arg, &tocentry, sizeof(struct cdrom_tocentry));
RETURN_UP(0);
@@ -4642,10 +4638,10 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
case CDROMSTOP: /* Spin down the drive */
msg(DBG_IOC,"ioctl: CDROMSTOP entered.\n");
#if SAFE_MIXED
- if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
+ if (current_drive->has_data>1) RETURN_UP(-EBUSY);
#endif /* SAFE_MIXED */
i=cc_Pause_Resume(1);
- D_S[d].audio_state=0;
+ current_drive->audio_state=0;
#if 0
cc_DriveReset();
#endif
@@ -4654,16 +4650,16 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
case CDROMSTART: /* Spin up the drive */
msg(DBG_IOC,"ioctl: CDROMSTART entered.\n");
cc_SpinUp();
- D_S[d].audio_state=0;
+ current_drive->audio_state=0;
RETURN_UP(0);
case CDROMVOLCTRL: /* Volume control */
msg(DBG_IOC,"ioctl: CDROMVOLCTRL entered.\n");
memcpy(&volctrl,(char *) arg,sizeof(volctrl));
- D_S[d].vol_chan0=0;
- D_S[d].vol_ctrl0=volctrl.channel0;
- D_S[d].vol_chan1=1;
- D_S[d].vol_ctrl1=volctrl.channel1;
+ current_drive->vol_chan0=0;
+ current_drive->vol_ctrl0=volctrl.channel0;
+ current_drive->vol_chan1=1;
+ current_drive->vol_ctrl1=volctrl.channel1;
i=cc_SetVolume();
RETURN_UP(0);
@@ -4671,8 +4667,8 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n");
st=cc_GetVolume();
if (st<0) RETURN_UP(st);
- volctrl.channel0=D_S[d].vol_ctrl0;
- volctrl.channel1=D_S[d].vol_ctrl1;
+ volctrl.channel0=current_drive->vol_ctrl0;
+ volctrl.channel1=current_drive->vol_ctrl1;
volctrl.channel2=0;
volctrl.channel2=0;
memcpy((void *)arg,&volctrl,sizeof(volctrl));
@@ -4689,22 +4685,22 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
i=cc_ReadSubQ();
if (i<0) {
j=cc_ReadError(); /* clear out error status from drive */
- D_S[d].audio_state=CDROM_AUDIO_NO_STATUS;
+ current_drive->audio_state=CDROM_AUDIO_NO_STATUS;
/* get and set the disk state here,
probably not the right place, but who cares!
It makes it work properly! --AJK */
- if (D_S[d].CD_changed==0xFF) {
+ if (current_drive->CD_changed==0xFF) {
msg(DBG_000,"Disk changed detect\n");
- D_S[d].diskstate_flags &= ~cd_size_bit;
+ current_drive->diskstate_flags &= ~cd_size_bit;
}
RETURN_UP(-EIO);
}
- if (D_S[d].CD_changed==0xFF) {
+ if (current_drive->CD_changed==0xFF) {
/* reread the TOC because the disk has changed! --AJK */
msg(DBG_000,"Disk changed STILL detected, rereading TOC!\n");
i=DiskInfo();
if(i==0) {
- D_S[d].CD_changed=0x00; /* cd has changed, procede, */
+ current_drive->CD_changed=0x00; /* cd has changed, procede, */
RETURN_UP(-EIO); /* and get TOC, etc on next try! --AJK */
} else {
RETURN_UP(-EIO); /* we weren't ready yet! --AJK */
@@ -4725,12 +4721,12 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning);
msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
/* st_busy indicates if it's _ACTUALLY_ playing audio */
- switch (D_S[d].audio_state)
+ switch (current_drive->audio_state)
{
case audio_playing:
if(st_busy==0) {
/* CD has stopped playing audio --AJK */
- D_S[d].audio_state=audio_completed;
+ current_drive->audio_state=audio_completed;
SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED;
} else {
SC.cdsc_audiostatus=CDROM_AUDIO_PLAY;
@@ -4746,23 +4742,23 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS;
break;
}
- SC.cdsc_adr=D_S[d].SubQ_ctl_adr;
- SC.cdsc_ctrl=D_S[d].SubQ_ctl_adr>>4;
- SC.cdsc_trk=bcd2bin(D_S[d].SubQ_trk);
- SC.cdsc_ind=bcd2bin(D_S[d].SubQ_pnt_idx);
+ SC.cdsc_adr=current_drive->SubQ_ctl_adr;
+ SC.cdsc_ctrl=current_drive->SubQ_ctl_adr>>4;
+ SC.cdsc_trk=bcd2bin(current_drive->SubQ_trk);
+ SC.cdsc_ind=bcd2bin(current_drive->SubQ_pnt_idx);
if (SC.cdsc_format==CDROM_LBA)
{
- SC.cdsc_absaddr.lba=msf2blk(D_S[d].SubQ_run_tot);
- SC.cdsc_reladdr.lba=msf2blk(D_S[d].SubQ_run_trk);
+ SC.cdsc_absaddr.lba=msf2blk(current_drive->SubQ_run_tot);
+ SC.cdsc_reladdr.lba=msf2blk(current_drive->SubQ_run_trk);
}
else /* not only if (SC.cdsc_format==CDROM_MSF) */
{
- SC.cdsc_absaddr.msf.minute=(D_S[d].SubQ_run_tot>>16)&0x00FF;
- SC.cdsc_absaddr.msf.second=(D_S[d].SubQ_run_tot>>8)&0x00FF;
- SC.cdsc_absaddr.msf.frame=D_S[d].SubQ_run_tot&0x00FF;
- SC.cdsc_reladdr.msf.minute=(D_S[d].SubQ_run_trk>>16)&0x00FF;
- SC.cdsc_reladdr.msf.second=(D_S[d].SubQ_run_trk>>8)&0x00FF;
- SC.cdsc_reladdr.msf.frame=D_S[d].SubQ_run_trk&0x00FF;
+ SC.cdsc_absaddr.msf.minute=(current_drive->SubQ_run_tot>>16)&0x00FF;
+ SC.cdsc_absaddr.msf.second=(current_drive->SubQ_run_tot>>8)&0x00FF;
+ SC.cdsc_absaddr.msf.frame=current_drive->SubQ_run_tot&0x00FF;
+ SC.cdsc_reladdr.msf.minute=(current_drive->SubQ_run_trk>>16)&0x00FF;
+ SC.cdsc_reladdr.msf.second=(current_drive->SubQ_run_trk>>8)&0x00FF;
+ SC.cdsc_reladdr.msf.frame=current_drive->SubQ_run_trk&0x00FF;
}
memcpy((void *) arg, &SC, sizeof(struct cdrom_subchnl));
msg(DBG_IOS,"CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
@@ -4786,11 +4782,11 @@ static void sbp_transfer(struct request *req)
long offs;
while ( (req->nr_sectors > 0) &&
- (req->sector/4 >= D_S[d].sbp_first_frame) &&
- (req->sector/4 <= D_S[d].sbp_last_frame) )
+ (req->sector/4 >= current_drive->sbp_first_frame) &&
+ (req->sector/4 <= current_drive->sbp_last_frame) )
{
- offs = (req->sector - D_S[d].sbp_first_frame * 4) * 512;
- memcpy(req->buffer, D_S[d].sbp_buf + offs, 512);
+ offs = (req->sector - current_drive->sbp_first_frame * 4) * 512;
+ memcpy(req->buffer, current_drive->sbp_buf + offs, 512);
req->nr_sectors--;
req->sector++;
req->buffer += 512;
@@ -4833,8 +4829,9 @@ static void do_sbpcd_request(request_queue_t * q)
{
u_int block;
u_int nsect;
- int i, status_tries, data_tries;
+ int status_tries, data_tries;
struct request *req;
+ struct sbpcd_drive *p;
#ifdef DEBUG_GTL
static int xx_nr=0;
int xnr;
@@ -4873,9 +4870,8 @@ static void do_sbpcd_request(request_queue_t * q)
msg(DBG_INF, "bad cmd %d\n", req->cmd);
goto err_done;
}
- i = minor(req->rq_dev);
- if ( (i<0) || (i>=NR_SBPCD) || (D_S[i].drv_id==-1))
- {
+ p = D_S + minor(req->rq_dev);
+ if (p->drv_id==-1) {
msg(DBG_INF, "do_request: bad device: %s\n",
kdevname(req->rq_dev));
goto err_done;
@@ -4885,9 +4881,10 @@ static void do_sbpcd_request(request_queue_t * q)
busy_data=1;
#endif /* OLD_BUSY */
- if (D_S[i].audio_state==audio_playing) goto err_done;
- if (d!=i) switch_drive(i);
-
+ if (p->audio_state==audio_playing) goto err_done;
+ if (p != current_drive)
+ switch_drive(p);
+
block = req->sector; /* always numbered as 512-byte-pieces */
nsect = req->nr_sectors; /* always counted as 512-byte-pieces */
@@ -4939,7 +4936,7 @@ static void do_sbpcd_request(request_queue_t * q)
if (sbp_data(req) != 0)
{
#if SAFE_MIXED
- D_S[d].has_data=2; /* is really a data disk */
+ current_drive->has_data=2; /* is really a data disk */
#endif /* SAFE_MIXED */
#ifdef DEBUG_GTL
printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n",
@@ -4977,20 +4974,20 @@ static void sbp_read_cmd(struct request *req)
int i;
int block;
- D_S[d].sbp_first_frame=D_S[d].sbp_last_frame=-1; /* purge buffer */
- D_S[d].sbp_current = 0;
+ current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */
+ current_drive->sbp_current = 0;
block=req->sector/4;
- if (block+D_S[d].sbp_bufsiz <= D_S[d].CDsize_frm)
- D_S[d].sbp_read_frames = D_S[d].sbp_bufsiz;
+ if (block+current_drive->sbp_bufsiz <= current_drive->CDsize_frm)
+ current_drive->sbp_read_frames = current_drive->sbp_bufsiz;
else
{
- D_S[d].sbp_read_frames=D_S[d].CDsize_frm-block;
+ current_drive->sbp_read_frames=current_drive->CDsize_frm-block;
/* avoid reading past end of data */
- if (D_S[d].sbp_read_frames < 1)
+ if (current_drive->sbp_read_frames < 1)
{
msg(DBG_INF,"requested frame %d, CD size %d ???\n",
- block, D_S[d].CDsize_frm);
- D_S[d].sbp_read_frames=1;
+ block, current_drive->CDsize_frm);
+ current_drive->sbp_read_frames=1;
}
}
@@ -5003,27 +5000,27 @@ static void sbp_read_cmd(struct request *req)
bin2bcdx(&drvcmd[1]);
bin2bcdx(&drvcmd[2]);
bin2bcdx(&drvcmd[3]);
- drvcmd[4]=D_S[d].sbp_read_frames>>8;
- drvcmd[5]=D_S[d].sbp_read_frames&0xff;
+ drvcmd[4]=current_drive->sbp_read_frames>>8;
+ drvcmd[5]=current_drive->sbp_read_frames&0xff;
drvcmd[6]=0x02; /* flag "msf-bcd" */
}
else if (fam0L_drive)
{
flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
- if (D_S[d].xa_byte==0x20)
+ if (current_drive->xa_byte==0x20)
{
cmd_type=READ_M2;
drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
drvcmd[1]=(block>>16)&0x0ff;
drvcmd[2]=(block>>8)&0x0ff;
drvcmd[3]=block&0x0ff;
- drvcmd[4]=(D_S[d].sbp_read_frames>>8)&0x0ff;
- drvcmd[5]=D_S[d].sbp_read_frames&0x0ff;
+ drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
+ drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
}
else
{
drvcmd[0]=CMD0_READ; /* "read frames", old drives */
- if (D_S[d].drv_type>=drv_201)
+ if (current_drive->drv_type>=drv_201)
{
lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
bin2bcdx(&drvcmd[1]);
@@ -5036,24 +5033,24 @@ static void sbp_read_cmd(struct request *req)
drvcmd[2]=(block>>8)&0x0ff;
drvcmd[3]=block&0x0ff;
}
- drvcmd[4]=(D_S[d].sbp_read_frames>>8)&0x0ff;
- drvcmd[5]=D_S[d].sbp_read_frames&0x0ff;
- drvcmd[6]=(D_S[d].drv_type<drv_201)?0:2; /* flag "lba or msf-bcd format" */
+ drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
+ drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
+ drvcmd[6]=(current_drive->drv_type<drv_201)?0:2; /* flag "lba or msf-bcd format" */
}
}
else if (fam1_drive)
{
drvcmd[0]=CMD1_READ;
lba2msf(block,&drvcmd[1]); /* msf-bin format required */
- drvcmd[5]=(D_S[d].sbp_read_frames>>8)&0x0ff;
- drvcmd[6]=D_S[d].sbp_read_frames&0x0ff;
+ drvcmd[5]=(current_drive->sbp_read_frames>>8)&0x0ff;
+ drvcmd[6]=current_drive->sbp_read_frames&0x0ff;
}
else if (fam2_drive)
{
drvcmd[0]=CMD2_READ;
lba2msf(block,&drvcmd[1]); /* msf-bin format required */
- drvcmd[4]=(D_S[d].sbp_read_frames>>8)&0x0ff;
- drvcmd[5]=D_S[d].sbp_read_frames&0x0ff;
+ drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
+ drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
drvcmd[6]=0x02;
}
else if (famT_drive)
@@ -5063,8 +5060,8 @@ static void sbp_read_cmd(struct request *req)
drvcmd[3]=(block>>16)&0x0ff;
drvcmd[4]=(block>>8)&0x0ff;
drvcmd[5]=block&0x0ff;
- drvcmd[7]=(D_S[d].sbp_read_frames>>8)&0x0ff;
- drvcmd[8]=D_S[d].sbp_read_frames&0x0ff;
+ drvcmd[7]=(current_drive->sbp_read_frames>>8)&0x0ff;
+ drvcmd[8]=current_drive->sbp_read_frames&0x0ff;
}
flags_cmd_out=f_putcmd;
response_count=0;
@@ -5075,7 +5072,7 @@ static void sbp_read_cmd(struct request *req)
/*==========================================================================*/
/*
* Check the completion of the read-data command. On success, read
- * the D_S[d].sbp_bufsiz * 2048 bytes of data from the disk into buffer.
+ * the current_drive->sbp_bufsiz * 2048 bytes of data from the disk into buffer.
*/
static int sbp_data(struct request *req)
{
@@ -5098,11 +5095,11 @@ static int sbp_data(struct request *req)
#if LONG_TIMING
max_latency=9*HZ;
#else
- if (D_S[d].f_multisession) max_latency=15*HZ;
+ if (current_drive->f_multisession) max_latency=15*HZ;
else max_latency=5*HZ;
#endif
duration=jiffies;
- for (frame=0;frame<D_S[d].sbp_read_frames&&!error_flag; frame++)
+ for (frame=0;frame<current_drive->sbp_read_frames&&!error_flag; frame++)
{
SBPCD_CLI;
@@ -5112,7 +5109,7 @@ static int sbp_data(struct request *req)
add_timer(&data_timer);
while (!timed_out_data)
{
- if (D_S[d].f_multisession) try=maxtim_data*4;
+ if (current_drive->f_multisession) try=maxtim_data*4;
else try=maxtim_data;
msg(DBG_000,"sbp_data: CDi_status loop: try=%d.\n",try);
for ( ; try!=0;try--)
@@ -5155,7 +5152,7 @@ static int sbp_data(struct request *req)
}
if (j&s_not_data_ready)
{
- if ((D_S[d].ored_ctl_adr&0x40)==0)
+ if ((current_drive->ored_ctl_adr&0x40)==0)
msg(DBG_INF, "CD contains no data tracks.\n");
else msg(DBG_INF, "sbp_data: DATA_READY timeout (%02X).\n", j);
error_flag++;
@@ -5164,7 +5161,7 @@ static int sbp_data(struct request *req)
if (error_flag) break;
msg(DBG_000, "sbp_data: beginning to read.\n");
- p = D_S[d].sbp_buf + frame * CD_FRAMESIZE;
+ p = current_drive->sbp_buf + frame * CD_FRAMESIZE;
if (sbpro_type==1) OUT(CDo_sel_i_d,1);
if (cmd_type==READ_M2) {
if (do_16bit) insw(CDi_data, xa_head_buf, CD_XA_HEAD>>1);
@@ -5176,7 +5173,7 @@ static int sbp_data(struct request *req)
if (do_16bit) insw(CDi_data, xa_tail_buf, CD_XA_TAIL>>1);
else insb(CDi_data, xa_tail_buf, CD_XA_TAIL);
}
- D_S[d].sbp_current++;
+ current_drive->sbp_current++;
if (sbpro_type==1) OUT(CDo_sel_i_d,0);
if (cmd_type==READ_M2)
{
@@ -5255,9 +5252,9 @@ static int sbp_data(struct request *req)
sbp_sleep(1);
}
while (j<0);
- D_S[d].error_state=infobuf[2];
- D_S[d].b3=infobuf[3];
- D_S[d].b4=infobuf[4];
+ current_drive->error_state=infobuf[2];
+ current_drive->b3=infobuf[3];
+ current_drive->b4=infobuf[4];
}
break;
}
@@ -5327,7 +5324,7 @@ static int sbp_data(struct request *req)
#endif
if (i<0)
{
- msg(DBG_INF,"bad cc_ReadStatus after read: %02X\n", D_S[d].status_bits);
+ msg(DBG_INF,"bad cc_ReadStatus after read: %02X\n", current_drive->status_bits);
return (0);
}
}
@@ -5341,14 +5338,14 @@ static int sbp_data(struct request *req)
if (fatal_err)
{
fatal_err=0;
- D_S[d].sbp_first_frame=D_S[d].sbp_last_frame=-1; /* purge buffer */
- D_S[d].sbp_current = 0;
+ current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */
+ current_drive->sbp_current = 0;
msg(DBG_INF,"sbp_data: fatal_err - retrying.\n");
return (0);
}
- D_S[d].sbp_first_frame = req -> sector / 4;
- D_S[d].sbp_last_frame = D_S[d].sbp_first_frame + D_S[d].sbp_read_frames - 1;
+ current_drive->sbp_first_frame = req -> sector / 4;
+ current_drive->sbp_last_frame = current_drive->sbp_first_frame + current_drive->sbp_read_frames - 1;
sbp_transfer(req);
return (1);
}
@@ -5368,34 +5365,33 @@ static struct block_device_operations sbpcd_bdops =
*/
static int sbpcd_open(struct cdrom_device_info *cdi, int purpose)
{
- int i;
-
- i = minor(cdi->dev);
+ struct sbpcd_drive *p = cdi->handle;
down(&ioctl_read_sem);
- switch_drive(i);
+ switch_drive(p);
/*
* try to keep an "open" counter here and lock the door if 0->1.
*/
msg(DBG_LCK,"open_count: %d -> %d\n",
- D_S[d].open_count,D_S[d].open_count+1);
- if (++D_S[d].open_count<=1)
+ current_drive->open_count,current_drive->open_count+1);
+ if (++current_drive->open_count<=1)
{
+ int i;
i=LockDoor();
- D_S[d].open_count=1;
+ current_drive->open_count=1;
if (famT_drive) msg(DBG_TEA,"sbpcd_open: before i=DiskInfo();.\n");
i=DiskInfo();
if (famT_drive) msg(DBG_TEA,"sbpcd_open: after i=DiskInfo();.\n");
- if ((D_S[d].ored_ctl_adr&0x40)==0)
+ if ((current_drive->ored_ctl_adr&0x40)==0)
{
msg(DBG_INF,"CD contains no data tracks.\n");
#if SAFE_MIXED
- D_S[d].has_data=0;
+ current_drive->has_data=0;
#endif /* SAFE_MIXED */
}
#if SAFE_MIXED
- else if (D_S[d].has_data<1) D_S[d].has_data=1;
+ else if (current_drive->has_data<1) current_drive->has_data=1;
#endif /* SAFE_MIXED */
}
if (!st_spinning) cc_SpinUp();
@@ -5407,32 +5403,30 @@ static int sbpcd_open(struct cdrom_device_info *cdi, int purpose)
*/
static void sbpcd_release(struct cdrom_device_info * cdi)
{
- int i;
+ struct sbpcd_drive *p = cdi->handle;
- i = minor(cdi->dev);
- if ((i<0) || (i>=NR_SBPCD) || (D_S[i].drv_id==-1))
- {
- msg(DBG_INF, "release: bad device: %04X\n", cdi->dev);
- return ;
+ if (p->drv_id==-1) {
+ msg(DBG_INF, "release: bad device: %s\n", cdi->name);
+ return;
}
down(&ioctl_read_sem);
- switch_drive(i);
+ switch_drive(p);
/*
* try to keep an "open" counter here and unlock the door if 1->0.
*/
msg(DBG_LCK,"open_count: %d -> %d\n",
- D_S[d].open_count,D_S[d].open_count-1);
- if (D_S[d].open_count>-2) /* CDROMEJECT may have been done */
+ p->open_count,p->open_count-1);
+ if (p->open_count>-2) /* CDROMEJECT may have been done */
{
- if (--D_S[d].open_count<=0)
+ if (--p->open_count<=0)
{
- D_S[d].sbp_first_frame=D_S[d].sbp_last_frame=-1;
- if (D_S[d].audio_state!=audio_playing)
- if (D_S[d].f_eject) cc_SpinDown();
- D_S[d].diskstate_flags &= ~cd_size_bit;
- D_S[d].open_count=0;
+ p->sbp_first_frame=p->sbp_last_frame=-1;
+ if (p->audio_state!=audio_playing)
+ if (p->f_eject) cc_SpinDown();
+ p->diskstate_flags &= ~cd_size_bit;
+ p->open_count=0;
#if SAFE_MIXED
- D_S[d].has_data=0;
+ p->has_data=0;
#endif /* SAFE_MIXED */
}
}
@@ -5463,13 +5457,6 @@ static struct cdrom_device_ops sbpcd_dops = {
n_minors: 1,
};
-static struct cdrom_device_info sbpcd_info = {
- ops: &sbpcd_dops,
- speed: 2,
- capacity: 1,
- name: "sbpcd",
-};
-
/*==========================================================================*/
/*
* accept "kernel command line" parameters
@@ -5708,21 +5695,23 @@ int __init sbpcd_init(void)
for (j=0;j<NR_SBPCD;j++)
{
- if (D_S[j].drv_id==-1) continue;
- switch_drive(j);
+ struct sbpcd_drive *p = D_S + j;
+ if (p->drv_id==-1)
+ continue;
+ switch_drive(p);
#if 1
if (!famL_drive) cc_DriveReset();
#endif
if (!st_spinning) cc_SpinUp();
- D_S[j].sbp_first_frame = -1; /* First frame in buffer */
- D_S[j].sbp_last_frame = -1; /* Last frame in buffer */
- D_S[j].sbp_read_frames = 0; /* Number of frames being read to buffer */
- D_S[j].sbp_current = 0; /* Frame being currently read */
- D_S[j].CD_changed=1;
- D_S[j].frame_size=CD_FRAMESIZE;
- D_S[j].f_eject=0;
+ p->sbp_first_frame = -1; /* First frame in buffer */
+ p->sbp_last_frame = -1; /* Last frame in buffer */
+ p->sbp_read_frames = 0; /* Number of frames being read to buffer */
+ p->sbp_current = 0; /* Frame being currently read */
+ p->CD_changed=1;
+ p->frame_size=CD_FRAMESIZE;
+ p->f_eject=0;
#if EJECT
- if (!fam0_drive) D_S[j].f_eject=1;
+ if (!fam0_drive) p->f_eject=1;
#endif /* EJECT */
cc_ReadStatus();
i=ResponseStatus(); /* returns orig. status or p_busy_new */
@@ -5742,8 +5731,8 @@ int __init sbpcd_init(void)
}
msg(DBG_INI,"init: first GetStatus: %d\n",i);
msg(DBG_LCS,"init: first GetStatus: error_byte=%d\n",
- D_S[j].error_byte);
- if (D_S[j].error_byte==aud_12)
+ p->error_byte);
+ if (p->error_byte==aud_12)
{
timeout=jiffies+2*HZ;
do
@@ -5752,14 +5741,14 @@ int __init sbpcd_init(void)
msg(DBG_INI,"init: second GetStatus: %02X\n",i);
msg(DBG_LCS,
"init: second GetStatus: error_byte=%d\n",
- D_S[j].error_byte);
+ p->error_byte);
if (i<0) break;
if (!st_caddy_in) break;
}
while ((!st_diskok)||time_after(jiffies, timeout));
}
i=SetSpeed();
- if (i>=0) D_S[j].CD_changed=1;
+ if (i>=0) p->CD_changed=1;
}
/*
@@ -5788,24 +5777,26 @@ int __init sbpcd_init(void)
for (j=0;j<NR_SBPCD;j++)
{
struct cdrom_device_info * sbpcd_infop;
+ struct sbpcd_drive *p = D_S + j;
- if (D_S[j].drv_id==-1) continue;
- switch_drive(j);
+ if (p->drv_id==-1) continue;
+ switch_drive(p);
#if SAFE_MIXED
- D_S[j].has_data=0;
+ p->has_data=0;
#endif /* SAFE_MIXED */
/*
* allocate memory for the frame buffers
*/
- D_S[j].aud_buf=NULL;
- D_S[j].sbp_audsiz=0;
- D_S[j].sbp_bufsiz=buffers;
- if (D_S[j].drv_type&drv_fam1)
- if (READ_AUDIO>0) D_S[j].sbp_audsiz=READ_AUDIO;
- D_S[j].sbp_buf=(u_char *) vmalloc(D_S[j].sbp_bufsiz*CD_FRAMESIZE);
- if (D_S[j].sbp_buf==NULL)
- {
- msg(DBG_INF,"data buffer (%d frames) not available.\n",D_S[j].sbp_bufsiz);
+ p->aud_buf=NULL;
+ p->sbp_audsiz=0;
+ p->sbp_bufsiz=buffers;
+ if (p->drv_type&drv_fam1)
+ if (READ_AUDIO>0)
+ p->sbp_audsiz = READ_AUDIO;
+ p->sbp_buf=(u_char *) vmalloc(buffers*CD_FRAMESIZE);
+ if (!p->sbp_buf) {
+ msg(DBG_INF,"data buffer (%d frames) not available.\n",
+ buffers);
if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
{
printk("Can't unregister %s\n", major_name);
@@ -5817,11 +5808,11 @@ int __init sbpcd_init(void)
#ifdef MODULE
msg(DBG_INF,"data buffer size: %d frames.\n",buffers);
#endif /* MODULE */
- if (D_S[j].sbp_audsiz>0)
+ if (p->sbp_audsiz>0)
{
- D_S[j].aud_buf=(u_char *) vmalloc(D_S[j].sbp_audsiz*CD_FRAMESIZE_RAW);
- if (D_S[j].aud_buf==NULL) msg(DBG_INF,"audio buffer (%d frames) not available.\n",D_S[j].sbp_audsiz);
- else msg(DBG_INF,"audio buffer size: %d frames.\n",D_S[j].sbp_audsiz);
+ p->aud_buf=(u_char *) vmalloc(p->sbp_audsiz*CD_FRAMESIZE_RAW);
+ if (p->aud_buf==NULL) msg(DBG_INF,"audio buffer (%d frames) not available.\n",p->sbp_audsiz);
+ else msg(DBG_INF,"audio buffer size: %d frames.\n",p->sbp_audsiz);
}
sbpcd_infop = vmalloc(sizeof (struct cdrom_device_info));
if (sbpcd_infop == NULL)
@@ -5830,12 +5821,15 @@ int __init sbpcd_init(void)
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
return -ENOMEM;
}
- D_S[j].sbpcd_infop = sbpcd_infop;
- memcpy (sbpcd_infop, &sbpcd_info, sizeof(struct cdrom_device_info));
+ memset(sbpcd_infop, 0, sizeof(struct cdrom_device_info));
+ sbpcd_infop->ops = &sbpcd_dops;
+ sbpcd_infop->speed = 2;
+ sbpcd_infop->capacity = 1;
+ sprintf(sbpcd_infop->name, "sbpcd%d", j);
sbpcd_infop->dev = mk_kdev(MAJOR_NR, j);
- strncpy(sbpcd_infop->name,major_name, sizeof(sbpcd_infop->name));
-
- sprintf (nbuff, "c0t%d/cd", D_S[j].drv_id);
+ sbpcd_infop->handle = p;
+ p->sbpcd_infop = sbpcd_infop;
+ sprintf(nbuff, "c0t%d/cd", p->drv_id);
sbpcd_infop->de =
devfs_register (devfs_handle, nbuff, DEVFS_FL_DEFAULT,
MAJOR_NR, j, S_IFBLK | S_IRUGO | S_IWUGO,
@@ -5886,28 +5880,21 @@ module_exit(sbpcd_exit);
#endif /* MODULE */
-/*==========================================================================*/
-/*
- * Check if the media has changed in the CD-ROM drive.
- * used externally (isofs/inode.c, fs/buffer.c)
- */
-static int sbpcd_chk_disk_change(kdev_t full_dev)
+static int sbpcd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
{
- int i;
-
- i=minor(full_dev);
- msg(DBG_CHK,"media_check (%d) called\n", i);
+ struct sbpcd_drive *p = cdi->handle;
+ msg(DBG_CHK,"media_check (%s) called\n", cdi->name);
- if (D_S[i].CD_changed==0xFF)
+ if (p->CD_changed==0xFF)
{
- D_S[i].CD_changed=0;
- msg(DBG_CHK,"medium changed (drive %d)\n", i);
+ p->CD_changed=0;
+ msg(DBG_CHK,"medium changed (drive %s)\n", cdi->name);
/* BUG! Should invalidate buffers! --AJK */
/* Why should it do the above at all?! --mdcki */
- D_S[d].diskstate_flags &= ~toc_bit;
- D_S[d].diskstate_flags &= ~cd_size_bit;
+ current_drive->diskstate_flags &= ~toc_bit;
+ current_drive->diskstate_flags &= ~cd_size_bit;
#if SAFE_MIXED
- D_S[d].has_data=0;
+ current_drive->has_data=0;
#endif /* SAFE_MIXED */
return (1);
@@ -5916,11 +5903,6 @@ static int sbpcd_chk_disk_change(kdev_t full_dev)
return (0);
}
-static int sbpcd_media_changed( struct cdrom_device_info *cdi, int disc_nr)
-{
- return sbpcd_chk_disk_change(cdi->dev);
-}
-
MODULE_LICENSE("GPL");
/*==========================================================================*/
diff --git a/drivers/cdrom/sbpcd.h b/drivers/cdrom/sbpcd.h
index 74255554611d..16a0208a2598 100644
--- a/drivers/cdrom/sbpcd.h
+++ b/drivers/cdrom/sbpcd.h
@@ -242,12 +242,12 @@
/*
* disk states (bits of diskstate_flags):
*/
-#define upc_valid (D_S[d].diskstate_flags&upc_bit)
-#define volume_valid (D_S[d].diskstate_flags&volume_bit)
-#define toc_valid (D_S[d].diskstate_flags&toc_bit)
-#define cd_size_valid (D_S[d].diskstate_flags&cd_size_bit)
-#define subq_valid (D_S[d].diskstate_flags&subq_bit)
-#define frame_size_valid (D_S[d].diskstate_flags&frame_size_bit)
+#define upc_valid (current_drive->diskstate_flags&upc_bit)
+#define volume_valid (current_drive->diskstate_flags&volume_bit)
+#define toc_valid (current_drive->diskstate_flags&toc_bit)
+#define cd_size_valid (current_drive->diskstate_flags&cd_size_bit)
+#define subq_valid (current_drive->diskstate_flags&subq_bit)
+#define frame_size_valid (current_drive->diskstate_flags&frame_size_bit)
/*
* the status_bits variable
@@ -324,13 +324,13 @@
/*
* used drive states:
*/
-#define st_door_closed (D_S[d].status_bits&p_door_closed)
-#define st_caddy_in (D_S[d].status_bits&p_caddy_in)
-#define st_spinning (D_S[d].status_bits&p_spinning)
-#define st_check (D_S[d].status_bits&p_check)
-#define st_busy (D_S[d].status_bits&p_busy_new)
-#define st_door_locked (D_S[d].status_bits&p_door_locked)
-#define st_diskok (D_S[d].status_bits&p_disk_ok)
+#define st_door_closed (current_drive->status_bits&p_door_closed)
+#define st_caddy_in (current_drive->status_bits&p_caddy_in)
+#define st_spinning (current_drive->status_bits&p_spinning)
+#define st_check (current_drive->status_bits&p_check)
+#define st_busy (current_drive->status_bits&p_busy_new)
+#define st_door_locked (current_drive->status_bits&p_door_locked)
+#define st_diskok (current_drive->status_bits&p_disk_ok)
/*
* bits of the CDi_status register:
@@ -372,22 +372,22 @@
#define drv_famV 0x2000 /* ECS-AT (vertos-100) family */
#define drv_at (drv_famV+0x01) /* ECS-AT, firmware "1.00" */
-#define fam0_drive (D_S[d].drv_type&drv_fam0)
-#define famL_drive (D_S[d].drv_type&drv_famL)
-#define famV_drive (D_S[d].drv_type&drv_famV)
-#define fam1_drive (D_S[d].drv_type&drv_fam1)
-#define fam2_drive (D_S[d].drv_type&drv_fam2)
-#define famT_drive (D_S[d].drv_type&drv_famT)
-#define fam0L_drive (D_S[d].drv_type&(drv_fam0|drv_famL))
-#define fam0V_drive (D_S[d].drv_type&(drv_fam0|drv_famV))
-#define famLV_drive (D_S[d].drv_type&(drv_famL|drv_famV))
-#define fam0LV_drive (D_S[d].drv_type&(drv_fam0|drv_famL|drv_famV))
-#define fam1L_drive (D_S[d].drv_type&(drv_fam1|drv_famL))
-#define fam1V_drive (D_S[d].drv_type&(drv_fam1|drv_famV))
-#define fam1LV_drive (D_S[d].drv_type&(drv_fam1|drv_famL|drv_famV))
-#define fam01_drive (D_S[d].drv_type&(drv_fam0|drv_fam1))
-#define fam12_drive (D_S[d].drv_type&(drv_fam1|drv_fam2))
-#define fam2T_drive (D_S[d].drv_type&(drv_fam2|drv_famT))
+#define fam0_drive (current_drive->drv_type&drv_fam0)
+#define famL_drive (current_drive->drv_type&drv_famL)
+#define famV_drive (current_drive->drv_type&drv_famV)
+#define fam1_drive (current_drive->drv_type&drv_fam1)
+#define fam2_drive (current_drive->drv_type&drv_fam2)
+#define famT_drive (current_drive->drv_type&drv_famT)
+#define fam0L_drive (current_drive->drv_type&(drv_fam0|drv_famL))
+#define fam0V_drive (current_drive->drv_type&(drv_fam0|drv_famV))
+#define famLV_drive (current_drive->drv_type&(drv_famL|drv_famV))
+#define fam0LV_drive (current_drive->drv_type&(drv_fam0|drv_famL|drv_famV))
+#define fam1L_drive (current_drive->drv_type&(drv_fam1|drv_famL))
+#define fam1V_drive (current_drive->drv_type&(drv_fam1|drv_famV))
+#define fam1LV_drive (current_drive->drv_type&(drv_fam1|drv_famL|drv_famV))
+#define fam01_drive (current_drive->drv_type&(drv_fam0|drv_fam1))
+#define fam12_drive (current_drive->drv_type&(drv_fam1|drv_fam2))
+#define fam2T_drive (current_drive->drv_type&(drv_fam2|drv_famT))
/*
* audio states:
diff --git a/drivers/ide/hd.c b/drivers/ide/hd.c
index 81624ccfe02f..714e27ff87b1 100644
--- a/drivers/ide/hd.c
+++ b/drivers/ide/hd.c
@@ -145,8 +145,6 @@ static struct hd_i_struct hd_info[MAX_HD];
static int NR_HD;
#endif
-static struct hd_struct hd[MAX_HD<<6];
-
static struct timer_list device_timer;
#define TIMEOUT_VALUE (6*HZ)
@@ -596,22 +594,21 @@ repeat:
reset_hd();
return;
}
- dev = minor(CURRENT->rq_dev);
+ dev = DEVICE_NR(CURRENT->rq_dev);
block = CURRENT->sector;
nsect = CURRENT->nr_sectors;
- if (dev >= (NR_HD<<6) || (dev & 0x3f) ||
- block >= hd[dev].nr_sects || ((block+nsect) > hd[dev].nr_sects)) {
- if (dev >= (NR_HD<<6) || (dev & 0x3f))
+ if (dev >= NR_HD || block >= get_capacity(hd_gendisk+dev) ||
+ ((block+nsect) > get_capacity(hd_gendisk+unit))) {
+ if (dev >= NR_HD)
printk("hd: bad minor number: device=%s\n",
kdevname(CURRENT->rq_dev));
else
printk("hd%c: bad access: block=%d, count=%d\n",
- (minor(CURRENT->rq_dev)>>6)+'a', block, nsect);
+ dev+'a', block, nsect);
end_request(CURRENT, 0);
goto repeat;
}
- dev >>= 6;
if (special_op[dev]) {
if (do_special_op(dev))
goto repeat;
@@ -707,14 +704,12 @@ static struct gendisk hd_gendisk[2] = {
.first_minor = 0,
.major_name = "hda",
.minor_shift = 6,
- .part = hd,
.fops = &hd_fops,
},{
.major = MAJOR_NR,
.first_minor = 64,
.major_name = "hdb",
.minor_shift = 6,
- .part = hd + 64,
.fops = &hd_fops,
}
};
@@ -819,10 +814,11 @@ static void __init hd_geninit(void)
#endif
for (drive=0 ; drive < NR_HD ; drive++) {
- hd[drive<<6].nr_sects = hd_info[drive].head *
+ sector_t size = hd_info[drive].head *
hd_info[drive].sect * hd_info[drive].cyl;
- printk ("hd%c: %ldMB, CHS=%d/%d/%d\n", drive+'a',
- hd[drive<<6].nr_sects / 2048, hd_info[drive].cyl,
+ set_capacity(hd_gendisk + drive, size);
+ printk ("%s: %ldMB, CHS=%d/%d/%d\n", hd_gendisk[drive].major_name,
+ size / 2048, hd_info[drive].cyl,
hd_info[drive].head, hd_info[drive].sect);
}
if (!NR_HD)
@@ -849,7 +845,6 @@ static void __init hd_geninit(void)
}
for(drive=0; drive < NR_HD; drive++) {
- hd_gendisk[drive].nr_real = 1;
add_gendisk(hd_gendisk + drive);
register_disk(hd_gendisk + drive,
mk_kdev(MAJOR_NR,drive<<6), 1<<6,
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index d6e7db8b7887..b293f3e92833 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -2138,7 +2138,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
if (stat)
toc->capacity = 0x1fffff;
- drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
+ set_capacity(drive->disk, toc->capacity * SECTORS_PER_FRAME);
/* Remember that we've read this stuff. */
CDROM_STATE_FLAGS (drive)->toc_valid = 1;
@@ -2593,9 +2593,8 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
{
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *devinfo = &info->devinfo;
- int minor = (drive->select.b.unit) << PARTN_BITS;
- devinfo->dev = mk_kdev(HWIF(drive)->major, minor);
+ devinfo->dev = mk_kdev(drive->disk->major, drive->disk->first_minor);
devinfo->ops = &ide_cdrom_dops;
devinfo->mask = 0;
*(int *)&devinfo->speed = CDROM_STATE_FLAGS (drive)->current_speed;
@@ -2622,7 +2621,8 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
devinfo->mask |= CDC_CLOSE_TRAY;
devinfo->de = devfs_register(drive->de, "cd", DEVFS_FL_DEFAULT,
- HWIF(drive)->major, minor,
+ drive->disk->major,
+ drive->disk->first_minor,
S_IFBLK | S_IRUGO | S_IWUGO,
ide_fops, NULL);
@@ -2823,13 +2823,12 @@ int ide_cdrom_setup (ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *cdi = &info->devinfo;
- int minor = drive->select.b.unit << PARTN_BITS;
int nslots;
/*
* default to read-only always and fix latter at the bottom
*/
- set_device_ro(mk_kdev(HWIF(drive)->major, minor), 1);
+ set_device_ro(mk_kdev(drive->disk->major, drive->disk->first_minor), 1);
blk_queue_hardsect_size(&drive->queue, CD_FRAMESIZE);
blk_queue_prep_rq(&drive->queue, ll_10byte_cmd_build);
@@ -2951,7 +2950,7 @@ int ide_cdrom_setup (ide_drive_t *drive)
nslots = ide_cdrom_probe_capabilities (drive);
if (CDROM_CONFIG_FLAGS(drive)->dvd_ram)
- set_device_ro(mk_kdev(HWIF(drive)->major, minor), 0);
+ set_device_ro(mk_kdev(drive->disk->major, drive->disk->first_minor), 0);
if (ide_cdrom_register (drive, nslots)) {
printk ("%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
@@ -2998,8 +2997,8 @@ void ide_cdrom_release (struct inode *inode, struct file *file,
static
int ide_cdrom_check_media_change (ide_drive_t *drive)
{
- return cdrom_media_changed(mk_kdev(HWIF (drive)->major,
- (drive->select.b.unit) << PARTN_BITS));
+ return cdrom_media_changed(mk_kdev(drive->disk->major,
+ drive->disk->first_minor));
}
static
@@ -3025,9 +3024,7 @@ int ide_cdrom_cleanup(ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *devinfo = &info->devinfo;
- ide_hwif_t *hwif = HWIF(drive);
- int unit = drive - hwif->drives;
- struct gendisk *g = hwif->gd[unit];
+ struct gendisk *g = drive->disk;
if (ide_unregister_subdriver (drive))
return 1;
@@ -3092,9 +3089,7 @@ MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
static int ide_cdrom_reinit (ide_drive_t *drive)
{
struct cdrom_info *info;
- ide_hwif_t *hwif = HWIF(drive);
- int unit = drive - hwif->drives;
- struct gendisk *g = hwif->gd[unit];
+ struct gendisk *g = drive->disk;
struct request_sense sense;
if (!strstr("ide-cdrom", drive->driver_req))
@@ -3147,10 +3142,13 @@ static int ide_cdrom_reinit (ide_drive_t *drive)
cdrom_read_toc(drive, &sense);
g->minor_shift = 0;
+ /* probably bogus, but that's the old behaviour */
+ g->de = NULL;
+ g->flags = GENHD_FL_DEVFS;
add_gendisk(g);
register_disk(g, mk_kdev(g->major,g->first_minor),
1<<g->minor_shift, ide_fops,
- g->part[0].nr_sects);
+ get_capacity(g));
return 0;
failed:
return 1;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index ce8e1a9e57b9..e8040b7626f7 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1516,8 +1516,6 @@ static void idedisk_add_settings(ide_drive_t *drive)
static void idedisk_setup (ide_drive_t *drive)
{
- int i;
-
struct hd_driveid *id = drive->id;
unsigned long capacity;
@@ -1538,15 +1536,6 @@ static void idedisk_setup (ide_drive_t *drive)
drive->doorlocking = 1;
}
}
- for (i = 0; i < MAX_DRIVES; ++i) {
- ide_hwif_t *hwif = HWIF(drive);
-
- if (drive != &hwif->drives[i]) continue;
- hwif->gd[i]->de_arr[i] = drive->de;
- if (drive->removable)
- hwif->gd[i]->flags[i] |= GENHD_FL_REMOVABLE;
- break;
- }
#if 1
(void) probe_lba_addressing(drive, 1);
@@ -1629,9 +1618,7 @@ static void idedisk_setup (ide_drive_t *drive)
static int idedisk_cleanup (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
- int unit = drive - hwif->drives;
- struct gendisk *g = hwif->gd[unit];
+ struct gendisk *g = drive->disk;
if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
if (do_idedisk_flushcache(drive))
printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
@@ -1683,9 +1670,7 @@ MODULE_DESCRIPTION("ATA DISK Driver");
static int idedisk_reinit(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
- int unit = drive - hwif->drives;
- struct gendisk *g = hwif->gd[unit];
+ struct gendisk *g = drive->disk;
/* strstr("foo", "") is non-NULL */
if (!strstr("ide-disk", drive->driver_req))
@@ -1714,6 +1699,9 @@ static int idedisk_reinit(ide_drive_t *drive)
}
DRIVER(drive)->busy--;
g->minor_shift = PARTN_BITS;
+ g->de = drive->de;
+ g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
+ g->flags |= GENHD_FL_DEVFS;
add_gendisk(g);
register_disk(g, mk_kdev(g->major,g->first_minor),
1<<g->minor_shift, ide_fops,
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 4a62a49af582..3c6fbfd9b3f4 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -1500,7 +1500,7 @@ static int idefloppy_get_capacity (ide_drive_t *drive)
drive->bios_cyl = 0;
drive->bios_head = drive->bios_sect = 0;
floppy->blocks = floppy->bs_factor = 0;
- drive->part[0].nr_sects = 0;
+ set_capacity(drive->disk, 0);
idefloppy_create_read_capacity_cmd (&pc);
if (idefloppy_queue_pc_tail (drive, &pc)) {
@@ -1555,7 +1555,7 @@ static int idefloppy_get_capacity (ide_drive_t *drive)
(void) idefloppy_get_flexible_disk_page (drive);
}
- drive->part[0].nr_sects = floppy->blocks * floppy->bs_factor;
+ set_capacity(drive->disk, floppy->blocks * floppy->bs_factor);
return rc;
}
@@ -2065,7 +2065,6 @@ static void idefloppy_add_settings(ide_drive_t *drive)
static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
{
struct idefloppy_id_gcw gcw;
- int i;
*((unsigned short *) &gcw) = drive->id->config;
drive->driver_data = floppy;
@@ -2108,23 +2107,12 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
(void) idefloppy_get_capacity (drive);
idefloppy_add_settings(drive);
- for (i = 0; i < MAX_DRIVES; ++i) {
- ide_hwif_t *hwif = HWIF(drive);
-
- if (drive != &hwif->drives[i]) continue;
- hwif->gd[i]->de_arr[i] = drive->de;
- if (drive->removable)
- hwif->gd[i]->flags[i] |= GENHD_FL_REMOVABLE;
- break;
- }
}
static int idefloppy_cleanup (ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- ide_hwif_t *hwif = HWIF(drive);
- int unit = drive - hwif->drives;
- struct gendisk *g = hwif->gd[unit];
+ struct gendisk *g = drive->disk;
if (ide_unregister_subdriver (drive))
return 1;
@@ -2191,9 +2179,7 @@ static ide_driver_t idefloppy_driver = {
static int idefloppy_reinit (ide_drive_t *drive)
{
idefloppy_floppy_t *floppy;
- ide_hwif_t *hwif = HWIF(drive);
- int unit = drive - hwif->drives;
- struct gendisk *g = hwif->gd[unit];
+ struct gendisk *g = drive->disk;
if (!strstr("ide-floppy", drive->driver_req))
goto failed;
if (!drive->present)
@@ -2221,10 +2207,13 @@ static int idefloppy_reinit (ide_drive_t *drive)
idefloppy_setup (drive, floppy);
DRIVER(drive)->busy--;
g->minor_shift = PARTN_BITS;
+ g->de = drive->de;
+ g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
+ g->flags |= GENHD_FL_DEVFS;
add_gendisk(g);
register_disk(g, mk_kdev(g->major,g->first_minor),
1<<g->minor_shift, ide_fops,
- g->part[0].nr_sects);
+ get_capacity(g));
return 0;
failed:
return 1;
diff --git a/drivers/ide/ide-geometry.c b/drivers/ide/ide-geometry.c
index 5f21651c1785..850419f2a0a7 100644
--- a/drivers/ide/ide-geometry.c
+++ b/drivers/ide/ide-geometry.c
@@ -214,7 +214,7 @@ int ide_xlate_1024 (kdev_t i_rdev, int xparm, int ptheads, const char *msg)
ret = 1;
}
- drive->part[0].nr_sects = current_capacity(drive);
+ set_capacity(drive->disk, current_capacity(drive));
if (ret)
printk("%s%s [%d/%d/%d]", msg, msg1,
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 1b972998ea2f..f56203db719a 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -807,9 +807,6 @@ static int init_irq (ide_hwif_t *hwif)
static void init_gendisk (ide_hwif_t *hwif)
{
struct gendisk *gd;
- struct hd_struct *part;
- devfs_handle_t *de_arr;
- char *flags;
unsigned int unit, units, minors;
extern devfs_handle_t ide_devfs_handle;
char *names;
@@ -830,40 +827,19 @@ static void init_gendisk (ide_hwif_t *hwif)
goto err_kmalloc_gd;
memset(gd, 0, MAX_DRIVES * sizeof(struct gendisk));
- part = kmalloc(minors * sizeof(struct hd_struct), GFP_KERNEL);
- if (!part)
- goto err_kmalloc_gd_part;
-
- memset(part, 0, minors * sizeof(struct hd_struct));
-
- de_arr = kmalloc(sizeof(devfs_handle_t) * MAX_DRIVES, GFP_KERNEL);
- if (!de_arr)
- goto err_kmalloc_gd_de_arr;
- memset(de_arr, 0, sizeof(devfs_handle_t) * MAX_DRIVES);
-
- flags = kmalloc(sizeof(char) * MAX_DRIVES, GFP_KERNEL);
- if (!flags)
- goto err_kmalloc_gd_flags;
- memset(flags, 0, sizeof(char) * MAX_DRIVES);
-
names = kmalloc (4 * MAX_DRIVES, GFP_KERNEL);
if (!names)
goto err_kmalloc_gd_names;
memset(names, 0, 4 * MAX_DRIVES);
for (unit = 0; unit < units; ++unit) {
- gd[unit].part = part + (unit << PARTN_BITS);
- gd[unit].de_arr = de_arr + unit;
- gd[unit].flags = flags + unit;
- hwif->drives[unit].part = gd[unit].part;
gd[unit].major = hwif->major;
gd[unit].first_minor = unit << PARTN_BITS;
sprintf(names + 4*unit, "hd%c",'a'+hwif->index*MAX_DRIVES+unit);
gd[unit].major_name = names + 4*unit;
gd[unit].minor_shift = PARTN_BITS;
- gd[unit].nr_real = 1;
gd[unit].fops = ide_fops;
- hwif->gd[unit] = gd + unit;
+ hwif->drives[unit].disk = gd + unit;
}
for (unit = 0; unit < units; ++unit) {
@@ -892,12 +868,6 @@ static void init_gendisk (ide_hwif_t *hwif)
return;
err_kmalloc_gd_names:
- kfree(names);
-err_kmalloc_gd_flags:
- kfree(de_arr);
-err_kmalloc_gd_de_arr:
- kfree(part);
-err_kmalloc_gd_part:
kfree(gd);
err_kmalloc_gd:
printk(KERN_WARNING "(ide::init_gendisk) Out of memory\n");
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 8ae42efbe71c..e072c15231a1 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1660,7 +1660,7 @@ ide_drive_t *get_info_ptr (kdev_t i_rdev)
if (unit < MAX_DRIVES) {
ide_drive_t *drive = &hwif->drives[unit];
#if 0
- if ((drive->present) && (drive->part[minor].nr_sects))
+ if (drive->present && get_capacity(drive->disk))
#else
if (drive->present)
#endif
@@ -1747,10 +1747,7 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
void ide_revalidate_drive (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
- int unit = drive - hwif->drives;
- struct gendisk *g = hwif->gd[unit];
- g->part[0].nr_sects = current_capacity(drive);
+ set_capacity(drive->disk, current_capacity(drive));
}
/*
@@ -1975,7 +1972,7 @@ void ide_unregister (unsigned int index)
continue;
minor = drive->select.b.unit << PARTN_BITS;
for (p = 0; p < (1<<PARTN_BITS); ++p) {
- if (drive->part[p].nr_sects > 0) {
+ if (get_capacity(drive->disk)) {
kdev_t devp = mk_kdev(hwif->major, minor+p);
invalidate_device(devp, 0);
}
@@ -2055,17 +2052,12 @@ void ide_unregister (unsigned int index)
blk_dev[hwif->major].data = NULL;
blk_dev[hwif->major].queue = NULL;
blk_clear(hwif->major);
- gd = hwif->gd[0];
+ gd = hwif->drives[0].disk;
if (gd) {
int i;
- kfree(gd->part);
- if (gd->de_arr)
- kfree (gd->de_arr);
- if (gd->flags)
- kfree (gd->flags);
- kfree(gd);
for (i = 0; i < MAX_DRIVES; i++)
- hwif->gd[i] = NULL;
+ hwif->drives[i].disk = NULL;
+ kfree(gd);
}
old_hwif = *hwif;
init_hwif_data (index); /* restore hwif data to pristine status */
@@ -2527,7 +2519,7 @@ static int ide_ioctl (struct inode *inode, struct file *file,
if (put_user(drive->bios_head, (byte *) &loc->heads)) return -EFAULT;
if (put_user(drive->bios_sect, (byte *) &loc->sectors)) return -EFAULT;
if (put_user(bios_cyl, (unsigned short *) &loc->cylinders)) return -EFAULT;
- if (put_user((unsigned)drive->part[minor(inode->i_rdev)&PARTN_MASK].start_sect,
+ if (put_user((unsigned)get_start_sect(inode->i_bdev),
(unsigned long *) &loc->start)) return -EFAULT;
return 0;
}
@@ -2539,7 +2531,7 @@ static int ide_ioctl (struct inode *inode, struct file *file,
if (put_user(drive->head, (byte *) &loc->heads)) return -EFAULT;
if (put_user(drive->sect, (byte *) &loc->sectors)) return -EFAULT;
if (put_user(drive->cyl, (unsigned int *) &loc->cylinders)) return -EFAULT;
- if (put_user((unsigned)drive->part[minor(inode->i_rdev)&PARTN_MASK].start_sect,
+ if (put_user((unsigned)get_start_sect(inode->i_bdev),
(unsigned long *) &loc->start)) return -EFAULT;
return 0;
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 16496cc15d77..2686038c5a9e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -103,11 +103,6 @@ static ctl_table raid_root_table[] = {
{0}
};
-/*
- * these have to be allocated separately because external
- * subsystems want to have a pre-defined structure
- */
-struct hd_struct md_hd_struct[MAX_MD_DEVS];
static void md_recover_arrays(void);
static mdk_thread_t *md_recovery_thread;
@@ -276,7 +271,7 @@ char * partition_name(kdev_t dev)
hd = get_gendisk (dev);
dname->name = NULL;
if (hd)
- dname->name = disk_name (hd, minor(dev), dname->namebuf);
+ dname->name = disk_name(hd, minor(dev)-hd->first_minor, dname->namebuf);
if (!dname->name) {
sprintf (dname->namebuf, "[dev %s]", kdevname(dev));
dname->name = dname->namebuf;
@@ -618,7 +613,7 @@ static void free_mddev(mddev_t *mddev)
export_array(mddev);
md_size[mdidx(mddev)] = 0;
- md_hd_struct[mdidx(mddev)].nr_sects = 0;
+ set_capacity(disks[mdidx(mddev)], 0);
}
#undef BAD_CSUM
@@ -1458,8 +1453,6 @@ static int do_md_run(mddev_t * mddev)
disk->minor_shift = 0;
sprintf(major_name, "md%d", mdidx(mddev));
disk->major_name = major_name;
- disk->part = md_hd_struct + mdidx(mddev);
- disk->nr_real = 1;
disk->fops = &md_fops;
mddev->pers = pers[pnum];
@@ -2344,7 +2337,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
err = put_user (4, (char *) &loc->sectors);
if (err)
goto abort_unlock;
- err = put_user (md_hd_struct[mdidx(mddev)].nr_sects/8,
+ err = put_user(get_capacity(disks[mdidx(mddev)])/8,
(short *) &loc->cylinders);
if (err)
goto abort_unlock;
@@ -3178,11 +3171,10 @@ int __init md_init(void)
return (-1);
}
devfs_handle = devfs_mk_dir (NULL, "md", NULL);
- /* we don't use devfs_register_series because we want to fill md_hd_struct */
for (minor=0; minor < MAX_MD_DEVS; ++minor) {
char devname[128];
sprintf (devname, "%u", minor);
- md_hd_struct[minor].de = devfs_register (devfs_handle,
+ devfs_register (devfs_handle,
devname, DEVFS_FL_DEFAULT, MAJOR_NR, minor,
S_IFBLK | S_IRUSR | S_IWUSR, &md_fops, NULL);
}
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 0dba96c0d6af..ae7befdf574b 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -186,7 +186,6 @@ static struct i2ob_request *i2ob_backlog_tail[MAX_I2O_CONTROLLERS];
static struct i2ob_device i2ob_dev[MAX_I2OB<<4];
static int i2ob_dev_count = 0;
-static struct hd_struct i2ob[MAX_I2OB<<4];
static struct gendisk i2o_disk[MAX_I2OB];
static char i2o_names[MAX_I2OB * 8];
@@ -248,7 +247,7 @@ static u32 i2ob_get(struct i2ob_device *dev)
* Turn a Linux block request into an I2O block read/write.
*/
-static int i2ob_send(u32 m, struct i2ob_device *dev, struct i2ob_request *ireq, u32 base, int unit)
+static int i2ob_send(u32 m, struct i2ob_device *dev, struct i2ob_request *ireq, int unit)
{
struct i2o_controller *c = dev->controller;
int tid = dev->tid;
@@ -279,7 +278,7 @@ static int i2ob_send(u32 m, struct i2ob_device *dev, struct i2ob_request *ireq,
/* This can be optimised later - just want to be sure its right for
starters */
- offset = ((u64)(req->sector+base)) << 9;
+ offset = ((u64)req->sector) << 9;
__raw_writel( offset & 0xFFFFFFFF, msg+24);
__raw_writel(offset>>32, msg+28);
mptr=msg+32;
@@ -724,7 +723,7 @@ static int i2ob_evt(void *dummy)
register_disk(p,
mk_kdev(p->major, p->first_minor),
1<<p->minor_shift, p->fops,
- i2ob[unit].nr_sects);
+ get_capacity(p));
break;
}
@@ -737,7 +736,6 @@ static int i2ob_evt(void *dummy)
case I2O_EVT_IND_BSA_VOLUME_UNLOAD:
{
struct gendisk *p = &i2o_disk[unit>>4];
- wipe_partitions(mk_kdev(MAJOR_NR, unit));
del_gendisk(p);
for(i = unit; i <= unit+15; i++)
blk_queue_max_sectors(i2ob_dev[i].req_queue, 0);
@@ -769,7 +767,7 @@ static int i2ob_evt(void *dummy)
i2ob_query_device(&i2ob_dev[unit], 0x0000, 4, &size, 8);
spin_lock_irqsave(I2O_LOCK(unit), flags);
- i2ob[unit].nr_sects = size>>9;
+ set_capacity(&i2o_disk[unit>>4], size>>9);
spin_unlock_irqrestore(I2O_LOCK(unit), flags);
break;
}
@@ -870,7 +868,7 @@ static int i2ob_backlog_request(struct i2o_controller *c, struct i2ob_device *de
i2ob_backlog_tail[c->unit] = NULL;
unit = minor(ireq->req->rq_dev);
- i2ob_send(m, dev, ireq, i2ob[unit].start_sect, unit);
+ i2ob_send(m, dev, ireq, unit);
}
if(i2ob_backlog[c->unit])
return 1;
@@ -970,7 +968,7 @@ static void i2ob_request(request_queue_t *q)
i2ob_queues[dev->unit]->i2ob_qhead = ireq->next;
ireq->req = req;
- i2ob_send(m, dev, ireq, i2ob[unit].start_sect, (unit&0xF0));
+ i2ob_send(m, dev, ireq, (unit&0xF0));
}
}
@@ -1039,7 +1037,7 @@ static int i2ob_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct hd_geometry g;
- int u = minor(inode->i_rdev) & 0xF0;
+ int u = minor(inode->i_rdev) >> 4;
/* Anyone capable of this syscall can do *real bad* things */
if (!capable(CAP_SYS_ADMIN))
@@ -1047,7 +1045,7 @@ static int i2ob_ioctl(struct inode *inode, struct file *file,
if (cmd != HDIO_GETGEO)
return -EINVAL;
- i2o_block_biosparam(i2ob[u].nr_sects,
+ i2o_block_biosparam(get_capacity(&i2o_disk[u]),
&g.cylinders, &g.heads, &g.sectors);
g.start = get_start_sect(inode->i_bdev);
return copy_to_user((void *)arg, &g, sizeof(g)) ? -EFAULT : 0;
@@ -1223,7 +1221,7 @@ static int i2ob_install_device(struct i2o_controller *c, struct i2o_device *d, i
i2ob_query_device(dev, 0x0000, 5, &flags, 4);
i2ob_query_device(dev, 0x0000, 6, &status, 4);
- i2ob[unit].nr_sects = size>>9;
+ set_capacity(&i2o_disk[unit>>4], size>>9);
/* Set limit based on inbound frame size */
limit = (d->controller->status_block->inbound_frame_size - 8)/2;
@@ -1327,7 +1325,7 @@ static int i2ob_install_device(struct i2o_controller *c, struct i2o_device *d, i
i2o_event_register(c, d->lct_data.tid, i2ob_context, unit,
(I2OB_EVENT_MASK & d->lct_data.event_capabilities));
- i2ob[unit].nr_sects = size>>9;
+ set_capacity(i2o_disk[unit>>4], size>>9);
return 0;
}
@@ -1472,7 +1470,7 @@ static void i2ob_scan(int bios)
register_disk(p,
mk_kdev(p->major, p->first_minor),
1<<p->minor_shift, p->fops,
- i2ob[scan_unit].nr_sects);
+ get_capacity(p));
scan_unit+=16;
i2ob_dev_count++;
@@ -1565,7 +1563,7 @@ void i2ob_new_device(struct i2o_controller *c, struct i2o_device *d)
register_disk(p,
mk_kdev(p->major, p->first_minor),
1<<p->minor_shift, p->fops,
- i2ob[unit].nr_sects);
+ get_capacity(p));
i2ob_dev_count++;
i2o_device_notify_on(d, &i2o_block_handler);
}
@@ -1616,7 +1614,6 @@ void i2ob_del_device(struct i2o_controller *c, struct i2o_device *d)
* This will force errors when i2ob_get_queue() is called
* by the kenrel.
*/
- wipe_partitions(mk_kdev(MAJOR_NR, unit));
del_gendisk(&i2o_disk[unit>>4]);
i2ob_dev[unit].req_queue = NULL;
for(i = unit; i <= unit+15; i++)
@@ -1773,9 +1770,7 @@ int i2o_block_init(void)
disk->major = MAJOR_NR;
disk->first_minor = i<<4;
disk->minor_shift = 4;
- disk->part = i2ob + (i<<4);
disk->fops = &i2ob_fops;
- disk->nr_real = 1;
disk->major_name = i2o_names + i*8;
sprintf(disk->major_name, "i2o/hd%c", 'a' + i);
}
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index 83e5ba3c3f7f..4ddc0d9337ec 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -175,8 +175,6 @@ static struct mtd_notifier ftl_notifier = {
#define XFER_PREPARED 0x03
#define XFER_FAILED 0x04
-static struct hd_struct ftl_hd[MINOR_NR(MAX_DEV, 0, 0)];
-
/*====================================================================*/
static int ftl_ioctl(struct inode *inode, struct file *file,
@@ -846,7 +844,7 @@ static int ftl_open(struct inode *inode, struct file *file)
if (partition->state != FTL_FORMATTED)
return -ENXIO;
- if (partition->disk->part[0].nr_sects == 0)
+ if (get_capacity(partition->disk) == 0)
return -ENXIO;
if (!get_mtd_device(partition->mtd, -1))
@@ -1132,8 +1130,8 @@ static int ftl_revalidate(kdev_t dev)
int unit = minor(dev) >> 4;
partition_t *part = myparts[unit];
scan_header(part);
- part->disk->part[0].nr_sects =
- le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
+ set_capacity(part->disk,
+ le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE));
return 0;
}
@@ -1252,9 +1250,7 @@ static void ftl_notify_add(struct mtd_info *mtd)
disk->first_minor = device << 4;
disk->major_name = name;
disk->minor_shift = PART_BITS;
- disk->part = ftl_hd + (device << 4);
disk->fops = &ftl_blk_fops;
- disk->nr_real = 1;
partition->mtd = mtd;
partition->disk = disk;
@@ -1298,7 +1294,6 @@ static void ftl_notify_remove(struct mtd_info *mtd)
ftl_freepart(myparts[i]);
myparts[i]->state = 0;
- wipe_partitions(mk_kdev(MAJOR_NR, i<<4));
del_gendisk(myparts[i]->disk);
kfree(myparts[i]->disk->name);
kfree(myparts[i]->disk);
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index 2de5c0783fde..c6fa25aeabf6 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -49,16 +49,6 @@
/* Linux-specific block device functions */
-/* I _HATE_ the Linux block device setup more than anything else I've ever
- * encountered, except ...
- */
-
-/* .. for the Linux partition table handling. */
-/* So why didn't you fucking go and clean it up? -- AV */
-struct hd_struct part_table[256];
-
-static struct block_device_operations nftl_fops;
-
struct NFTLrecord *NFTLs[MAX_NFTLS];
static void NFTL_setup(struct mtd_info *mtd)
@@ -150,9 +140,7 @@ static void NFTL_setup(struct mtd_info *mtd)
gd->major = MAJOR_NR;
gd->first_minor = firstfree << NFTL_PARTN_BITS;
gd->minor_shift = NFTL_PARTN_BITS;
- gd->part = part_table + (firstfree << NFTL_PARTN_BITS);
gd->major_name = name;
- gd->nr_real = 1;
nftl->disk = gd;
add_gendisk(gd);
register_disk(gd, mk_kdev(MAJOR_NR,firstfree<<NFTL_PARTN_BITS),
@@ -847,10 +835,10 @@ void nftl_request(RQFUNC_ARG)
down(&nftl->mutex);
DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n");
- if (block + nsect > part_table[dev].nr_sects) {
+ if (block + nsect > get_capacity(nftl->disk)) {
/* access past the end of device */
printk("nftl%c%d: bad access: block = %d, count = %d\n",
- (minor(req->rq_dev)>>6)+'a', dev & 0xf, block, nsect);
+ unit+'a', dev & 0xf, block, nsect);
up(&nftl->mutex);
res = 0; /* fail */
goto repeat;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 060b94008a15..6460e5f08eda 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -128,6 +128,13 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
if (!dev) /* It's a host bus, nothing to read */
return;
+ if (dev->transparent) {
+ printk("Transparent bridge - %s\n", dev->name);
+ for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++)
+ child->resource[i] = child->parent->resource[i];
+ return;
+ }
+
for(i=0; i<3; i++)
child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
@@ -149,13 +156,6 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
res->start = base;
res->end = limit + 0xfff;
- } else {
- /*
- * Ugh. We don't know enough about this bridge. Just assume
- * that it's entirely transparent.
- */
- printk(KERN_ERR "Unknown bridge resource %d: assuming transparent\n", 0);
- child->resource[0] = child->parent->resource[0];
}
res = child->resource[1];
@@ -167,10 +167,6 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
res->start = base;
res->end = limit + 0xfffff;
- } else {
- /* See comment above. Same thing */
- printk(KERN_ERR "Unknown bridge resource %d: assuming transparent\n", 1);
- child->resource[1] = child->parent->resource[1];
}
res = child->resource[2];
@@ -197,10 +193,6 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
res->start = base;
res->end = limit + 0xfffff;
- } else {
- /* See comments above */
- printk(KERN_ERR "Unknown bridge resource %d: assuming transparent\n", 2);
- child->resource[2] = child->parent->resource[2];
}
}
@@ -389,6 +381,10 @@ int pci_setup_device(struct pci_dev * dev)
case PCI_HEADER_TYPE_BRIDGE: /* bridge header */
if (class != PCI_CLASS_BRIDGE_PCI)
goto bad;
+ /* The PCI-to-PCI bridge spec requires that subtractive
+ decoding (i.e. transparent) bridge must have programming
+ interface code of 0x01. */
+ dev->transparent = ((class & 0xff) == 1);
pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
break;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index e66a3237f252..43aea3183d77 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -471,6 +471,11 @@ static void __init quirk_dunord ( struct pci_dev * dev )
r -> end = 0xffffff;
}
+static void __init quirk_transparent_bridge(struct pci_dev *dev)
+{
+ dev->transparent = 1;
+}
+
/*
* The main table of quirks.
*/
@@ -525,6 +530,13 @@ static struct pci_fixup pci_fixups[] __initdata = {
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering },
+ /*
+ * i82380FB mobile docking controller: its PCI-to-PCI bridge
+ * is subtractive decoding (transparent), and does indicate this
+ * in the ProgIf. Unfortunately, the ProgIf value is wrong - 0x80
+ * instead of 0x01.
+ */
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82380FB, quirk_transparent_bridge },
{ 0 }
};
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 33efcd5717e9..da3eb2e5f5cc 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -73,7 +73,7 @@ static int pci_assign_bus_resource(const struct pci_bus *bus,
int i;
type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
- for (i = 0 ; i < 4; i++) {
+ for (i = 0 ; i < PCI_BUS_NUM_RESOURCES; i++) {
struct resource *r = bus->resource[i];
if (!r)
continue;
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 8f7670f944ed..422e6e6e9d3c 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -302,7 +302,7 @@ dasd_state_new_to_known(dasd_device_t *device)
/* Add a proc directory and the dasd device entry to devfs. */
sprintf(buffer, "%04x", device->devinfo.devno);
dir = devfs_mk_dir(dasd_devfs_handle, buffer, device);
- gdp->de_arr[0] = dir;
+ gdp->de = dir;
if (devmap->features & DASD_FEATURE_READONLY)
devfs_perm = S_IFBLK | S_IRUSR;
else
@@ -328,7 +328,7 @@ dasd_state_known_to_new(dasd_device_t * device)
return;
/* Remove device entry and devfs directory. */
devfs_unregister(device->devfs_entry);
- devfs_unregister(gdp->de_arr[0]);
+ devfs_unregister(gdp->de);
/* Forget the discipline information. */
device->discipline = NULL;
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 5733d3f466f5..6df129445724 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -34,10 +34,7 @@ struct major_info {
struct list_head list;
int major;
struct gendisk disks[DASD_PER_MAJOR];
- devfs_handle_t de_arr[DASD_PER_MAJOR];
- char flags[DASD_PER_MAJOR];
char names[DASD_PER_MAJOR * 8];
- struct hd_struct part[1<<MINORBITS];
};
/*
@@ -106,11 +103,8 @@ dasd_register_major(int major)
disk->major = new_major;
disk->first_minor = i << DASD_PARTN_BITS;
disk->minor_shift = DASD_PARTN_BITS;
- disk->nr_real = 1;
disk->fops = &dasd_device_operations;
- disk->de_arr = mi->de_arr + i;
- disk->flags = mi->flags + i;
- disk->part = mi->part + (i << DASD_PARTN_BITS);
+ disk->flags = GENHD_FL_DEVFS;
}
/* Setup block device pointers for the new major. */
@@ -284,14 +278,6 @@ dasd_destroy_partitions(dasd_device_t * device)
if (disk == NULL)
return;
- wipe_partitions(device->kdev);
-
- /*
- * This is confusing. The funcions is devfs_register_partitions
- * but the 1 as third parameter makes it do an unregister...
- * FIXME: there must be a better way to get rid of the devfs entries
- */
- devfs_register_partitions(disk, minor(device->kdev), 1);
del_gendisk(disk);
}
diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
index 6ae15e45a619..f5900895fc93 100644
--- a/drivers/scsi/qlogicfc.c
+++ b/drivers/scsi/qlogicfc.c
@@ -1342,18 +1342,11 @@ int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *))
num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
num_free = (num_free > 2) ? num_free - 2 : 0;
- host->can_queue = hostdata->queued + num_free;
+ host->can_queue = host->host_busy + num_free;
if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN)
host->can_queue = QLOGICFC_REQ_QUEUE_LEN;
host->sg_tablesize = QLOGICFC_MAX_SG(num_free);
- /* this is really gross */
- if (host->can_queue <= host->host_busy){
- if (host->can_queue+2 < host->host_busy)
- DEBUG(printk("qlogicfc%d.c crosses its fingers.\n", hostdata->host_id));
- host->can_queue = host->host_busy + 1;
- }
-
LEAVE("isp2x00_queuecommand");
return 0;
@@ -1623,17 +1616,11 @@ void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
num_free = (num_free > 2) ? num_free - 2 : 0;
- host->can_queue = hostdata->queued + num_free;
+ host->can_queue = host->host_busy + num_free;
if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN)
host->can_queue = QLOGICFC_REQ_QUEUE_LEN;
host->sg_tablesize = QLOGICFC_MAX_SG(num_free);
- if (host->can_queue <= host->host_busy){
- if (host->can_queue+2 < host->host_busy)
- DEBUG(printk("qlogicfc%d : crosses its fingers.\n", hostdata->host_id));
- host->can_queue = host->host_busy + 1;
- }
-
outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
LEAVE_INTR("isp2x00_intr_handler");
}
diff --git a/drivers/scsi/qlogicfc.h b/drivers/scsi/qlogicfc.h
index e67e9f5af274..a2b54f43256c 100644
--- a/drivers/scsi/qlogicfc.h
+++ b/drivers/scsi/qlogicfc.h
@@ -65,7 +65,7 @@
#define DATASEGS_PER_COMMAND 2
#define DATASEGS_PER_CONT 5
-#define QLOGICFC_REQ_QUEUE_LEN 127 /* must be power of two - 1 */
+#define QLOGICFC_REQ_QUEUE_LEN 255 /* must be power of two - 1 */
#define QLOGICFC_MAX_SG(ql) (DATASEGS_PER_COMMAND + (((ql) > 0) ? DATASEGS_PER_CONT*((ql) - 1) : 0))
#define QLOGICFC_CMD_PER_LUN 8
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 9cdfbbe27d0e..96d8d8c1c017 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -84,9 +84,6 @@
#define SD_DSK_ARR_LUMP 6 /* amount to over allocate sd_dsk_arr by */
-
-struct hd_struct *sd;
-
static Scsi_Disk ** sd_dsk_arr;
static rwlock_t sd_dsk_arr_lock = RW_LOCK_UNLOCKED;
@@ -126,8 +123,6 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt);
static Scsi_Disk * sd_get_sdisk(int index);
-extern void driverfs_remove_partitions(struct gendisk *hd, int minor);
-
#if defined(CONFIG_PPC32)
/**
* sd_find_target - find kdev_t of first scsi disk that matches
@@ -288,6 +283,8 @@ static request_queue_t *sd_find_queue(kdev_t dev)
return NULL; /* No such device */
}
+static struct gendisk **sd_disks;
+
/**
* sd_init_command - build a scsi (read or write) command from
* information in the request structure.
@@ -323,7 +320,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
/* >>>>> this change is not in the lk 2.5 series */
if (part_nr >= (sd_template.dev_max << 4) || (part_nr & 0xf) ||
!sdp || !sdp->online ||
- block + SCpnt->request->nr_sectors > sd[part_nr].nr_sects) {
+ block + SCpnt->request->nr_sectors > get_capacity(sd_disks[dsk_nr])) {
SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n",
SCpnt->request->nr_sectors));
SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
@@ -590,8 +587,6 @@ static struct block_device_operations sd_fops =
revalidate: sd_revalidate
};
-static struct gendisk **sd_disks;
-
/**
* sd_rw_intr - bottom half handler: called when the lower level
* driver has completed (successfully or otherwise) a scsi command.
@@ -1207,12 +1202,10 @@ static int sd_init()
init_mem_lth(sd_disks, sd_template.dev_max);
if (sd_disks)
zero_mem_lth(sd_disks, sd_template.dev_max);
- init_mem_lth(sd, maxparts);
- if (!sd_dsk_arr || !sd || !sd_disks)
+ if (!sd_dsk_arr || !sd_disks)
goto cleanup_mem;
- zero_mem_lth(sd, maxparts);
return 0;
#undef init_mem_lth
@@ -1221,8 +1214,6 @@ static int sd_init()
cleanup_mem:
vfree(sd_disks);
sd_disks = NULL;
- vfree(sd);
- sd = NULL;
if (sd_dsk_arr) {
for (k = 0; k < sd_template.dev_max; ++k)
vfree(sd_dsk_arr[k]);
@@ -1312,9 +1303,6 @@ static int sd_attach(Scsi_Device * sdp)
unsigned long iflags;
struct {
struct gendisk disk;
- devfs_handle_t de;
- struct device *dev;
- char flags;
char name[5];
} *p;
struct gendisk *gd;
@@ -1327,9 +1315,6 @@ static int sd_attach(Scsi_Device * sdp)
if (!p)
return 1;
gd = &p->disk;
- gd->de_arr = &p->de;
- gd->flags = &p->flags;
- gd->driverfs_dev_arr = &p->dev;
SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n",
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun));
@@ -1361,21 +1346,19 @@ static int sd_attach(Scsi_Device * sdp)
}
sd_template.nr_dev++;
- gd->nr_real = 1;
- gd->de_arr[0] = sdp->de;
- gd->driverfs_dev_arr[0] = &sdp->sdev_driverfs_dev;
+ gd->de = sdp->de;
gd->major = SD_MAJOR(dsk_nr>>4);
gd->first_minor = (dsk_nr & 15)<<4;
gd->minor_shift = 4;
- gd->part = sd + (dsk_nr << 4);
gd->fops = &sd_fops;
if (dsk_nr > 26)
sprintf(p->name, "sd%c%c", 'a'+dsk_nr/26-1, 'a'+dsk_nr%26);
else
sprintf(p->name, "sd%c", 'a'+dsk_nr%26);
gd->major_name = p->name;
- if (sdp->removable)
- gd->flags[0] |= GENHD_FL_REMOVABLE;
+ gd->flags = sdp->removable ? GENHD_FL_REMOVABLE : 0;
+ gd->driverfs_dev = &sdp->sdev_driverfs_dev;
+ gd->flags |= GENHD_FL_DRIVERFS | GENHD_FL_DEVFS;
sd_disks[dsk_nr] = gd;
sd_dskname(dsk_nr, diskname);
printk(KERN_NOTICE "Attached scsi %sdisk %s at scsi%d, channel %d, "
@@ -1393,7 +1376,7 @@ static int sd_revalidate(kdev_t dev)
return -ENODEV;
sd_init_onedisk(sdkp, dsk_nr);
- sd_disks[dsk_nr]->part[0].nr_sects = sdkp->capacity;
+ set_capacity(sd_disks[dsk_nr], sdkp->capacity);
return 0;
}
@@ -1435,10 +1418,6 @@ static void sd_detach(Scsi_Device * sdp)
if (sdkp->has_been_registered) {
sdkp->has_been_registered = 0;
dev = MKDEV_SD(dsk_nr);
- driverfs_remove_partitions(sd_disks[dsk_nr], minor(dev));
- wipe_partitions(dev);
- devfs_register_partitions (sd_disks[dsk_nr], minor(dev), 1);
- /* unregister_disk() */
del_gendisk(sd_disks[dsk_nr]);
}
sdp->attached--;
@@ -1488,7 +1467,6 @@ static void __exit exit_sd(void)
vfree(sd_dsk_arr[k]);
vfree(sd_dsk_arr);
}
- vfree((char *) sd);
for (k = 0; k < N_USED_SD_MAJORS; k++) {
blk_dev[SD_MAJOR(k)].queue = NULL;
blk_clear(SD_MAJOR(k));
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index e3eb4be41a26..5ba16cfec18c 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -20,8 +20,6 @@
#include <linux/genhd.h>
#endif
-extern struct hd_struct *sd;
-
typedef struct scsi_disk {
unsigned capacity; /* size in 512-byte sectors */
Scsi_Device *device;
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 6be5cdac0797..4e68f16b14e7 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -87,25 +87,24 @@ static struct Scsi_Device_Template sr_template =
init_command:sr_init_command
};
-Scsi_CD *scsi_CDs;
-static int *sr_sizes;
+static Scsi_CD *scsi_CDs;
static int sr_open(struct cdrom_device_info *, int);
-void get_sectorsize(int);
-void get_capabilities(int);
+static void get_sectorsize(Scsi_CD *);
+static void get_capabilities(Scsi_CD *);
static int sr_media_change(struct cdrom_device_info *, int);
static int sr_packet(struct cdrom_device_info *, struct cdrom_generic_command *);
static void sr_release(struct cdrom_device_info *cdi)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
- if (SCp->device->sector_size > 2048)
- sr_set_blocklength(minor(cdi->dev), 2048);
- SCp->device->access_count--;
- if (SCp->device->host->hostt->module)
- __MOD_DEC_USE_COUNT(SCp->device->host->hostt->module);
+ if (cd->device->sector_size > 2048)
+ sr_set_blocklength(cd, 2048);
+ cd->device->access_count--;
+ if (cd->device->host->hostt->module)
+ __MOD_DEC_USE_COUNT(cd->device->host->hostt->module);
if (sr_template.module)
__MOD_DEC_USE_COUNT(sr_template.module);
}
@@ -146,7 +145,7 @@ static struct cdrom_device_ops sr_dops =
int sr_media_change(struct cdrom_device_info *cdi, int slot)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
int retval;
if (CDSL_CURRENT != slot) {
@@ -154,19 +153,19 @@ int sr_media_change(struct cdrom_device_info *cdi, int slot)
return -EINVAL;
}
- retval = scsi_ioctl(SCp->device, SCSI_IOCTL_TEST_UNIT_READY, 0);
+ retval = scsi_ioctl(cd->device, SCSI_IOCTL_TEST_UNIT_READY, 0);
if (retval) {
/* Unable to test, unit probably not ready. This usually
* means there is no disc in the drive. Mark as changed,
* and we will figure it out later once the drive is
* available again. */
- SCp->device->changed = 1;
+ cd->device->changed = 1;
return 1; /* This will force a flush, if called from
* check_disk_change */
};
- retval = SCp->device->changed;
- SCp->device->changed = 0;
+ retval = cd->device->changed;
+ cd->device->changed = 0;
/* If the disk changed, the capacity will now be different,
* so we force a re-read of this information */
if (retval) {
@@ -180,8 +179,8 @@ int sr_media_change(struct cdrom_device_info *cdi, int slot)
* be trying to use something that is too small if the disc
* has changed.
*/
- SCp->needs_sector_size = 1;
- SCp->device->sector_size = 2048;
+ cd->needs_sector_size = 1;
+ cd->device->sector_size = 2048;
}
return retval;
}
@@ -198,7 +197,7 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
int good_sectors = (result == 0 ? this_count : 0);
int block_sectors = 0;
int device_nr = DEVICE_NR(SCpnt->request->rq_dev);
- Scsi_CD *SCp = &scsi_CDs[device_nr];
+ Scsi_CD *cd = &scsi_CDs[device_nr];
#ifdef DEBUG
printk("sr.c done: %x %p\n", result, SCpnt->request->bh->b_data);
@@ -223,7 +222,7 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
block_sectors = bio_sectors(SCpnt->request->bio);
if (block_sectors < 4)
block_sectors = 4;
- if (SCp->device->sector_size == 2048)
+ if (cd->device->sector_size == 2048)
error_sector <<= 2;
error_sector &= ~(block_sectors - 1);
good_sectors = error_sector - SCpnt->request->sector;
@@ -235,9 +234,9 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
* block. Therefore, if we hit a medium error within the last
* 75 2K sectors, we decrease the saved size value.
*/
- if ((error_sector >> 1) < sr_sizes[device_nr] &&
- SCp->capacity - error_sector < 4 * 75)
- sr_sizes[device_nr] = error_sector >> 1;
+ if (error_sector < get_capacity(cd->disk) &&
+ cd->capacity - error_sector < 4 * 75)
+ set_capacity(cd->disk, error_sector);
}
/*
@@ -251,34 +250,34 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
static request_queue_t *sr_find_queue(kdev_t dev)
{
- Scsi_CD *SCp;
+ Scsi_CD *cd;
if (minor(dev) >= sr_template.dev_max)
return NULL;
- SCp = &scsi_CDs[minor(dev)];
- if (!SCp->device)
+ cd = &scsi_CDs[minor(dev)];
+ if (!cd->device)
return NULL;
- return &SCp->device->request_queue;
+ return &cd->device->request_queue;
}
static int sr_init_command(Scsi_Cmnd * SCpnt)
{
int dev, devm, block=0, this_count, s_size;
- Scsi_CD *SCp;
+ Scsi_CD *cd;
devm = minor(SCpnt->request->rq_dev);
dev = DEVICE_NR(SCpnt->request->rq_dev);
- SCp = &scsi_CDs[dev];
+ cd = &scsi_CDs[dev];
SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %d, block = %d\n", devm, block));
- if (dev >= sr_template.nr_dev || !SCp->device || !SCp->device->online) {
+ if (dev >= sr_template.nr_dev || !cd->device || !cd->device->online) {
SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", SCpnt->request->nr_sectors));
SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
return 0;
}
- if (SCp->device->changed) {
+ if (cd->device->changed) {
/*
* quietly refuse to do anything to a changed disc until the
* changed bit has been reset
@@ -295,10 +294,10 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
* we do lazy blocksize switching (when reading XA sectors,
* see CDROMREADMODE2 ioctl)
*/
- s_size = SCp->device->sector_size;
+ s_size = cd->device->sector_size;
if (s_size > 2048) {
if (!in_interrupt())
- sr_set_blocklength(DEVICE_NR(CURRENT->rq_dev), 2048);
+ sr_set_blocklength(cd, 2048);
else
printk("sr: can't switch blocksize: in interrupt\n");
}
@@ -309,7 +308,7 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
}
if (rq_data_dir(SCpnt->request) == WRITE) {
- if (!SCp->device->writeable)
+ if (!cd->device->writeable)
return 0;
SCpnt->cmnd[0] = WRITE_10;
SCpnt->sc_data_direction = SCSI_DATA_WRITE;
@@ -332,8 +331,8 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9);
- SCSI_LOG_HLQUEUE(2, printk("sr%d : %s %d/%ld 512 byte blocks.\n",
- devm,
+ SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n",
+ cd->cdi.name,
(rq_data_dir(SCpnt->request) == WRITE) ? "writing" : "reading",
this_count, SCpnt->request->nr_sectors));
@@ -358,7 +357,7 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
* host adapter, it's safe to assume that we can at least transfer
* this many bytes between each connect / disconnect.
*/
- SCpnt->transfersize = SCp->device->sector_size;
+ SCpnt->transfersize = cd->device->sector_size;
SCpnt->underflow = this_count << 9;
SCpnt->allowed = MAX_RETRIES;
@@ -400,21 +399,20 @@ struct block_device_operations sr_bdops =
static int sr_open(struct cdrom_device_info *cdi, int purpose)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
- if (minor(cdi->dev) >= sr_template.dev_max || !SCp->device) {
+ if (!cd->device)
return -ENXIO; /* No such device */
- }
/*
* If the device is in error recovery, wait until it is done.
* If the device is offline, then disallow any access to it.
*/
- if (!scsi_block_when_processing_errors(SCp->device)) {
+ if (!scsi_block_when_processing_errors(cd->device)) {
return -ENXIO;
}
- SCp->device->access_count++;
- if (SCp->device->host->hostt->module)
- __MOD_INC_USE_COUNT(SCp->device->host->hostt->module);
+ cd->device->access_count++;
+ if (cd->device->host->hostt->module)
+ __MOD_INC_USE_COUNT(cd->device->host->hostt->module);
if (sr_template.module)
__MOD_INC_USE_COUNT(sr_template.module);
@@ -423,8 +421,8 @@ static int sr_open(struct cdrom_device_info *cdi, int purpose)
* this is the case, and try again.
*/
- if (SCp->needs_sector_size)
- get_sectorsize(minor(cdi->dev));
+ if (cd->needs_sector_size)
+ get_sectorsize(cd);
return 0;
}
@@ -464,35 +462,32 @@ static int sr_attach(Scsi_Device * SDp)
if (sr_template.nr_dev > sr_template.dev_max)
panic("scsi_devices corrupt (sr)");
- printk("Attached scsi CD-ROM sr%d at scsi%d, channel %d, id %d, lun %d\n",
- i, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
+ printk("Attached scsi CD-ROM %s at scsi%d, channel %d, id %d, lun %d\n",
+ scsi_CDs[i].cdi.name, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
return 0;
}
-void get_sectorsize(int i)
+static void get_sectorsize(Scsi_CD *cd)
{
unsigned char cmd[10];
unsigned char *buffer;
int the_result, retries = 3;
int sector_size;
Scsi_Request *SRpnt = NULL;
- Scsi_CD *SCp;
request_queue_t *queue;
- SCp = &scsi_CDs[i];
-
buffer = kmalloc(512, GFP_DMA);
if (!buffer)
goto Enomem;
- SRpnt = scsi_allocate_request(SCp->device);
+ SRpnt = scsi_allocate_request(cd->device);
if (!SRpnt)
goto Enomem;
do {
cmd[0] = READ_CAPACITY;
- cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- ((SCp->device->lun << 5) & 0xe0) : 0;
+ cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ ((cd->device->lun << 5) & 0xe0) : 0;
memset((void *) &cmd[2], 0, 8);
SRpnt->sr_request->rq_status = RQ_SCSI_BUSY; /* Mark as really busy */
SRpnt->sr_cmd_len = 0;
@@ -515,15 +510,15 @@ void get_sectorsize(int i)
SRpnt = NULL;
if (the_result) {
- SCp->capacity = 0x1fffff;
+ cd->capacity = 0x1fffff;
sector_size = 2048; /* A guess, just in case */
- SCp->needs_sector_size = 1;
+ cd->needs_sector_size = 1;
} else {
#if 0
- if (cdrom_get_last_written(&SCp->cdi,
- &SCp->capacity))
+ if (cdrom_get_last_written(&cd->cdi,
+ &cd->capacity))
#endif
- SCp->capacity = 1 + ((buffer[0] << 24) |
+ cd->capacity = 1 + ((buffer[0] << 24) |
(buffer[1] << 16) |
(buffer[2] << 8) |
buffer[3]);
@@ -542,45 +537,44 @@ void get_sectorsize(int i)
sector_size = 2048;
/* fall through */
case 2048:
- SCp->capacity *= 4;
+ cd->capacity *= 4;
/* fall through */
case 512:
break;
default:
- printk("sr%d: unsupported sector size %d.\n",
- i, sector_size);
- SCp->capacity = 0;
- SCp->needs_sector_size = 1;
+ printk("%s: unsupported sector size %d.\n",
+ cd->cdi.name, sector_size);
+ cd->capacity = 0;
+ cd->needs_sector_size = 1;
}
- SCp->device->sector_size = sector_size;
+ cd->device->sector_size = sector_size;
/*
* Add this so that we have the ability to correctly gauge
* what the device is capable of.
*/
- SCp->needs_sector_size = 0;
- sr_sizes[i] = SCp->capacity >> (BLOCK_SIZE_BITS - 9);
+ cd->needs_sector_size = 0;
+ set_capacity(cd->disk, cd->capacity);
}
- queue = &SCp->device->request_queue;
+ queue = &cd->device->request_queue;
blk_queue_hardsect_size(queue, sector_size);
out:
kfree(buffer);
return;
Enomem:
- SCp->capacity = 0x1fffff;
+ cd->capacity = 0x1fffff;
sector_size = 2048; /* A guess, just in case */
- SCp->needs_sector_size = 1;
+ cd->needs_sector_size = 1;
if (SRpnt)
scsi_release_request(SRpnt);
goto out;
}
-void get_capabilities(int i)
+void get_capabilities(Scsi_CD *cd)
{
- Scsi_CD *SCp;
unsigned char cmd[6];
unsigned char *buffer;
int rc, n;
@@ -597,7 +591,6 @@ void get_capabilities(int i)
""
};
- SCp = &scsi_CDs[i];
buffer = kmalloc(512, GFP_DMA);
if (!buffer)
{
@@ -605,31 +598,31 @@ void get_capabilities(int i)
return;
}
cmd[0] = MODE_SENSE;
- cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- ((SCp->device->lun << 5) & 0xe0) : 0;
+ cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ ((cd->device->lun << 5) & 0xe0) : 0;
cmd[2] = 0x2a;
cmd[4] = 128;
cmd[3] = cmd[5] = 0;
- rc = sr_do_ioctl(i, cmd, buffer, 128, 1, SCSI_DATA_READ, NULL);
+ rc = sr_do_ioctl(cd, cmd, buffer, 128, 1, SCSI_DATA_READ, NULL);
if (rc) {
/* failed, drive doesn't have capabilities mode page */
- SCp->cdi.speed = 1;
- SCp->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
+ cd->cdi.speed = 1;
+ cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
CDC_DVD | CDC_DVD_RAM |
CDC_SELECT_DISC | CDC_SELECT_SPEED);
kfree(buffer);
- printk("sr%i: scsi-1 drive\n", i);
+ printk("%s: scsi-1 drive\n", cd->cdi.name);
return;
}
n = buffer[3] + 4;
- SCp->cdi.speed = ((buffer[n + 8] << 8) + buffer[n + 9]) / 176;
- SCp->readcd_known = 1;
- SCp->readcd_cdda = buffer[n + 5] & 0x01;
+ cd->cdi.speed = ((buffer[n + 8] << 8) + buffer[n + 9]) / 176;
+ cd->readcd_known = 1;
+ cd->readcd_cdda = buffer[n + 5] & 0x01;
/* print some capability bits */
- printk("sr%i: scsi3-mmc drive: %dx/%dx %s%s%s%s%s%s\n", i,
+ printk("%s: scsi3-mmc drive: %dx/%dx %s%s%s%s%s%s\n", cd->cdi.name,
((buffer[n + 14] << 8) + buffer[n + 15]) / 176,
- SCp->cdi.speed,
+ cd->cdi.speed,
buffer[n + 3] & 0x01 ? "writer " : "", /* CD Writer */
buffer[n + 3] & 0x20 ? "dvd-ram " : "",
buffer[n + 2] & 0x02 ? "cd/rw " : "", /* can read rewriteable */
@@ -638,38 +631,38 @@ void get_capabilities(int i)
loadmech[buffer[n + 6] >> 5]);
if ((buffer[n + 6] >> 5) == 0)
/* caddy drives can't close tray... */
- SCp->cdi.mask |= CDC_CLOSE_TRAY;
+ cd->cdi.mask |= CDC_CLOSE_TRAY;
if ((buffer[n + 2] & 0x8) == 0)
/* not a DVD drive */
- SCp->cdi.mask |= CDC_DVD;
+ cd->cdi.mask |= CDC_DVD;
if ((buffer[n + 3] & 0x20) == 0) {
/* can't write DVD-RAM media */
- SCp->cdi.mask |= CDC_DVD_RAM;
+ cd->cdi.mask |= CDC_DVD_RAM;
} else {
- SCp->device->writeable = 1;
+ cd->device->writeable = 1;
}
if ((buffer[n + 3] & 0x10) == 0)
/* can't write DVD-R media */
- SCp->cdi.mask |= CDC_DVD_R;
+ cd->cdi.mask |= CDC_DVD_R;
if ((buffer[n + 3] & 0x2) == 0)
/* can't write CD-RW media */
- SCp->cdi.mask |= CDC_CD_RW;
+ cd->cdi.mask |= CDC_CD_RW;
if ((buffer[n + 3] & 0x1) == 0)
/* can't write CD-R media */
- SCp->cdi.mask |= CDC_CD_R;
+ cd->cdi.mask |= CDC_CD_R;
if ((buffer[n + 6] & 0x8) == 0)
/* can't eject */
- SCp->cdi.mask |= CDC_OPEN_TRAY;
+ cd->cdi.mask |= CDC_OPEN_TRAY;
if ((buffer[n + 6] >> 5) == mechtype_individual_changer ||
(buffer[n + 6] >> 5) == mechtype_cartridge_changer)
- SCp->cdi.capacity =
- cdrom_number_of_slots(&SCp->cdi);
- if (SCp->cdi.capacity <= 1)
+ cd->cdi.capacity =
+ cdrom_number_of_slots(&cd->cdi);
+ if (cd->cdi.capacity <= 1)
/* not a changer */
- SCp->cdi.mask |= CDC_SELECT_DISC;
+ cd->cdi.mask |= CDC_SELECT_DISC;
/*else I don't think it can close its tray
- SCp->cdi.mask |= CDC_CLOSE_TRAY; */
+ cd->cdi.mask |= CDC_CLOSE_TRAY; */
kfree(buffer);
}
@@ -680,14 +673,14 @@ void get_capabilities(int i)
*/
static int sr_packet(struct cdrom_device_info *cdi, struct cdrom_generic_command *cgc)
{
- Scsi_CD *SCp = cdi->handle;
- Scsi_Device *device = SCp->device;
+ Scsi_CD *cd = cdi->handle;
+ Scsi_Device *device = cd->device;
/* set the LUN */
if (device->scsi_level <= SCSI_2)
cgc->cmd[1] |= device->lun << 5;
- cgc->stat = sr_do_ioctl(minor(cdi->dev), cgc->cmd, cgc->buffer, cgc->buflen, cgc->quiet, cgc->data_direction, cgc->sense);
+ cgc->stat = sr_do_ioctl(cdi->handle, cgc->cmd, cgc->buffer, cgc->buflen, cgc->quiet, cgc->data_direction, cgc->sense);
return cgc->stat;
}
@@ -696,6 +689,7 @@ static int sr_registered;
static int sr_init()
{
+ int i;
if (sr_template.dev_noticed == 0)
return 0;
@@ -714,15 +708,10 @@ static int sr_init()
if (!scsi_CDs)
goto cleanup_dev;
memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD));
-
- sr_sizes = kmalloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC);
- if (!sr_sizes)
- goto cleanup_cds;
- memset(sr_sizes, 0, sr_template.dev_max * sizeof(int));
+ for (i = 0; i < sr_template.dev_max; i++)
+ sprintf(scsi_CDs[i].cdi.name, "sr%d", i);
return 0;
-cleanup_cds:
- kfree(scsi_CDs);
cleanup_dev:
unregister_blkdev(MAJOR_NR, "sr");
sr_registered--;
@@ -750,67 +739,80 @@ static DEVICE_ATTR(type,S_IRUGO,sr_device_type_read,NULL);
void sr_finish()
{
int i;
- char name[6];
blk_dev[MAJOR_NR].queue = sr_find_queue;
- blk_size[MAJOR_NR] = sr_sizes;
for (i = 0; i < sr_template.nr_dev; ++i) {
- Scsi_CD *SCp = &scsi_CDs[i];
+ struct gendisk *disk;
+ Scsi_CD *cd = &scsi_CDs[i];
/* If we have already seen this, then skip it. Comes up
* with loadable modules. */
- if (SCp->capacity)
+ if (cd->disk)
+ continue;
+ disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
+ if (!disk)
continue;
- SCp->capacity = 0x1fffff;
- SCp->device->sector_size = 2048;/* A guess, just in case */
- SCp->needs_sector_size = 1;
- SCp->device->changed = 1; /* force recheck CD type */
+ if (cd->disk) {
+ kfree(disk);
+ continue;
+ }
+ memset(disk, 0, sizeof(struct gendisk));
+ disk->major = MAJOR_NR;
+ disk->first_minor = i;
+ disk->minor_shift = 0;
+ disk->major_name = cd->cdi.name;
+ disk->fops = &sr_bdops;
+ cd->disk = disk;
+ cd->capacity = 0x1fffff;
+ cd->device->sector_size = 2048;/* A guess, just in case */
+ cd->needs_sector_size = 1;
+ cd->device->changed = 1; /* force recheck CD type */
#if 0
/* seems better to leave this for later */
- get_sectorsize(i);
- printk("Scd sectorsize = %d bytes.\n", SCp->sector_size);
+ get_sectorsize(cd);
+ printk("Scd sectorsize = %d bytes.\n", cd->sector_size);
#endif
- SCp->use = 1;
-
- SCp->device->ten = 1;
- SCp->device->remap = 1;
- SCp->readcd_known = 0;
- SCp->readcd_cdda = 0;
- sr_sizes[i] = SCp->capacity >> (BLOCK_SIZE_BITS - 9);
-
- SCp->cdi.ops = &sr_dops;
- SCp->cdi.handle = SCp;
- SCp->cdi.dev = mk_kdev(MAJOR_NR, i);
- SCp->cdi.mask = 0;
- SCp->cdi.capacity = 1;
+ cd->use = 1;
+
+ cd->device->ten = 1;
+ cd->device->remap = 1;
+ cd->readcd_known = 0;
+ cd->readcd_cdda = 0;
+
+ cd->cdi.ops = &sr_dops;
+ cd->cdi.handle = cd;
+ cd->cdi.dev = mk_kdev(MAJOR_NR, i);
+ cd->cdi.mask = 0;
+ cd->cdi.capacity = 1;
/*
* FIXME: someone needs to handle a get_capabilities
* failure properly ??
*/
- get_capabilities(i);
- sr_vendor_init(SCp);
-
- sprintf(name, "sr%d", i);
- strcpy(SCp->cdi.name, name);
- sprintf(SCp->cdi.cdrom_driverfs_dev.bus_id, "%s:cd",
- SCp->device->sdev_driverfs_dev.bus_id);
- sprintf(SCp->cdi.cdrom_driverfs_dev.name, "%scdrom",
- SCp->device->sdev_driverfs_dev.name);
- SCp->cdi.cdrom_driverfs_dev.parent =
- &SCp->device->sdev_driverfs_dev;
- SCp->cdi.cdrom_driverfs_dev.bus = &scsi_driverfs_bus_type;
- SCp->cdi.cdrom_driverfs_dev.driver_data =
+ get_capabilities(cd);
+ sr_vendor_init(cd);
+
+ sprintf(cd->cdi.cdrom_driverfs_dev.bus_id, "%s:cd",
+ cd->device->sdev_driverfs_dev.bus_id);
+ sprintf(cd->cdi.cdrom_driverfs_dev.name, "%scdrom",
+ cd->device->sdev_driverfs_dev.name);
+ cd->cdi.cdrom_driverfs_dev.parent =
+ &cd->device->sdev_driverfs_dev;
+ cd->cdi.cdrom_driverfs_dev.bus = &scsi_driverfs_bus_type;
+ cd->cdi.cdrom_driverfs_dev.driver_data =
(void *)(long)__mkdev(MAJOR_NR, i);
- device_register(&SCp->cdi.cdrom_driverfs_dev);
- device_create_file(&SCp->cdi.cdrom_driverfs_dev,
+ device_register(&cd->cdi.cdrom_driverfs_dev);
+ device_create_file(&cd->cdi.cdrom_driverfs_dev,
&dev_attr_type);
- device_create_file(&SCp->cdi.cdrom_driverfs_dev,
+ device_create_file(&cd->cdi.cdrom_driverfs_dev,
&dev_attr_kdev);
- SCp->cdi.de = devfs_register(SCp->device->de, "cd",
+ cd->cdi.de = devfs_register(cd->device->de, "cd",
DEVFS_FL_DEFAULT, MAJOR_NR, i,
S_IFBLK | S_IRUGO | S_IWUGO,
&sr_bdops, NULL);
- register_cdrom(&SCp->cdi);
+ register_cdrom(&cd->cdi);
+ add_gendisk(disk);
+ register_disk(disk, mk_kdev(disk->major, disk->first_minor),
+ 1<<disk->minor_shift, disk->fops, cd->capacity);
}
}
@@ -826,7 +828,9 @@ static void sr_detach(Scsi_Device * SDp)
* the device.
* We should be kind to our buffer cache, however.
*/
- invalidate_device(mk_kdev(MAJOR_NR, i), 0);
+ del_gendisk(cpnt->disk);
+ kfree(cpnt->disk);
+ cpnt->disk = NULL;
/*
* Reset things back to a sane state so that one can
@@ -838,7 +842,6 @@ static void sr_detach(Scsi_Device * SDp)
SDp->attached--;
sr_template.nr_dev--;
sr_template.dev_noticed--;
- sr_sizes[i] = 0;
return;
}
}
@@ -861,12 +864,8 @@ static void __exit exit_sr(void)
scsi_unregister_device(&sr_template);
unregister_blkdev(MAJOR_NR, "sr");
sr_registered--;
- if (scsi_CDs != NULL) {
+ if (scsi_CDs != NULL)
kfree(scsi_CDs);
-
- kfree(sr_sizes);
- sr_sizes = NULL;
- }
blk_clear(MAJOR_NR);
sr_template.dev_max = 0;
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h
index e4ac7cb2265d..3c3ec7165690 100644
--- a/drivers/scsi/sr.h
+++ b/drivers/scsi/sr.h
@@ -18,6 +18,7 @@
#define _SR_H
#include "scsi.h"
+#include <linux/genhd.h>
typedef struct {
unsigned capacity; /* size in blocks */
@@ -30,11 +31,10 @@ typedef struct {
unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */
unsigned readcd_cdda:1; /* reading audio data using READ_CD */
struct cdrom_device_info cdi;
+ struct gendisk *disk;
} Scsi_CD;
-extern Scsi_CD *scsi_CDs;
-
-int sr_do_ioctl(int, unsigned char *, void *, unsigned, int, int, struct request_sense *);
+int sr_do_ioctl(Scsi_CD *, unsigned char *, void *, unsigned, int, int, struct request_sense *);
int sr_lock_door(struct cdrom_device_info *, int);
int sr_tray_move(struct cdrom_device_info *, int);
@@ -47,12 +47,11 @@ int sr_select_speed(struct cdrom_device_info *cdi, int speed);
int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *);
int sr_dev_ioctl(struct cdrom_device_info *, unsigned int, unsigned long);
-int sr_read_sector(int minor, int lba, int blksize, unsigned char *dest);
-int sr_is_xa(int minor);
+int sr_is_xa(Scsi_CD *);
/* sr_vendor.c */
void sr_vendor_init(Scsi_CD *);
int sr_cd_check(struct cdrom_device_info *);
-int sr_set_blocklength(int minor, int blocklength);
+int sr_set_blocklength(Scsi_CD *, int blocklength);
#endif
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index 85ba7a66a237..f6a54e77bc66 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -24,8 +24,6 @@
* It is off by default and can be turned on with this module parameter */
static int xa_test = 0;
-extern void get_sectorsize(int);
-
#define IOCTL_RETRIES 3
/* The CDROM is fairly slow, so we need a little extra time */
/* In fact, it is very slow if it has to spin up first */
@@ -69,14 +67,14 @@ static int sr_fake_playtrkind(struct cdrom_device_info *cdi, struct cdrom_ti *ti
sr_cmd[6] = trk1_te.cdte_addr.msf.minute;
sr_cmd[7] = trk1_te.cdte_addr.msf.second;
sr_cmd[8] = trk1_te.cdte_addr.msf.frame;
- return sr_do_ioctl(minor(cdi->dev), sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL);
+ return sr_do_ioctl(cdi->handle, sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL);
}
/* We do our own retries because we want to know what the specific
error code is. Normally the UNIT_ATTENTION code will automatically
clear after one error */
-int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflength, int quiet, int readwrite, struct request_sense *sense)
+int sr_do_ioctl(Scsi_CD *cd, unsigned char *sr_cmd, void *buffer, unsigned buflength, int quiet, int readwrite, struct request_sense *sense)
{
Scsi_Request *SRpnt;
Scsi_Device *SDev;
@@ -84,7 +82,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
int result, err = 0, retries = 0;
char *bounce_buffer;
- SDev = scsi_CDs[target].device;
+ SDev = cd->device;
SRpnt = scsi_allocate_request(SDev);
if (!SRpnt) {
printk("Unable to allocate SCSI request in sr_do_ioctl");
@@ -127,7 +125,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
case UNIT_ATTENTION:
SDev->changed = 1;
if (!quiet)
- printk(KERN_INFO "sr%d: disc change detected.\n", target);
+ printk(KERN_INFO "%s: disc change detected.\n", cd->cdi.name);
if (retries++ < 10)
goto retry;
err = -ENOMEDIUM;
@@ -137,7 +135,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
SRpnt->sr_sense_buffer[13] == 0x01) {
/* sense: Logical unit is in process of becoming ready */
if (!quiet)
- printk(KERN_INFO "sr%d: CDROM not ready yet.\n", target);
+ printk(KERN_INFO "%s: CDROM not ready yet.\n", cd->cdi.name);
if (retries++ < 10) {
/* sleep 2 sec and try again */
scsi_sleep(2 * HZ);
@@ -149,7 +147,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
}
}
if (!quiet)
- printk(KERN_INFO "sr%d: CDROM not ready. Make sure there is a disc in the drive.\n", target);
+ printk(KERN_INFO "%s: CDROM not ready. Make sure there is a disc in the drive.\n", cd->cdi.name);
#ifdef DEBUG
print_req_sense("sr", SRpnt);
#endif
@@ -157,8 +155,8 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
break;
case ILLEGAL_REQUEST:
if (!quiet)
- printk(KERN_ERR "sr%d: CDROM (ioctl) reports ILLEGAL "
- "REQUEST.\n", target);
+ printk(KERN_ERR "%s: CDROM (ioctl) reports ILLEGAL "
+ "REQUEST.\n", cd->cdi.name);
if (SRpnt->sr_sense_buffer[12] == 0x20 &&
SRpnt->sr_sense_buffer[13] == 0x00) {
/* sense: Invalid command operation code */
@@ -172,7 +170,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
#endif
break;
default:
- printk(KERN_ERR "sr%d: CDROM (ioctl) error, command: ", target);
+ printk(KERN_ERR "%s: CDROM (ioctl) error, command: ", cd->cdi.name);
print_command(sr_cmd);
print_req_sense("sr", SRpnt);
err = -EIO;
@@ -191,38 +189,36 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
/* ---------------------------------------------------------------------- */
/* interface to cdrom.c */
-static int test_unit_ready(int minor)
+static int test_unit_ready(Scsi_CD *cd)
{
- Scsi_CD *SCp;
u_char sr_cmd[10];
- SCp = &scsi_CDs[minor];
sr_cmd[0] = GPCMD_TEST_UNIT_READY;
- sr_cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- ((SCp->device->lun) << 5) : 0;
+ sr_cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ ((cd->device->lun) << 5) : 0;
sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
- return sr_do_ioctl(minor, sr_cmd, NULL, 0, 1, SCSI_DATA_NONE, NULL);
+ return sr_do_ioctl(cd, sr_cmd, NULL, 0, 1, SCSI_DATA_NONE, NULL);
}
int sr_tray_move(struct cdrom_device_info *cdi, int pos)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
u_char sr_cmd[10];
sr_cmd[0] = GPCMD_START_STOP_UNIT;
- sr_cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- ((SCp->device->lun) << 5) : 0;
+ sr_cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ ((cd->device->lun) << 5) : 0;
sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
sr_cmd[4] = (pos == 0) ? 0x03 /* close */ : 0x02 /* eject */ ;
- return sr_do_ioctl(minor(cdi->dev), sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL);
+ return sr_do_ioctl(cd, sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL);
}
int sr_lock_door(struct cdrom_device_info *cdi, int lock)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
- return scsi_ioctl(SCp->device, lock ? SCSI_IOCTL_DOORLOCK :
+ return scsi_ioctl(cd->device, lock ? SCSI_IOCTL_DOORLOCK :
SCSI_IOCTL_DOORUNLOCK, 0);
}
@@ -232,7 +228,7 @@ int sr_drive_status(struct cdrom_device_info *cdi, int slot)
/* we have no changer support */
return -EINVAL;
}
- if (0 == test_unit_ready(minor(cdi->dev)))
+ if (0 == test_unit_ready(cdi->handle))
return CDS_DISC_OK;
return CDS_TRAY_OPEN;
@@ -240,7 +236,7 @@ int sr_drive_status(struct cdrom_device_info *cdi, int slot)
int sr_disk_status(struct cdrom_device_info *cdi)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
struct cdrom_tochdr toc_h;
struct cdrom_tocentry toc_e;
int i, rc, have_datatracks = 0;
@@ -262,7 +258,7 @@ int sr_disk_status(struct cdrom_device_info *cdi)
if (!have_datatracks)
return CDS_AUDIO;
- if (SCp->xa_flag)
+ if (cd->xa_flag)
return CDS_XA_2_1;
else
return CDS_DATA_1;
@@ -271,24 +267,24 @@ int sr_disk_status(struct cdrom_device_info *cdi)
int sr_get_last_session(struct cdrom_device_info *cdi,
struct cdrom_multisession *ms_info)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
- ms_info->addr.lba = SCp->ms_offset;
- ms_info->xa_flag = SCp->xa_flag || SCp->ms_offset > 0;
+ ms_info->addr.lba = cd->ms_offset;
+ ms_info->xa_flag = cd->xa_flag || cd->ms_offset > 0;
return 0;
}
int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
u_char sr_cmd[10];
char buffer[32];
int result;
sr_cmd[0] = GPCMD_READ_SUBCHANNEL;
- sr_cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- ((SCp->device->lun) << 5) : 0;
+ sr_cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ ((cd->device->lun) << 5) : 0;
sr_cmd[2] = 0x40; /* I do want the subchannel info */
sr_cmd[3] = 0x02; /* Give me medium catalog number info */
sr_cmd[4] = sr_cmd[5] = 0;
@@ -297,7 +293,7 @@ int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
sr_cmd[8] = 24;
sr_cmd[9] = 0;
- result = sr_do_ioctl(minor(cdi->dev), sr_cmd, buffer, 24, 0, SCSI_DATA_READ, NULL);
+ result = sr_do_ioctl(cd, sr_cmd, buffer, 24, 0, SCSI_DATA_READ, NULL);
memcpy(mcn->medium_catalog_number, buffer + 9, 13);
mcn->medium_catalog_number[13] = 0;
@@ -307,13 +303,12 @@ int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
int sr_reset(struct cdrom_device_info *cdi)
{
- invalidate_buffers(cdi->dev);
return 0;
}
int sr_select_speed(struct cdrom_device_info *cdi, int speed)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
u_char sr_cmd[MAX_COMMAND_SIZE];
if (speed == 0)
@@ -323,12 +318,12 @@ int sr_select_speed(struct cdrom_device_info *cdi, int speed)
memset(sr_cmd, 0, MAX_COMMAND_SIZE);
sr_cmd[0] = GPCMD_SET_SPEED; /* SET CD SPEED */
- sr_cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- ((SCp->device->lun) << 5) : 0;
+ sr_cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ ((cd->device->lun) << 5) : 0;
sr_cmd[2] = (speed >> 8) & 0xff; /* MSB for speed (in kbytes/sec) */
sr_cmd[3] = speed & 0xff; /* LSB */
- if (sr_do_ioctl(minor(cdi->dev), sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL))
+ if (sr_do_ioctl(cd, sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL))
return -EIO;
return 0;
}
@@ -341,9 +336,9 @@ int sr_select_speed(struct cdrom_device_info *cdi, int speed)
int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
u_char sr_cmd[10];
- int result, target = minor(cdi->dev);
+ int result;
unsigned char buffer[32];
memset(sr_cmd, 0, sizeof(sr_cmd));
@@ -354,12 +349,12 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg;
sr_cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
- sr_cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- ((SCp->device->lun) << 5) : 0;
+ sr_cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ ((cd->device->lun) << 5) : 0;
sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
sr_cmd[8] = 12; /* LSB of length */
- result = sr_do_ioctl(target, sr_cmd, buffer, 12, 1, SCSI_DATA_READ, NULL);
+ result = sr_do_ioctl(cd, sr_cmd, buffer, 12, 1, SCSI_DATA_READ, NULL);
tochdr->cdth_trk0 = buffer[2];
tochdr->cdth_trk1 = buffer[3];
@@ -372,14 +367,14 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
struct cdrom_tocentry *tocentry = (struct cdrom_tocentry *) arg;
sr_cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
- sr_cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- ((SCp->device->lun) << 5) : 0;
+ sr_cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ ((cd->device->lun) << 5) : 0;
sr_cmd[1] |= (tocentry->cdte_format == CDROM_MSF) ? 0x02 : 0;
sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
sr_cmd[6] = tocentry->cdte_track;
sr_cmd[8] = 12; /* LSB of length */
- result = sr_do_ioctl(target, sr_cmd, buffer, 12, 0, SCSI_DATA_READ, NULL);
+ result = sr_do_ioctl(cd, sr_cmd, buffer, 12, 0, SCSI_DATA_READ, NULL);
tocentry->cdte_ctrl = buffer[5] & 0xf;
tocentry->cdte_adr = buffer[5] >> 4;
@@ -399,14 +394,14 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
struct cdrom_ti* ti = (struct cdrom_ti*)arg;
sr_cmd[0] = GPCMD_PLAYAUDIO_TI;
- sr_cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- (SCp->device->lun << 5) : 0;
+ sr_cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ (cd->device->lun << 5) : 0;
sr_cmd[4] = ti->cdti_trk0;
sr_cmd[5] = ti->cdti_ind0;
sr_cmd[7] = ti->cdti_trk1;
sr_cmd[8] = ti->cdti_ind1;
- result = sr_do_ioctl(target, sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL);
+ result = sr_do_ioctl(cd, sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL);
if (result == -EDRIVE_CANT_DO_THIS)
result = sr_fake_playtrkind(cdi, ti);
@@ -439,20 +434,19 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
* blksize: 2048 | 2336 | 2340 | 2352
*/
-int sr_read_cd(int minor, unsigned char *dest, int lba, int format, int blksize)
+static int sr_read_cd(Scsi_CD *cd, unsigned char *dest, int lba, int format, int blksize)
{
unsigned char cmd[MAX_COMMAND_SIZE];
- Scsi_CD *SCp = &scsi_CDs[minor];
#ifdef DEBUG
- printk("sr%d: sr_read_cd lba=%d format=%d blksize=%d\n",
- minor, lba, format, blksize);
+ printk("%s: sr_read_cd lba=%d format=%d blksize=%d\n",
+ cd->cdi.name, lba, format, blksize);
#endif
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = GPCMD_READ_CD; /* READ_CD */
- cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- (SCp->device->lun << 5) : 0;
+ cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ (cd->device->lun << 5) : 0;
cmd[1] |= ((format & 7) << 2);
cmd[2] = (unsigned char) (lba >> 24) & 0xff;
cmd[3] = (unsigned char) (lba >> 16) & 0xff;
@@ -473,47 +467,46 @@ int sr_read_cd(int minor, unsigned char *dest, int lba, int format, int blksize)
cmd[9] = 0x10;
break;
}
- return sr_do_ioctl(minor, cmd, dest, blksize, 0, SCSI_DATA_READ, NULL);
+ return sr_do_ioctl(cd, cmd, dest, blksize, 0, SCSI_DATA_READ, NULL);
}
/*
* read sectors with blocksizes other than 2048
*/
-int sr_read_sector(int minor, int lba, int blksize, unsigned char *dest)
+static int sr_read_sector(Scsi_CD *cd, int lba, int blksize, unsigned char *dest)
{
unsigned char cmd[MAX_COMMAND_SIZE]; /* the scsi-command */
- Scsi_CD *SCp = &scsi_CDs[minor];
int rc;
/* we try the READ CD command first... */
- if (SCp->readcd_known) {
- rc = sr_read_cd(minor, dest, lba, 0, blksize);
+ if (cd->readcd_known) {
+ rc = sr_read_cd(cd, dest, lba, 0, blksize);
if (-EDRIVE_CANT_DO_THIS != rc)
return rc;
- SCp->readcd_known = 0;
+ cd->readcd_known = 0;
printk("CDROM does'nt support READ CD (0xbe) command\n");
/* fall & retry the other way */
}
/* ... if this fails, we switch the blocksize using MODE SELECT */
- if (blksize != SCp->device->sector_size) {
- if (0 != (rc = sr_set_blocklength(minor, blksize)))
+ if (blksize != cd->device->sector_size) {
+ if (0 != (rc = sr_set_blocklength(cd, blksize)))
return rc;
}
#ifdef DEBUG
- printk("sr%d: sr_read_sector lba=%d blksize=%d\n", minor, lba, blksize);
+ printk("%s: sr_read_sector lba=%d blksize=%d\n", cd->cdi.name, lba, blksize);
#endif
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = GPCMD_READ_10;
- cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- (SCp->device->lun << 5) : 0;
+ cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ (cd->device->lun << 5) : 0;
cmd[2] = (unsigned char) (lba >> 24) & 0xff;
cmd[3] = (unsigned char) (lba >> 16) & 0xff;
cmd[4] = (unsigned char) (lba >> 8) & 0xff;
cmd[5] = (unsigned char) lba & 0xff;
cmd[8] = 1;
- rc = sr_do_ioctl(minor, cmd, dest, blksize, 0, SCSI_DATA_READ, NULL);
+ rc = sr_do_ioctl(cd, cmd, dest, blksize, 0, SCSI_DATA_READ, NULL);
return rc;
}
@@ -523,10 +516,9 @@ int sr_read_sector(int minor, int lba, int blksize, unsigned char *dest)
* ret: 1 == mode2 (XA), 0 == mode1, <0 == error
*/
-int sr_is_xa(int minor)
+int sr_is_xa(Scsi_CD *cd)
{
unsigned char *raw_sector;
- Scsi_CD *SCp = &scsi_CDs[minor];
int is_xa;
if (!xa_test)
@@ -535,7 +527,7 @@ int sr_is_xa(int minor)
raw_sector = (unsigned char *) kmalloc(2048, GFP_DMA | GFP_KERNEL);
if (!raw_sector)
return -ENOMEM;
- if (0 == sr_read_sector(minor, SCp->ms_offset + 16,
+ if (0 == sr_read_sector(cd, cd->ms_offset + 16,
CD_FRAMESIZE_RAW1, raw_sector)) {
is_xa = (raw_sector[3] == 0x02) ? 1 : 0;
} else {
@@ -544,7 +536,7 @@ int sr_is_xa(int minor)
}
kfree(raw_sector);
#ifdef DEBUG
- printk("sr%d: sr_is_xa: %d\n", minor, is_xa);
+ printk("%s: sr_is_xa: %d\n", cd->cdi.name, is_xa);
#endif
return is_xa;
}
@@ -552,16 +544,16 @@ int sr_is_xa(int minor)
int sr_dev_ioctl(struct cdrom_device_info *cdi,
unsigned int cmd, unsigned long arg)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
switch (cmd) {
case BLKGETSIZE:
- return put_user(SCp->capacity, (unsigned long *) arg);
+ return put_user(cd->capacity, (unsigned long *) arg);
case BLKGETSIZE64:
- return put_user((u64)SCp->capacity << 9, (u64 *)arg);
+ return put_user((u64)cd->capacity << 9, (u64 *)arg);
default:
- return scsi_ioctl(SCp->device, cmd, (void *)arg);
+ return scsi_ioctl(cd->device, cmd, (void *)arg);
}
}
diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c
index 9733ae387f65..b7000df8b520 100644
--- a/drivers/scsi/sr_vendor.c
+++ b/drivers/scsi/sr_vendor.c
@@ -58,25 +58,25 @@
#define VENDOR_TOSHIBA 3
#define VENDOR_WRITER 4 /* pre-scsi3 writers */
-void sr_vendor_init(Scsi_CD *SCp)
+void sr_vendor_init(Scsi_CD *cd)
{
#ifndef CONFIG_BLK_DEV_SR_VENDOR
- SCp->vendor = VENDOR_SCSI3;
+ cd->vendor = VENDOR_SCSI3;
#else
- char *vendor = SCp->device->vendor;
- char *model = SCp->device->model;
+ char *vendor = cd->device->vendor;
+ char *model = cd->device->model;
/* default */
- SCp->vendor = VENDOR_SCSI3;
- if (SCp->readcd_known)
+ cd->vendor = VENDOR_SCSI3;
+ if (cd->readcd_known)
/* this is true for scsi3/mmc drives - no more checks */
return;
- if (SCp->device->type == TYPE_WORM) {
- SCp->vendor = VENDOR_WRITER;
+ if (cd->device->type == TYPE_WORM) {
+ cd->vendor = VENDOR_WRITER;
} else if (!strncmp(vendor, "NEC", 3)) {
- SCp->vendor = VENDOR_NEC;
+ cd->vendor = VENDOR_NEC;
if (!strncmp(model, "CD-ROM DRIVE:25", 15) ||
!strncmp(model, "CD-ROM DRIVE:36", 15) ||
!strncmp(model, "CD-ROM DRIVE:83", 15) ||
@@ -88,10 +88,10 @@ void sr_vendor_init(Scsi_CD *SCp)
#endif
)
/* these can't handle multisession, may hang */
- SCp->cdi.mask |= CDC_MULTI_SESSION;
+ cd->cdi.mask |= CDC_MULTI_SESSION;
} else if (!strncmp(vendor, "TOSHIBA", 7)) {
- SCp->vendor = VENDOR_TOSHIBA;
+ cd->vendor = VENDOR_TOSHIBA;
}
#endif
@@ -101,16 +101,15 @@ void sr_vendor_init(Scsi_CD *SCp)
/* small handy function for switching block length using MODE SELECT,
* used by sr_read_sector() */
-int sr_set_blocklength(int minor, int blocklength)
+int sr_set_blocklength(Scsi_CD *cd, int blocklength)
{
unsigned char *buffer; /* the buffer for the ioctl */
unsigned char cmd[MAX_COMMAND_SIZE]; /* the scsi-command */
struct ccs_modesel_head *modesel;
- Scsi_CD *SCp = &scsi_CDs[minor];
int rc, density = 0;
#ifdef CONFIG_BLK_DEV_SR_VENDOR
- if (SCp->vendor == VENDOR_TOSHIBA)
+ if (cd->vendor == VENDOR_TOSHIBA)
density = (blocklength > 2048) ? 0x81 : 0x83;
#endif
@@ -119,12 +118,12 @@ int sr_set_blocklength(int minor, int blocklength)
return -ENOMEM;
#ifdef DEBUG
- printk("sr%d: MODE SELECT 0x%x/%d\n", minor, density, blocklength);
+ printk("%s: MODE SELECT 0x%x/%d\n", cd->cdi.name, density, blocklength);
#endif
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = MODE_SELECT;
- cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- (SCp->device->lun << 5) : 0;
+ cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ (cd->device->lun << 5) : 0;
cmd[1] |= (1 << 4);
cmd[4] = 12;
modesel = (struct ccs_modesel_head *) buffer;
@@ -133,13 +132,13 @@ int sr_set_blocklength(int minor, int blocklength)
modesel->density = density;
modesel->block_length_med = (blocklength >> 8) & 0xff;
modesel->block_length_lo = blocklength & 0xff;
- if (0 == (rc = sr_do_ioctl(minor, cmd, buffer, sizeof(*modesel), 0, SCSI_DATA_WRITE, NULL))) {
- SCp->device->sector_size = blocklength;
+ if (0 == (rc = sr_do_ioctl(cd, cmd, buffer, sizeof(*modesel), 0, SCSI_DATA_WRITE, NULL))) {
+ cd->device->sector_size = blocklength;
}
#ifdef DEBUG
else
- printk("sr%d: switching blocklength to %d bytes failed\n",
- minor, blocklength);
+ printk("%s: switching blocklength to %d bytes failed\n",
+ cd->cdi.name, blocklength);
#endif
kfree(buffer);
return rc;
@@ -152,14 +151,13 @@ int sr_set_blocklength(int minor, int blocklength)
int sr_cd_check(struct cdrom_device_info *cdi)
{
- Scsi_CD *SCp = cdi->handle;
+ Scsi_CD *cd = cdi->handle;
unsigned long sector;
unsigned char *buffer; /* the buffer for the ioctl */
unsigned char cmd[MAX_COMMAND_SIZE]; /* the scsi-command */
- int rc, no_multi, minor;
+ int rc, no_multi;
- minor = minor(cdi->dev);
- if (SCp->cdi.mask & CDC_MULTI_SESSION)
+ if (cd->cdi.mask & CDC_MULTI_SESSION)
return 0;
buffer = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA);
@@ -170,21 +168,21 @@ int sr_cd_check(struct cdrom_device_info *cdi)
no_multi = 0; /* flag: the drive can't handle multisession */
rc = 0;
- switch (SCp->vendor) {
+ switch (cd->vendor) {
case VENDOR_SCSI3:
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = READ_TOC;
- cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- (SCp->device->lun << 5) : 0;
+ cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ (cd->device->lun << 5) : 0;
cmd[8] = 12;
cmd[9] = 0x40;
- rc = sr_do_ioctl(minor, cmd, buffer, 12, 1, SCSI_DATA_READ, NULL);
+ rc = sr_do_ioctl(cd, cmd, buffer, 12, 1, SCSI_DATA_READ, NULL);
if (rc != 0)
break;
if ((buffer[0] << 8) + buffer[1] < 0x0a) {
- printk(KERN_INFO "sr%d: Hmm, seems the drive "
- "doesn't support multisession CD's\n", minor);
+ printk(KERN_INFO "%s: Hmm, seems the drive "
+ "doesn't support multisession CD's\n", cd->cdi.name);
no_multi = 1;
break;
}
@@ -201,16 +199,17 @@ int sr_cd_check(struct cdrom_device_info *cdi)
unsigned long min, sec, frame;
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = 0xde;
- cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- (SCp->device->lun << 5) : 0;
+ cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ (cd->device->lun << 5) : 0;
cmd[1] |= 0x03;
cmd[2] = 0xb0;
- rc = sr_do_ioctl(minor, cmd, buffer, 0x16, 1, SCSI_DATA_READ, NULL);
+ rc = sr_do_ioctl(cd, cmd, buffer, 0x16, 1, SCSI_DATA_READ, NULL);
if (rc != 0)
break;
if (buffer[14] != 0 && buffer[14] != 0xb0) {
- printk(KERN_INFO "sr%d: Hmm, seems the cdrom "
- "doesn't support multisession CD's\n", minor);
+ printk(KERN_INFO "%s: Hmm, seems the cdrom "
+ "doesn't support multisession CD's\n",
+ cd->cdi.name);
no_multi = 1;
break;
}
@@ -228,13 +227,14 @@ int sr_cd_check(struct cdrom_device_info *cdi)
* where starts the last session ?) */
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = 0xc7;
- cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- (SCp->device->lun << 5) : 0;
+ cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ (cd->device->lun << 5) : 0;
cmd[1] |= 0x03;
- rc = sr_do_ioctl(minor, cmd, buffer, 4, 1, SCSI_DATA_READ, NULL);
+ rc = sr_do_ioctl(cd, cmd, buffer, 4, 1, SCSI_DATA_READ, NULL);
if (rc == -EINVAL) {
- printk(KERN_INFO "sr%d: Hmm, seems the drive "
- "doesn't support multisession CD's\n", minor);
+ printk(KERN_INFO "%s: Hmm, seems the drive "
+ "doesn't support multisession CD's\n",
+ cd->cdi.name);
no_multi = 1;
break;
}
@@ -246,33 +246,33 @@ int sr_cd_check(struct cdrom_device_info *cdi)
sector = min * CD_SECS * CD_FRAMES + sec * CD_FRAMES + frame;
if (sector)
sector -= CD_MSF_OFFSET;
- sr_set_blocklength(minor, 2048);
+ sr_set_blocklength(cd, 2048);
break;
}
case VENDOR_WRITER:
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = READ_TOC;
- cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- (SCp->device->lun << 5) : 0;
+ cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ (cd->device->lun << 5) : 0;
cmd[8] = 0x04;
cmd[9] = 0x40;
- rc = sr_do_ioctl(minor, cmd, buffer, 0x04, 1, SCSI_DATA_READ, NULL);
+ rc = sr_do_ioctl(cd, cmd, buffer, 0x04, 1, SCSI_DATA_READ, NULL);
if (rc != 0) {
break;
}
if ((rc = buffer[2]) == 0) {
printk(KERN_WARNING
- "sr%d: No finished session\n", minor);
+ "%s: No finished session\n", cd->cdi.name);
break;
}
cmd[0] = READ_TOC; /* Read TOC */
- cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
- (SCp->device->lun << 5) : 0;
+ cmd[1] = (cd->device->scsi_level <= SCSI_2) ?
+ (cd->device->lun << 5) : 0;
cmd[6] = rc & 0x7f; /* number of last session */
cmd[8] = 0x0c;
cmd[9] = 0x40;
- rc = sr_do_ioctl(minor, cmd, buffer, 12, 1, SCSI_DATA_READ, NULL);
+ rc = sr_do_ioctl(cd, cmd, buffer, 12, 1, SCSI_DATA_READ, NULL);
if (rc != 0) {
break;
}
@@ -284,27 +284,27 @@ int sr_cd_check(struct cdrom_device_info *cdi)
default:
/* should not happen */
printk(KERN_WARNING
- "sr%d: unknown vendor code (%i), not initialized ?\n",
- minor, SCp->vendor);
+ "%s: unknown vendor code (%i), not initialized ?\n",
+ cd->cdi.name, cd->vendor);
sector = 0;
no_multi = 1;
break;
}
- SCp->ms_offset = sector;
- SCp->xa_flag = 0;
- if (CDS_AUDIO != sr_disk_status(cdi) && 1 == sr_is_xa(minor))
- SCp->xa_flag = 1;
+ cd->ms_offset = sector;
+ cd->xa_flag = 0;
+ if (CDS_AUDIO != sr_disk_status(cdi) && 1 == sr_is_xa(cd))
+ cd->xa_flag = 1;
- if (2048 != SCp->device->sector_size) {
- sr_set_blocklength(minor, 2048);
+ if (2048 != cd->device->sector_size) {
+ sr_set_blocklength(cd, 2048);
}
if (no_multi)
cdi->mask |= CDC_MULTI_SESSION;
#ifdef DEBUG
if (sector)
- printk(KERN_DEBUG "sr%d: multisession offset=%lu\n",
- minor, sector);
+ printk(KERN_DEBUG "%s: multisession offset=%lu\n",
+ cd->cdi.name, sector);
#endif
kfree(buffer);
return rc;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index ffb781e46792..074e657bee0b 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -184,7 +184,7 @@ static struct Scsi_Device_Template st_template = {
static int st_compression(Scsi_Tape *, int);
static int find_partition(Scsi_Tape *);
-static int update_partition(Scsi_Tape *);
+static int switch_partition(Scsi_Tape *);
static int st_int_ioctl(Scsi_Tape *, unsigned int, unsigned long);
@@ -1028,9 +1028,9 @@ static int st_flush(struct file *filp)
}
if (STp->can_partitions &&
- (result2 = update_partition(STp)) < 0) {
+ (result2 = switch_partition(STp)) < 0) {
DEBC(printk(ST_DEB_MSG
- "st%d: update_partition at close failed.\n", dev));
+ "st%d: switch_partition at close failed.\n", dev));
if (result == 0)
result = result2;
goto out;
@@ -1206,7 +1206,7 @@ static ssize_t rw_checks(Scsi_Tape *STp, struct file *filp, size_t count, loff_t
} ) /* end DEB */
if (STp->can_partitions &&
- (retval = update_partition(STp)) < 0)
+ (retval = switch_partition(STp)) < 0)
goto out;
if (STp->block_size == 0 && STp->max_block > 0 &&
@@ -2904,7 +2904,7 @@ static int find_partition(Scsi_Tape *STp)
/* Change the partition if necessary */
-static int update_partition(Scsi_Tape *STp)
+static int switch_partition(Scsi_Tape *STp)
{
ST_partstat *STps;
@@ -3239,7 +3239,7 @@ static int st_ioctl(struct inode *inode, struct file *file,
}
if (STp->can_partitions && STp->ready == ST_READY &&
- (i = update_partition(STp)) < 0) {
+ (i = switch_partition(STp)) < 0) {
retval = i;
goto out;
}
@@ -3260,7 +3260,7 @@ static int st_ioctl(struct inode *inode, struct file *file,
goto out;
}
if (STp->can_partitions &&
- (i = update_partition(STp)) < 0) {
+ (i = switch_partition(STp)) < 0) {
retval = i;
goto out;
}
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 6568b35895e9..af200dd36b29 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -27,6 +27,7 @@
#include <linux/fs.h>
#include <linux/amigaffs.h>
#include <linux/mm.h>
+#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
@@ -518,6 +519,7 @@ affs_do_readpage_ofs(struct file *file, struct page *page, unsigned from, unsign
pr_debug("AFFS: read_page(%u, %ld, %d, %d)\n", (u32)inode->i_ino, page->index, from, to);
if (from > to || to > PAGE_CACHE_SIZE)
BUG();
+ kmap(page);
data = page_address(page);
bsize = AFFS_SB(sb)->s_data_blksize;
tmp = (page->index << PAGE_CACHE_SHIFT) + from;
@@ -537,6 +539,8 @@ affs_do_readpage_ofs(struct file *file, struct page *page, unsigned from, unsign
from += tmp;
boff = 0;
}
+ flush_dcache_page(page);
+ kunmap(page);
return 0;
}
@@ -656,7 +660,11 @@ static int affs_prepare_write_ofs(struct file *file, struct page *page, unsigned
return err;
}
if (to < PAGE_CACHE_SIZE) {
- memset(page_address(page) + to, 0, PAGE_CACHE_SIZE - to);
+ char *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
+ flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
if (size > offset + to) {
if (size < offset + PAGE_CACHE_SIZE)
tmp = size & ~PAGE_CACHE_MASK;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 56fec1317128..7d8a089a9d0a 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -503,21 +503,16 @@ int check_disk_change(struct block_device *bdev)
struct block_device_operations * bdops = bdev->bd_op;
kdev_t dev = to_kdev_t(bdev->bd_dev);
struct gendisk *disk;
- struct hd_struct *part;
if (bdops->check_media_change == NULL)
return 0;
if (!bdops->check_media_change(dev))
return 0;
- printk(KERN_DEBUG "VFS: Disk change detected on device %s\n",
- bdevname(bdev));
-
if (invalidate_device(dev, 0))
printk("VFS: busy inodes on changed media.\n");
disk = get_gendisk(dev);
- part = disk->part + minor(dev) - disk->first_minor;
if (bdops->revalidate)
bdops->revalidate(dev);
if (disk && disk->minor_shift)
@@ -527,17 +522,13 @@ int check_disk_change(struct block_device *bdev)
int full_check_disk_change(struct block_device *bdev)
{
- int res;
+ int res = 0;
+ if (bdev->bd_contains != bdev)
+ BUG();
down(&bdev->bd_sem);
- res = check_disk_change(bdev);
- if (bdev->bd_invalidated && !bdev->bd_part_count) {
- struct gendisk *g = get_gendisk(to_kdev_t(bdev->bd_dev));
- struct hd_struct *part;
- part = g->part + MINOR(bdev->bd_dev) - g->first_minor;
- bdev->bd_invalidated = 0;
- wipe_partitions(to_kdev_t(bdev->bd_dev));
- if (part[0].nr_sects)
- check_partition(g, bdev);
+ if (check_disk_change(bdev)) {
+ rescan_partitions(get_gendisk(to_kdev_t(bdev->bd_dev)), bdev);
+ res = 1;
}
up(&bdev->bd_sem);
return res;
@@ -602,8 +593,7 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
struct gendisk *g = get_gendisk(dev);
bdev->bd_contains = bdev;
if (g) {
- int shift = g->minor_shift;
- unsigned minor0 = (minor >> shift) << shift;
+ unsigned minor0 = g->first_minor;
if (minor != minor0) {
struct block_device *disk;
disk = bdget(MKDEV(major(dev), minor0));
@@ -637,11 +627,9 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
sector_t sect = 0;
bdev->bd_offset = 0;
- if (g) {
- struct hd_struct *p;
- p = g->part + minor(dev) - g->first_minor;
- sect = p->nr_sects;
- } else if (blk_size[major(dev)])
+ if (g)
+ sect = get_capacity(g);
+ else if (blk_size[major(dev)])
sect = blk_size[major(dev)][minor(dev)] << 1;
bd_set_size(bdev, (loff_t)sect << 9);
bdi = blk_get_backing_dev_info(bdev);
@@ -650,21 +638,15 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
inode->i_data.backing_dev_info = bdi;
bdev->bd_inode->i_data.backing_dev_info = bdi;
}
- if (bdev->bd_invalidated && !bdev->bd_part_count) {
- struct hd_struct *part;
- part = g->part + minor(dev) - g->first_minor;
- bdev->bd_invalidated = 0;
- wipe_partitions(dev);
- if (part[0].nr_sects)
- check_partition(g, bdev);
- }
+ if (bdev->bd_invalidated)
+ rescan_partitions(g, bdev);
} else {
down(&bdev->bd_contains->bd_sem);
bdev->bd_contains->bd_part_count++;
if (!bdev->bd_openers) {
struct gendisk *g = get_gendisk(dev);
struct hd_struct *p;
- p = g->part + minor(dev) - g->first_minor;
+ p = g->part + minor(dev) - g->first_minor - 1;
inode->i_data.backing_dev_info =
bdev->bd_inode->i_data.backing_dev_info =
bdev->bd_contains->bd_inode->i_data.backing_dev_info;
@@ -792,27 +774,15 @@ static int blkdev_reread_part(struct block_device *bdev)
{
kdev_t dev = to_kdev_t(bdev->bd_dev);
struct gendisk *disk = get_gendisk(dev);
- struct hd_struct *part;
- int res;
+ int res = 0;
- if (!disk || !disk->minor_shift)
+ if (!disk || !disk->minor_shift || bdev != bdev->bd_contains)
return -EINVAL;
- part = disk->part + minor(dev) - disk->first_minor;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (down_trylock(&bdev->bd_sem))
return -EBUSY;
- if (bdev->bd_part_count) {
- up(&bdev->bd_sem);
- return -EBUSY;
- }
- res = wipe_partitions(dev);
- if (!res) {
- if (bdev->bd_op->revalidate)
- bdev->bd_op->revalidate(dev);
- if (part[0].nr_sects)
- check_partition(disk, bdev);
- }
+ res = rescan_partitions(disk, bdev);
up(&bdev->bd_sem);
return res;
}
diff --git a/fs/buffer.c b/fs/buffer.c
index 30dec7003327..20b2874fd6d8 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1784,6 +1784,7 @@ done:
if (err == 0)
return ret;
return err;
+
recover:
/*
* ENOSPC, or some other error. We may already have added some
@@ -1795,7 +1796,8 @@ recover:
bh = head;
/* Recovery: lock and submit the mapped buffers */
do {
- if (buffer_mapped(bh)) {
+ get_bh(bh);
+ if (buffer_mapped(bh) && buffer_dirty(bh)) {
lock_buffer(bh);
mark_buffer_async_write(bh);
} else {
@@ -1805,21 +1807,21 @@ recover:
*/
clear_buffer_dirty(bh);
}
- bh = bh->b_this_page;
- } while (bh != head);
+ } while ((bh = bh->b_this_page) != head);
+ SetPageError(page);
+ BUG_ON(PageWriteback(page));
+ SetPageWriteback(page);
+ unlock_page(page);
do {
struct buffer_head *next = bh->b_this_page;
if (buffer_async_write(bh)) {
- set_buffer_uptodate(bh);
clear_buffer_dirty(bh);
submit_bh(WRITE, bh);
nr_underway++;
}
+ put_bh(bh);
bh = next;
} while (bh != head);
- BUG_ON(PageWriteback(page));
- SetPageWriteback(page);
- unlock_page(page);
goto done;
}
@@ -1831,7 +1833,6 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
int err = 0;
unsigned blocksize, bbits;
struct buffer_head *bh, *head, *wait[2], **wait_bh=wait;
- char *kaddr = kmap(page);
BUG_ON(!PageLocked(page));
BUG_ON(from > PAGE_CACHE_SIZE);
@@ -1872,13 +1873,19 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
set_buffer_uptodate(bh);
continue;
}
- if (block_end > to)
- memset(kaddr+to, 0, block_end-to);
- if (block_start < from)
- memset(kaddr+block_start,
- 0, from-block_start);
- if (block_end > to || block_start < from)
+ if (block_end > to || block_start < from) {
+ void *kaddr;
+
+ kaddr = kmap_atomic(page, KM_USER0);
+ if (block_end > to)
+ memset(kaddr+to, 0,
+ block_end-to);
+ if (block_start < from)
+ memset(kaddr+block_start,
+ 0, from-block_start);
flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
+ }
continue;
}
}
@@ -1917,10 +1924,14 @@ out:
if (block_start >= to)
break;
if (buffer_new(bh)) {
+ void *kaddr;
+
clear_buffer_new(bh);
if (buffer_uptodate(bh))
buffer_error();
+ kaddr = kmap_atomic(page, KM_USER0);
memset(kaddr+block_start, 0, bh->b_size);
+ kunmap_atomic(kaddr, KM_USER0);
set_buffer_uptodate(bh);
mark_buffer_dirty(bh);
}
@@ -2006,9 +2017,10 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
SetPageError(page);
}
if (!buffer_mapped(bh)) {
- memset(kmap(page) + i*blocksize, 0, blocksize);
+ void *kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + i * blocksize, 0, blocksize);
flush_dcache_page(page);
- kunmap(page);
+ kunmap_atomic(kaddr, KM_USER0);
set_buffer_uptodate(bh);
continue;
}
@@ -2116,7 +2128,7 @@ int cont_prepare_write(struct page *page, unsigned offset,
long status;
unsigned zerofrom;
unsigned blocksize = 1 << inode->i_blkbits;
- char *kaddr;
+ void *kaddr;
while(page->index > (pgpos = *bytes>>PAGE_CACHE_SHIFT)) {
status = -ENOMEM;
@@ -2138,12 +2150,12 @@ int cont_prepare_write(struct page *page, unsigned offset,
PAGE_CACHE_SIZE, get_block);
if (status)
goto out_unmap;
- kaddr = page_address(new_page);
+ kaddr = kmap_atomic(new_page, KM_USER0);
memset(kaddr+zerofrom, 0, PAGE_CACHE_SIZE-zerofrom);
flush_dcache_page(new_page);
+ kunmap_atomic(kaddr, KM_USER0);
__block_commit_write(inode, new_page,
zerofrom, PAGE_CACHE_SIZE);
- kunmap(new_page);
unlock_page(new_page);
page_cache_release(new_page);
}
@@ -2168,21 +2180,20 @@ int cont_prepare_write(struct page *page, unsigned offset,
status = __block_prepare_write(inode, page, zerofrom, to, get_block);
if (status)
goto out1;
- kaddr = page_address(page);
if (zerofrom < offset) {
+ kaddr = kmap_atomic(page, KM_USER0);
memset(kaddr+zerofrom, 0, offset-zerofrom);
flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
__block_commit_write(inode, page, zerofrom, offset);
}
return 0;
out1:
ClearPageUptodate(page);
- kunmap(page);
return status;
out_unmap:
ClearPageUptodate(new_page);
- kunmap(new_page);
unlock_page(new_page);
page_cache_release(new_page);
out:
@@ -2194,10 +2205,8 @@ int block_prepare_write(struct page *page, unsigned from, unsigned to,
{
struct inode *inode = page->mapping->host;
int err = __block_prepare_write(inode, page, from, to, get_block);
- if (err) {
+ if (err)
ClearPageUptodate(page);
- kunmap(page);
- }
return err;
}
@@ -2205,7 +2214,6 @@ int block_commit_write(struct page *page, unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
__block_commit_write(inode,page,from,to);
- kunmap(page);
return 0;
}
@@ -2215,7 +2223,6 @@ int generic_commit_write(struct file *file, struct page *page,
struct inode *inode = page->mapping->host;
loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
__block_commit_write(inode,page,from,to);
- kunmap(page);
if (pos > inode->i_size) {
inode->i_size = pos;
mark_inode_dirty(inode);
@@ -2232,6 +2239,7 @@ int block_truncate_page(struct address_space *mapping,
struct inode *inode = mapping->host;
struct page *page;
struct buffer_head *bh;
+ void *kaddr;
int err;
blocksize = 1 << inode->i_blkbits;
@@ -2284,9 +2292,10 @@ int block_truncate_page(struct address_space *mapping,
goto unlock;
}
- memset(kmap(page) + offset, 0, length);
+ kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + offset, 0, length);
flush_dcache_page(page);
- kunmap(page);
+ kunmap_atomic(kaddr, KM_USER0);
mark_buffer_dirty(bh);
err = 0;
@@ -2306,7 +2315,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block)
struct inode * const inode = page->mapping->host;
const unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
unsigned offset;
- char *kaddr;
+ void *kaddr;
/* Is the page fully inside i_size? */
if (page->index < end_index)
@@ -2326,10 +2335,10 @@ int block_write_full_page(struct page *page, get_block_t *get_block)
* the page size, the remaining memory is zeroed when mapped, and
* writes to that region are not written out to the file."
*/
- kaddr = kmap(page);
+ kaddr = kmap_atomic(page, KM_USER0);
memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
flush_dcache_page(page);
- kunmap(page);
+ kunmap_atomic(kaddr, KM_USER0);
return __block_write_full_page(inode, page, get_block);
}
diff --git a/fs/driverfs/inode.c b/fs/driverfs/inode.c
index af41d842ef96..e91db32c1cbd 100644
--- a/fs/driverfs/inode.c
+++ b/fs/driverfs/inode.c
@@ -59,9 +59,11 @@ static int mount_count = 0;
static int driverfs_readpage(struct file *file, struct page * page)
{
if (!PageUptodate(page)) {
- memset(kmap(page), 0, PAGE_CACHE_SIZE);
- kunmap(page);
+ void *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr, 0, PAGE_CACHE_SIZE);
flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
SetPageUptodate(page);
}
unlock_page(page);
@@ -70,10 +72,12 @@ static int driverfs_readpage(struct file *file, struct page * page)
static int driverfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
{
- void *addr = kmap(page);
if (!PageUptodate(page)) {
- memset(addr, 0, PAGE_CACHE_SIZE);
+ void *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr, 0, PAGE_CACHE_SIZE);
flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
SetPageUptodate(page);
}
return 0;
@@ -85,7 +89,6 @@ static int driverfs_commit_write(struct file *file, struct page *page, unsigned
loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
set_page_dirty(page);
- kunmap(page);
if (pos > inode->i_size)
inode->i_size = pos;
return 0;
diff --git a/fs/exec.c b/fs/exec.c
index 769380e3899a..9344e1ec3894 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -504,6 +504,8 @@ static inline int make_private_signals(void)
{
struct signal_struct * newsig;
+ remove_thread_group(current, current->sig);
+
if (atomic_read(&current->sig->count) <= 1)
return 0;
newsig = kmem_cache_alloc(sigact_cachep, GFP_KERNEL);
@@ -512,6 +514,8 @@ static inline int make_private_signals(void)
spin_lock_init(&newsig->siglock);
atomic_set(&newsig->count, 1);
memcpy(newsig->action, current->sig->action, sizeof(newsig->action));
+ init_sigpending(&newsig->shared_pending);
+
spin_lock_irq(&current->sigmask_lock);
current->sig = newsig;
spin_unlock_irq(&current->sigmask_lock);
@@ -575,42 +579,10 @@ static inline void flush_old_files(struct files_struct * files)
*/
static void de_thread(struct task_struct *tsk)
{
- struct task_struct *sub;
- struct list_head *head, *ptr;
- struct siginfo info;
- int pause;
-
- write_lock_irq(&tasklist_lock);
-
- if (tsk->tgid != tsk->pid) {
- /* subsidiary thread - just escapes the group */
- list_del_init(&tsk->thread_group);
- tsk->tgid = tsk->pid;
- pause = 0;
- }
- else {
- /* master thread - kill all subsidiary threads */
- info.si_signo = SIGKILL;
- info.si_errno = 0;
- info.si_code = SI_DETHREAD;
- info.si_pid = current->pid;
- info.si_uid = current->uid;
-
- head = tsk->thread_group.next;
- list_del_init(&tsk->thread_group);
-
- list_for_each(ptr,head) {
- sub = list_entry(ptr,struct task_struct,thread_group);
- send_sig_info(SIGKILL,&info,sub);
- }
-
- pause = 1;
- }
-
- write_unlock_irq(&tasklist_lock);
-
- /* give the subsidiary threads a chance to clean themselves up */
- if (pause) yield();
+ if (!list_empty(&tsk->thread_group))
+ BUG();
+ /* An exec() starts a new thread group: */
+ tsk->tgid = tsk->pid;
}
int flush_old_exec(struct linux_binprm * bprm)
@@ -633,6 +605,8 @@ int flush_old_exec(struct linux_binprm * bprm)
if (retval) goto mmap_failed;
/* This is the point of no return */
+ de_thread(current);
+
release_old_signals(oldsig);
current->sas_ss_sp = current->sas_ss_size = 0;
@@ -651,9 +625,6 @@ int flush_old_exec(struct linux_binprm * bprm)
flush_thread();
- if (!list_empty(&current->thread_group))
- de_thread(current);
-
if (bprm->e_uid != current->euid || bprm->e_gid != current->egid ||
permission(bprm->file->f_dentry->d_inode,MAY_READ))
current->mm->dumpable = 0;
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 1260a599e83a..b0a69d186471 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -571,8 +571,8 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
struct page *page = grab_cache_page(mapping, 0);
unsigned chunk_size = ext2_chunk_size(inode);
struct ext2_dir_entry_2 * de;
- char *base;
int err;
+ void *kaddr;
if (!page)
return -ENOMEM;
@@ -581,22 +581,21 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
unlock_page(page);
goto fail;
}
- base = page_address(page);
-
- de = (struct ext2_dir_entry_2 *) base;
+ kaddr = kmap_atomic(page, KM_USER0);
+ de = (struct ext2_dir_entry_2 *)kaddr;
de->name_len = 1;
de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
memcpy (de->name, ".\0\0", 4);
de->inode = cpu_to_le32(inode->i_ino);
ext2_set_de_type (de, inode);
- de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1));
+ de = (struct ext2_dir_entry_2 *)(kaddr + EXT2_DIR_REC_LEN(1));
de->name_len = 2;
de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
de->inode = cpu_to_le32(parent->i_ino);
memcpy (de->name, "..\0", 4);
ext2_set_de_type (de, inode);
-
+ kunmap_atomic(kaddr, KM_USER0);
err = ext2_commit_chunk(page, 0, chunk_size);
fail:
page_cache_release(page);
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index d7c0b7030a6e..38e3decdae39 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1082,16 +1082,6 @@ static int ext3_prepare_write(struct file *file, struct page *page,
if (ext3_should_journal_data(inode)) {
ret = walk_page_buffers(handle, page_buffers(page),
from, to, NULL, do_journal_get_write_access);
- if (ret) {
- /*
- * We're going to fail this prepare_write(),
- * so commit_write() will not be called.
- * We need to undo block_prepare_write()'s kmap().
- * AKPM: Do we need to clear PageUptodate? I don't
- * think so.
- */
- kunmap(page);
- }
}
prepare_write_failed:
if (ret)
@@ -1151,7 +1141,6 @@ static int ext3_commit_write(struct file *file, struct page *page,
from, to, &partial, commit_write_fn);
if (!partial)
SetPageUptodate(page);
- kunmap(page);
if (pos > inode->i_size)
inode->i_size = pos;
EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
@@ -1162,17 +1151,8 @@ static int ext3_commit_write(struct file *file, struct page *page,
}
/* Be careful here if generic_commit_write becomes a
* required invocation after block_prepare_write. */
- if (ret == 0) {
+ if (ret == 0)
ret = generic_commit_write(file, page, from, to);
- } else {
- /*
- * block_prepare_write() was called, but we're not
- * going to call generic_commit_write(). So we
- * need to perform generic_commit_write()'s kunmap
- * by hand.
- */
- kunmap(page);
- }
}
if (inode->i_size > EXT3_I(inode)->i_disksize) {
EXT3_I(inode)->i_disksize = inode->i_size;
@@ -1535,6 +1515,7 @@ static int ext3_block_truncate_page(handle_t *handle,
struct page *page;
struct buffer_head *bh;
int err;
+ void *kaddr;
blocksize = inode->i_sb->s_blocksize;
length = offset & (blocksize - 1);
@@ -1590,10 +1571,11 @@ static int ext3_block_truncate_page(handle_t *handle,
if (err)
goto unlock;
}
-
- memset(kmap(page) + offset, 0, length);
+
+ kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + offset, 0, length);
flush_dcache_page(page);
- kunmap(page);
+ kunmap_atomic(kaddr, KM_USER0);
BUFFER_TRACE(bh, "zeroed end of block");
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 898cf3e1d940..79a5576740c5 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -982,11 +982,24 @@ static int fat_readpage(struct file *file, struct page *page)
{
return block_read_full_page(page,fat_get_block);
}
-static int fat_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+
+static int
+fat_prepare_write(struct file *file, struct page *page,
+ unsigned from, unsigned to)
{
+ kmap(page);
return cont_prepare_write(page,from,to,fat_get_block,
&MSDOS_I(page->mapping->host)->mmu_private);
}
+
+static int
+fat_commit_write(struct file *file, struct page *page,
+ unsigned from, unsigned to)
+{
+ kunmap(page);
+ return generic_commit_write(file, page, from, to);
+}
+
static int _fat_bmap(struct address_space *mapping, long block)
{
return generic_block_bmap(mapping,block,fat_get_block);
@@ -996,7 +1009,7 @@ static struct address_space_operations fat_aops = {
writepage: fat_writepage,
sync_page: block_sync_page,
prepare_write: fat_prepare_write,
- commit_write: generic_commit_write,
+ commit_write: fat_commit_write,
bmap: _fat_bmap
};
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index aca27e701f64..a9711a7fefae 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -47,6 +47,7 @@
#include <linux/stat.h>
#include <linux/blkdev.h>
#include <linux/quotaops.h>
+#include <linux/highmem.h>
#include <linux/smp_lock.h>
#include <asm/semaphore.h>
#include <asm/byteorder.h>
@@ -751,7 +752,6 @@ jffs_do_readpage_nolock(struct file *file, struct page *page)
get_page(page);
/* Don't SetPageLocked(page), should be locked already */
- buf = page_address(page);
ClearPageUptodate(page);
ClearPageError(page);
@@ -760,8 +760,10 @@ jffs_do_readpage_nolock(struct file *file, struct page *page)
read_len = 0;
result = 0;
-
offset = page->index << PAGE_CACHE_SHIFT;
+
+ kmap(page);
+ buf = page_address(page);
if (offset < inode->i_size) {
read_len = min_t(long, inode->i_size - offset, PAGE_SIZE);
r = jffs_read_data(f, buf, offset, read_len);
@@ -779,6 +781,8 @@ jffs_do_readpage_nolock(struct file *file, struct page *page)
/* This handles the case of partial or no read in above */
if(read_len < PAGE_SIZE)
memset(buf + read_len, 0, PAGE_SIZE - read_len);
+ flush_dcache_page(page);
+ kunmap(page);
D3(printk (KERN_NOTICE "readpage(): up biglock\n"));
up(&c->fmc->biglock);
@@ -788,9 +792,8 @@ jffs_do_readpage_nolock(struct file *file, struct page *page)
}else {
SetPageUptodate(page);
}
- flush_dcache_page(page);
- put_page(page);
+ page_cache_release(page);
D3(printk("jffs_readpage(): Leaving...\n"));
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index a8cf25f2c141..1d75079a5fb1 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -17,6 +17,7 @@
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/pagemap.h>
+#include <linux/highmem.h>
#include <linux/crc32.h>
#include <linux/jffs2.h>
#include "nodelist.h"
@@ -381,9 +382,10 @@ int jffs2_commit_write (struct file *filp, struct page *pg, unsigned start, unsi
ri->isize = (uint32_t)inode->i_size;
ri->atime = ri->ctime = ri->mtime = CURRENT_TIME;
- /* We rely on the fact that generic_file_write() currently kmaps the page for us. */
+ kmap(pg);
ret = jffs2_write_inode_range(c, f, ri, page_address(pg) + start,
(pg->index << PAGE_CACHE_SHIFT) + start, end - start, &writtenlen);
+ kunmap(pg);
if (ret) {
/* There was an error writing. */
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index eb4be0b97533..6c21109b9a94 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -403,7 +403,6 @@ static void __write_metapage(metapage_t * mp)
if (rc) {
jERROR(1, ("prepare_write return %d!\n", rc));
ClearPageUptodate(mp->page);
- kunmap(mp->page);
unlock_page(mp->page);
clear_bit(META_dirty, &mp->flag);
return;
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index 6df43a92d213..d8339f3f401f 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -7,6 +7,7 @@
*/
#include "minix.h"
+#include <linux/highmem.h>
#include <linux/smp_lock.h>
typedef struct minix_dir_entry minix_dirent;
@@ -261,7 +262,7 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
{
struct address_space *mapping = page->mapping;
struct inode *inode = (struct inode*)mapping->host;
- char *kaddr = (char*)page_address(page);
+ char *kaddr = page_address(page);
unsigned from = (char*)de - kaddr;
unsigned to = from + minix_sb(inode->i_sb)->s_dirsize;
int err;
@@ -286,7 +287,7 @@ int minix_make_empty(struct inode *inode, struct inode *dir)
struct page *page = grab_cache_page(mapping, 0);
struct minix_sb_info * sbi = minix_sb(inode->i_sb);
struct minix_dir_entry * de;
- char *base;
+ char *kaddr;
int err;
if (!page)
@@ -297,15 +298,16 @@ int minix_make_empty(struct inode *inode, struct inode *dir)
goto fail;
}
- base = (char*)page_address(page);
- memset(base, 0, PAGE_CACHE_SIZE);
+ kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr, 0, PAGE_CACHE_SIZE);
- de = (struct minix_dir_entry *) base;
+ de = (struct minix_dir_entry *)kaddr;
de->inode = inode->i_ino;
strcpy(de->name,".");
de = minix_next_entry(de, sbi);
de->inode = dir->i_ino;
strcpy(de->name,"..");
+ kunmap_atomic(kaddr, KM_USER0);
err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize);
fail:
diff --git a/fs/namei.c b/fs/namei.c
index ade1cb87562c..59b7bc8f86ba 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2200,8 +2200,9 @@ int page_symlink(struct inode *inode, const char *symname, int len)
err = mapping->a_ops->prepare_write(NULL, page, 0, len-1);
if (err)
goto fail_map;
- kaddr = page_address(page);
+ kaddr = kmap_atomic(page, KM_USER0);
memcpy(kaddr, symname, len-1);
+ kunmap_atomic(kaddr, KM_USER0);
mapping->a_ops->commit_write(NULL, page, 0, len-1);
/*
* Notice that we are _not_ going to block here - end of page is
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 907cb1faf056..8a12dbe5d523 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -35,7 +35,7 @@
#include "efi.h"
#if CONFIG_BLK_DEV_MD
-extern void md_autodetect_dev(kdev_t dev);
+extern void md_autodetect_dev(dev_t dev);
#endif
int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
@@ -87,46 +87,27 @@ static int (*check_part[])(struct parsed_partitions *, struct block_device *) =
* a pointer to that same buffer (for convenience).
*/
-char *disk_name (struct gendisk *hd, int minor, char *buf)
+char *disk_name(struct gendisk *hd, int part, char *buf)
{
- unsigned int unit = (minor >> hd->minor_shift);
- unsigned int part = (minor & ((1 << hd->minor_shift) -1 ));
- struct hd_struct *p = hd->part + minor - hd->first_minor;
- char s[40];
- const char *maj;
-
- if ((((minor - hd->first_minor) >> hd->minor_shift) < hd->nr_real) &&
- p->de) {
- int pos;
-
- pos = devfs_generate_path(p->de, buf, 64);
- if (pos >= 0)
- return buf + pos;
- }
-
- /*
- * Yes, I know, ... in cases is gccism and not a pretty one.
- * However, the first variant will eventually consume _all_ cases
- * and switch will disappear.
- */
- switch (hd->major) {
- default:
- maj = hd->major_name;
- break;
- case MD_MAJOR:
- sprintf(s, "%s%d", "md", unit);
- maj = s;
- break;
- case I2O_MAJOR:
- sprintf(s, "%s%c", hd->major_name, unit + 'a');
- maj = s;
+ int pos;
+ if (!part) {
+ if (hd->disk_de) {
+ pos = devfs_generate_path(hd->disk_de, buf, 64);
+ if (pos >= 0)
+ return buf + pos;
+ }
+ sprintf(buf, "%s", hd->major_name);
+ } else {
+ if (hd->part[part-1].de) {
+ pos = devfs_generate_path(hd->part[part-1].de, buf, 64);
+ if (pos >= 0)
+ return buf + pos;
+ }
+ if (isdigit(hd->major_name[strlen(hd->major_name)-1]))
+ sprintf(buf, "%sp%d", hd->major_name, part);
+ else
+ sprintf(buf, "%s%d", hd->major_name, part);
}
- if (!part)
- sprintf(buf, "%s", maj);
- else if (isdigit(maj[strlen(maj)-1]))
- sprintf(buf, "%sp%d", maj, part);
- else
- sprintf(buf, "%s%d", maj, part);
return buf;
}
@@ -147,118 +128,91 @@ static ssize_t partition_device_type_read(struct device *driverfs_dev,
}
static DEVICE_ATTR(type,S_IRUGO,partition_device_type_read,NULL);
-void driverfs_create_partitions(struct gendisk *hd, int minor)
+static void driverfs_create_partitions(struct gendisk *hd)
{
- int pos = -1;
- int devnum = (minor - hd->first_minor) >> hd->minor_shift;
- char dirname[256];
- struct device *parent = 0;
- int max_p;
+ int max_p = 1<<hd->minor_shift;
+ struct hd_struct *p = hd->part;
+ char name[DEVICE_NAME_SIZE];
+ char bus_id[BUS_ID_SIZE];
+ struct device *dev, *parent;
int part;
- devfs_handle_t dir = 0;
- struct hd_struct *p = hd->part + minor - hd->first_minor;
-
- /* get parent driverfs device structure */
- if (hd->driverfs_dev_arr)
- parent = hd->driverfs_dev_arr[devnum];
- else /* if driverfs not supported by subsystem, skip partitions */
+
+ /* if driverfs not supported by subsystem, skip partitions */
+ if (!(hd->flags & GENHD_FL_DRIVERFS))
return;
-
- /* get parent device node directory name */
- if (hd->de_arr) {
- dir = hd->de_arr[devnum];
- if (dir)
- pos = devfs_generate_path (dir, dirname,
- sizeof dirname);
+
+ parent = hd->driverfs_dev;
+
+ if (parent) {
+ sprintf(name, "%s", parent->name);
+ sprintf(bus_id, "%s:", parent->bus_id);
+ } else {
+ *name = *bus_id = '\0';
}
-
- if (pos < 0) {
- disk_name(hd, minor, dirname);
- pos = 0;
+
+ dev = &hd->disk_dev;
+ dev->driver_data = (void *)(long)__mkdev(hd->major, hd->first_minor);
+ sprintf(dev->name, "%sdisc", name);
+ sprintf(dev->bus_id, "%sdisc", bus_id);
+ for (part=1; part < max_p; part++) {
+ dev = &p[part-1].hd_driverfs_dev;
+ sprintf(dev->name, "%spart%d", name, part);
+ sprintf(dev->bus_id, "%s:p%d", bus_id, part);
+ if (!p[part-1].nr_sects)
+ continue;
+ dev->driver_data =
+ (void *)(long)__mkdev(hd->major, hd->first_minor+part);
}
-
- max_p = (1 << hd->minor_shift);
-
- /* for all partitions setup parents and device node names */
- for(part=0; part < max_p; part++) {
- if ((part == 0) || (p[part].nr_sects >= 1)) {
- struct device * current_driverfs_dev =
- &p[part].hd_driverfs_dev;
- current_driverfs_dev->parent = parent;
- /* handle disc case */
- current_driverfs_dev->driver_data =
- (void *)(long)__mkdev(hd->major, minor+part);
- if (part == 0) {
- if (parent) {
- sprintf(current_driverfs_dev->name,
- "%sdisc", parent->name);
- sprintf(current_driverfs_dev->bus_id,
- "%s:disc", parent->bus_id);
- } else {
- sprintf(current_driverfs_dev->name,
- "disc");
- sprintf(current_driverfs_dev->bus_id,
- "disc");
- }
- } else { /* this is a partition */
- if (parent) {
- sprintf(current_driverfs_dev->name,
- "%spart%d", parent->name, part);
- sprintf(current_driverfs_dev->bus_id,
- "%s:p%d", parent->bus_id, part);
- } else {
- sprintf(current_driverfs_dev->name,
- "part%d", part);
- sprintf(current_driverfs_dev->bus_id,
- "p%d" ,part);
- }
- }
- if (parent) current_driverfs_dev->bus = parent->bus;
- device_register(current_driverfs_dev);
- device_create_file(current_driverfs_dev,
- &dev_attr_type);
- device_create_file(current_driverfs_dev,
- &dev_attr_kdev);
- }
+
+ dev = &hd->disk_dev;
+ dev->parent = parent;
+ if (parent)
+ dev->bus = parent->bus;
+ device_register(dev);
+ device_create_file(dev, &dev_attr_type);
+ device_create_file(dev, &dev_attr_kdev);
+
+ for (part=0; part < max_p-1; part++) {
+ dev = &p[part].hd_driverfs_dev;
+ dev->parent = parent;
+ if (parent)
+ dev->bus = parent->bus;
+ if (!dev->driver_data)
+ continue;
+ device_register(dev);
+ device_create_file(dev, &dev_attr_type);
+ device_create_file(dev, &dev_attr_kdev);
}
}
-void driverfs_remove_partitions(struct gendisk *hd, int minor)
+static void driverfs_remove_partitions(struct gendisk *hd)
{
- int max_p;
+ int max_p = 1<<hd->minor_shift;
+ struct device *dev;
+ struct hd_struct *p;
int part;
- struct device * current_driverfs_dev;
- struct hd_struct *p = hd->part + minor - hd->first_minor;
-
- max_p=(1 << hd->minor_shift);
-
- /* for all parts setup parent relationships and device node names */
- for(part=1; part < max_p; part++) {
- if ((p[part].nr_sects >= 1)) {
- current_driverfs_dev = &p[part].hd_driverfs_dev;
- device_remove_file(current_driverfs_dev,
- &dev_attr_type);
- device_remove_file(current_driverfs_dev,
- &dev_attr_kdev);
- put_device(current_driverfs_dev);
+
+ for (part=1, p = hd->part; part < max_p; part++, p++) {
+ dev = &p->hd_driverfs_dev;
+ if (dev->driver_data) {
+ device_remove_file(dev, &dev_attr_type);
+ device_remove_file(dev, &dev_attr_kdev);
+ put_device(dev);
+ dev->driver_data = NULL;
}
}
- current_driverfs_dev = &p->hd_driverfs_dev;
- device_remove_file(current_driverfs_dev,
- &dev_attr_type);
- device_remove_file(current_driverfs_dev,
- &dev_attr_kdev);
- put_device(current_driverfs_dev);
- return;
+ dev = &hd->disk_dev;
+ if (dev->driver_data) {
+ device_remove_file(dev, &dev_attr_type);
+ device_remove_file(dev, &dev_attr_kdev);
+ put_device(dev);
+ dev->driver_data = NULL;
+ }
}
-/*
- * DON'T EXPORT
- */
-void check_partition(struct gendisk *hd, struct block_device *bdev)
+static void check_partition(struct gendisk *hd, struct block_device *bdev)
{
devfs_handle_t de = NULL;
- kdev_t dev = to_kdev_t(bdev->bd_dev);
char buf[64];
struct parsed_partitions *state;
int i;
@@ -267,17 +221,16 @@ void check_partition(struct gendisk *hd, struct block_device *bdev)
if (!state)
return;
- if (hd->de_arr)
- de = hd->de_arr[(minor(dev)-hd->first_minor)>>hd->minor_shift];
+ if (hd->flags & GENHD_FL_DEVFS)
+ de = hd->de;
i = devfs_generate_path (de, buf, sizeof buf);
if (i >= 0) {
printk(KERN_INFO " /dev/%s:", buf + i);
sprintf(state->name, "p");
} else {
- unsigned n = hd->major;
- disk_name(hd, minor(dev), state->name);
+ disk_name(hd, 0, state->name);
printk(KERN_INFO " %s:", state->name);
- if (n - COMPAQ_SMART2_MAJOR <= 7 || n - COMPAQ_CISS_MAJOR <= 7)
+ if (isdigit(state->name[strlen(state->name)-1]))
sprintf(state->name, "p");
}
state->limit = 1<<hd->minor_shift;
@@ -291,68 +244,65 @@ void check_partition(struct gendisk *hd, struct block_device *bdev)
if (res < 0) {
if (warn_no_part)
printk(" unable to read partition table\n");
- goto out;
+ return;
}
- p = hd->part + minor(dev) - hd->first_minor;
+ p = hd->part;
for (j = 1; j < state->limit; j++) {
- p[j].start_sect = state->parts[j].from;
- p[j].nr_sects = state->parts[j].size;
+ p[j-1].start_sect = state->parts[j].from;
+ p[j-1].nr_sects = state->parts[j].size;
#if CONFIG_BLK_DEV_MD
- if (!state->parts[j].flags)
+ if (!state->parts[j-1].flags)
continue;
- md_autodetect_dev(mk_kdev(major(dev),minor(dev)+j));
+ md_autodetect_dev(bdev->bd_dev+j);
#endif
}
- goto out;
+ return;
}
-
printk(" unknown partition table\n");
-out:
- driverfs_create_partitions(hd, minor(dev));
- devfs_register_partitions (hd, minor(dev), 0);
}
-#ifdef CONFIG_DEVFS_FS
-static void devfs_register_partition (struct gendisk *dev, int minor, int part)
+static void devfs_register_partition(struct gendisk *dev, int part)
{
- int devnum = (minor - dev->first_minor) >> dev->minor_shift;
+#ifdef CONFIG_DEVFS_FS
devfs_handle_t dir;
unsigned int devfs_flags = DEVFS_FL_DEFAULT;
- struct hd_struct *p = dev->part + minor - dev->first_minor;
+ struct hd_struct *p = dev->part;
char devname[16];
- if (p[part].de)
+ if (p[part-1].de)
return;
- dir = devfs_get_parent(p[0].de);
+ dir = devfs_get_parent(dev->disk_de);
if (!dir)
return;
- if ( dev->flags && (dev->flags[devnum] & GENHD_FL_REMOVABLE) )
+ if (dev->flags & GENHD_FL_REMOVABLE)
devfs_flags |= DEVFS_FL_REMOVABLE;
- sprintf (devname, "part%d", part);
- p[part].de = devfs_register (dir, devname, devfs_flags,
- dev->major, minor + part,
+ sprintf(devname, "part%d", part);
+ p[part-1].de = devfs_register (dir, devname, devfs_flags,
+ dev->major, dev->first_minor + part,
S_IFBLK | S_IRUSR | S_IWUSR,
dev->fops, NULL);
+#endif
}
+#ifdef CONFIG_DEVFS_FS
static struct unique_numspace disc_numspace = UNIQUE_NUMBERSPACE_INITIALISER;
+#endif
-static void devfs_register_disc (struct gendisk *dev, int minor)
+static void devfs_create_partitions(struct gendisk *dev)
{
+#ifdef CONFIG_DEVFS_FS
int pos = 0;
- int devnum = (minor - dev->first_minor) >> dev->minor_shift;
devfs_handle_t dir, slave;
unsigned int devfs_flags = DEVFS_FL_DEFAULT;
char dirname[64], symlink[16];
static devfs_handle_t devfs_handle;
- struct hd_struct *p = dev->part + minor - dev->first_minor;
+ int part, max_p = 1<<dev->minor_shift;
+ struct hd_struct *p = dev->part;
- if (p[0].de)
- return;
- if ( dev->flags && (dev->flags[devnum] & GENHD_FL_REMOVABLE) )
+ if (dev->flags & GENHD_FL_REMOVABLE)
devfs_flags |= DEVFS_FL_REMOVABLE;
- if (dev->de_arr) {
- dir = dev->de_arr[devnum];
+ if (dev->flags & GENHD_FL_DEVFS) {
+ dir = dev->de;
if (!dir) /* Aware driver wants to block disc management */
return;
pos = devfs_generate_path(dir, dirname + 3, sizeof dirname-3);
@@ -362,46 +312,39 @@ static void devfs_register_disc (struct gendisk *dev, int minor)
} else {
/* Unaware driver: construct "real" directory */
sprintf(dirname, "../%s/disc%d", dev->major_name,
- (dev->first_minor >> dev->minor_shift) + devnum);
+ dev->first_minor >> dev->minor_shift);
dir = devfs_mk_dir(NULL, dirname + 3, NULL);
}
if (!devfs_handle)
devfs_handle = devfs_mk_dir(NULL, "discs", NULL);
- p[0].number = devfs_alloc_unique_number (&disc_numspace);
- sprintf(symlink, "disc%d", p[0].number);
+ dev->number = devfs_alloc_unique_number (&disc_numspace);
+ sprintf(symlink, "disc%d", dev->number);
devfs_mk_symlink (devfs_handle, symlink, DEVFS_FL_DEFAULT,
dirname + pos, &slave, NULL);
- p[0].de = devfs_register (dir, "disc", devfs_flags, dev->major, minor,
+ dev->disk_de = devfs_register(dir, "disc", devfs_flags,
+ dev->major, dev->first_minor,
S_IFBLK | S_IRUSR | S_IWUSR, dev->fops, NULL);
- devfs_auto_unregister(p[0].de, slave);
- if (!dev->de_arr)
+ devfs_auto_unregister(dev->disk_de, slave);
+ if (!(dev->flags & GENHD_FL_DEVFS))
devfs_auto_unregister (slave, dir);
+ for (part = 1, p++; part < max_p; part++, p++)
+ if (p->nr_sects)
+ devfs_register_partition(dev, part);
+#endif
}
-#endif /* CONFIG_DEVFS_FS */
-void devfs_register_partitions (struct gendisk *dev, int minor, int unregister)
+static void devfs_remove_partitions(struct gendisk *dev)
{
#ifdef CONFIG_DEVFS_FS
- int part, max_p;
- struct hd_struct *p = dev->part + minor - dev->first_minor;
-
- if (!unregister)
- devfs_register_disc (dev, minor);
- max_p = (1 << dev->minor_shift);
- for (part = 1; part < max_p; part++) {
- if ( unregister || (p[part].nr_sects < 1) ) {
- devfs_unregister(p[part].de);
- p[part].de = NULL;
- continue;
- }
- devfs_register_partition (dev, minor, part);
- }
- if (unregister) {
- devfs_unregister(p[0].de);
- p[0].de = NULL;
- devfs_dealloc_unique_number(&disc_numspace, p[0].number);
+ int part;
+ for (part = (1<<dev->minor_shift)-1; part--; ) {
+ devfs_unregister(dev->part[part].de);
+ dev->part[part].de = NULL;
}
-#endif /* CONFIG_DEVFS_FS */
+ devfs_unregister(dev->disk_de);
+ dev->disk_de = NULL;
+ devfs_dealloc_unique_number(&disc_numspace, dev->number);
+#endif
}
/*
@@ -414,28 +357,18 @@ void devfs_register_partitions (struct gendisk *dev, int minor, int unregister)
* done
*/
-void register_disk(struct gendisk *gdev, kdev_t dev, unsigned minors,
+void register_disk(struct gendisk *disk, kdev_t dev, unsigned minors,
struct block_device_operations *ops, long size)
{
- if (!gdev)
- return;
- grok_partitions(dev, size);
-}
-
-void grok_partitions(kdev_t dev, long size)
-{
struct block_device *bdev;
- struct gendisk *g = get_gendisk(dev);
- struct hd_struct *p;
- if (!g)
+ if (!disk)
return;
- p = g->part + minor(dev) - g->first_minor;
- p[0].nr_sects = size;
+ set_capacity(disk, size);
/* No minors to use for partitions */
- if (!g->minor_shift)
+ if (!disk->minor_shift)
return;
/* No such device (e.g., media were just removed) */
@@ -445,10 +378,66 @@ void grok_partitions(kdev_t dev, long size)
bdev = bdget(kdev_t_to_nr(dev));
if (blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW) < 0)
return;
- check_partition(g, bdev);
+ check_partition(disk, bdev);
+ driverfs_create_partitions(disk);
+ devfs_create_partitions(disk);
blkdev_put(bdev, BDEV_RAW);
}
+void update_partition(struct gendisk *disk, int part)
+{
+ struct hd_struct *p = disk->part + part - 1;
+ struct device *dev = &p->hd_driverfs_dev;
+
+ if (!p->nr_sects) {
+ if (p->de) {
+ devfs_unregister(p->de);
+ p->de = NULL;
+ }
+ if (dev->driver_data) {
+ device_remove_file(dev, &dev_attr_type);
+ device_remove_file(dev, &dev_attr_kdev);
+ put_device(dev);
+ dev->driver_data = NULL;
+ }
+ return;
+ }
+ if (!p->de)
+ devfs_register_partition(disk, part);
+ if (dev->driver_data || !(disk->flags & GENHD_FL_DRIVERFS))
+ return;
+ dev->driver_data =
+ (void *)(long)__mkdev(disk->major, disk->first_minor+part);
+ device_register(dev);
+ device_create_file(dev, &dev_attr_type);
+ device_create_file(dev, &dev_attr_kdev);
+}
+
+int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
+{
+ kdev_t dev = to_kdev_t(bdev->bd_dev);
+ int p, res;
+ if (!bdev->bd_invalidated)
+ return 0;
+ if (bdev->bd_part_count)
+ return -EBUSY;
+ res = invalidate_device(dev, 1);
+ if (res)
+ return res;
+ bdev->bd_invalidated = 0;
+ for (p = 0; p < (1<<disk->minor_shift) - 1; p++) {
+ disk->part[p].start_sect = 0;
+ disk->part[p].nr_sects = 0;
+ }
+ if (bdev->bd_op->revalidate)
+ bdev->bd_op->revalidate(dev);
+ if (get_capacity(disk))
+ check_partition(disk, bdev);
+ for (p = 1; p < (1<<disk->minor_shift); p++)
+ update_partition(disk, p);
+ return res;
+}
+
unsigned char *read_dev_sector(struct block_device *bdev, unsigned long n, Sector *p)
{
struct address_space *mapping = bdev->bd_inode->i_mapping;
@@ -472,38 +461,46 @@ fail:
return NULL;
}
-int wipe_partitions(kdev_t dev)
+static int wipe_partitions(struct gendisk *disk)
{
- struct gendisk *g;
+ int max_p = 1 << disk->minor_shift;
kdev_t devp;
- int p, major, minor, minor0, max_p, res;
- struct hd_struct *part;
-
- g = get_gendisk(dev);
- if (g == NULL)
- return -EINVAL;
+ int res;
+ int p;
- max_p = 1 << g->minor_shift;
- major = major(dev);
- minor = minor(dev);
- minor0 = minor & ~(max_p - 1);
- if (minor0 != minor) /* for now only whole-disk reread */
- return -EINVAL; /* %%% later.. */
-
- part = g->part + minor - g->first_minor;
/* invalidate stuff */
- for (p = max_p - 1; p >= 0; p--) {
- minor = minor0 + p;
- devp = mk_kdev(major,minor);
+ for (p = max_p - 1; p > 0; p--) {
+ devp = mk_kdev(disk->major,disk->first_minor + p);
#if 0 /* %%% superfluous? */
- if (part[p].nr_sects == 0)
+ if (disk->part[p-1].nr_sects == 0)
continue;
#endif
res = invalidate_device(devp, 1);
if (res)
return res;
- part[p].start_sect = 0;
- part[p].nr_sects = 0;
+ disk->part[p-1].start_sect = 0;
+ disk->part[p-1].nr_sects = 0;
}
+ devp = mk_kdev(disk->major,disk->first_minor);
+#if 0 /* %%% superfluous? */
+ if (disk->part[p].nr_sects == 0)
+ continue;
+#endif
+ res = invalidate_device(devp, 1);
+ if (res)
+ return res;
+ disk->capacity = 0;
return 0;
}
+
+void del_gendisk(struct gendisk *disk)
+{
+ driverfs_remove_partitions(disk);
+ wipe_partitions(disk);
+ unlink_gendisk(disk);
+ devfs_remove_partitions(disk);
+ if (disk->part) {
+ kfree(disk->part);
+ disk->part = NULL;
+ }
+}
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index 1beb8ecb05f8..d1af58486615 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
+#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/smp_lock.h>
@@ -47,8 +48,10 @@ static struct inode_operations ramfs_dir_inode_operations;
static int ramfs_readpage(struct file *file, struct page * page)
{
if (!PageUptodate(page)) {
- memset(kmap(page), 0, PAGE_CACHE_SIZE);
- kunmap(page);
+ char *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr, 0, PAGE_CACHE_SIZE);
+ kunmap_atomic(kaddr, KM_USER0);
flush_dcache_page(page);
SetPageUptodate(page);
}
@@ -58,10 +61,12 @@ static int ramfs_readpage(struct file *file, struct page * page)
static int ramfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
{
- void *addr = kmap(page);
if (!PageUptodate(page)) {
- memset(addr, 0, PAGE_CACHE_SIZE);
+ char *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr, 0, PAGE_CACHE_SIZE);
flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
SetPageUptodate(page);
}
SetPageDirty(page);
@@ -73,7 +78,6 @@ static int ramfs_commit_write(struct file *file, struct page *page, unsigned off
struct inode *inode = page->mapping->host;
loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
- kunmap(page);
if (pos > inode->i_size)
inode->i_size = pos;
return 0;
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 5b2862949193..3344121f15d6 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -7,6 +7,7 @@
#include <linux/reiserfs_fs.h>
#include <linux/smp_lock.h>
#include <linux/pagemap.h>
+#include <linux/highmem.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <linux/buffer_head.h>
@@ -1672,8 +1673,6 @@ static int grab_tail_page(struct inode *p_s_inode,
if (error)
goto unlock ;
- kunmap(page) ; /* mapped by block_prepare_write */
-
head = page_buffers(page) ;
bh = head;
do {
@@ -1768,10 +1767,13 @@ void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
length = offset & (blocksize - 1) ;
/* if we are not on a block boundary */
if (length) {
+ char *kaddr;
+
length = blocksize - length ;
- memset((char *)kmap(page) + offset, 0, length) ;
+ kaddr = kmap_atomic(page, KM_USER0) ;
+ memset(kaddr + offset, 0, length) ;
flush_dcache_page(page) ;
- kunmap(page) ;
+ kunmap_atomic(kaddr, KM_USER0) ;
if (buffer_mapped(bh) && bh->b_blocknr != 0) {
mark_buffer_dirty(bh) ;
}
@@ -1921,23 +1923,25 @@ static int reiserfs_write_full_page(struct page *page) {
struct buffer_head *arr[PAGE_CACHE_SIZE/512] ;
int nr = 0 ;
- if (!page_has_buffers(page)) {
+ if (!page_has_buffers(page))
block_prepare_write(page, 0, 0, NULL) ;
- kunmap(page) ;
- }
+
/* last page in the file, zero out any contents past the
** last byte in the file
*/
if (page->index >= end_index) {
+ char *kaddr;
+
last_offset = inode->i_size & (PAGE_CACHE_SIZE - 1) ;
/* no file contents in this page */
if (page->index >= end_index + 1 || !last_offset) {
error = -EIO ;
goto fail ;
}
- memset((char *)kmap(page)+last_offset, 0, PAGE_CACHE_SIZE-last_offset) ;
+ kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + last_offset, 0, PAGE_CACHE_SIZE-last_offset) ;
flush_dcache_page(page) ;
- kunmap(page) ;
+ kunmap_atomic(kaddr, KM_USER0) ;
}
head = page_buffers(page) ;
bh = head ;
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index 560f1f336111..8d6dfeec1e06 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -1286,15 +1286,15 @@ int reiserfs_delete_item (struct reiserfs_transaction_handle *th,
**
** p_s_un_bh is from the page cache (all unformatted nodes are
** from the page cache) and might be a highmem page. So, we
- ** can't use p_s_un_bh->b_data. But, the page has already been
- ** kmapped, so we can use page_address()
+ ** can't use p_s_un_bh->b_data.
** -clm
*/
- data = page_address(p_s_un_bh->b_page) ;
+ data = kmap_atomic(p_s_un_bh->b_page, KM_USER0);
off = ((le_ih_k_offset (&s_ih) - 1) & (PAGE_CACHE_SIZE - 1));
memcpy(data + off,
B_I_PITEM(PATH_PLAST_BUFFER(p_s_path), &s_ih), n_ret_value);
+ kunmap_atomic(data, KM_USER0);
}
/* Perform balancing after all resources have been collected at once. */
diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
index ed235b1adeb4..9be2d624b989 100644
--- a/fs/reiserfs/tail_conversion.c
+++ b/fs/reiserfs/tail_conversion.c
@@ -122,11 +122,12 @@ int direct2indirect (struct reiserfs_transaction_handle *th, struct inode * inod
}
/* if we've copied bytes from disk into the page, we need to zero
** out the unused part of the block (it was not up to date before)
- ** the page is still kmapped (by whoever called reiserfs_get_block)
*/
if (up_to_date_bh) {
unsigned pgoff = (tail_offset + total_tail - 1) & (PAGE_CACHE_SIZE - 1);
- memset(page_address(unbh->b_page) + pgoff, 0, n_blk_size - total_tail) ;
+ char *kaddr=kmap_atomic(up_to_date_bh->b_page, KM_USER0);
+ memset(kaddr + pgoff, 0, n_blk_size - total_tail) ;
+ kunmap_atomic(kaddr, KM_USER0);
}
REISERFS_I(inode)->i_first_direct_byte = U32_MAX;
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index c7ae7625f15f..e56c14bec653 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -14,6 +14,7 @@
*/
#include <linux/pagemap.h>
+#include <linux/highmem.h>
#include <linux/smp_lock.h>
#include "sysv.h"
@@ -273,6 +274,7 @@ int sysv_make_empty(struct inode *inode, struct inode *dir)
if (!page)
return -ENOMEM;
+ kmap(page);
err = mapping->a_ops->prepare_write(NULL, page, 0, 2 * SYSV_DIRSIZE);
if (err) {
unlock_page(page);
@@ -291,6 +293,7 @@ int sysv_make_empty(struct inode *inode, struct inode *dir)
err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE);
fail:
+ kunmap(page);
page_cache_release(page);
return err;
}
diff --git a/include/asm-alpha/core_t2.h b/include/asm-alpha/core_t2.h
index 007cf43baf10..fdaa57aa2c14 100644
--- a/include/asm-alpha/core_t2.h
+++ b/include/asm-alpha/core_t2.h
@@ -19,7 +19,7 @@
*
*/
-#define T2_MEM_R1_MASK 0x03ffffff /* Mem sparse region 1 mask is 26 bits */
+#define T2_MEM_R1_MASK 0x07ffffff /* Mem sparse region 1 mask is 26 bits */
/* GAMMA-SABLE is a SABLE with EV5-based CPUs */
#define _GAMMA_BIAS 0x8000000000UL
@@ -402,13 +402,17 @@ __EXTERN_INLINE void t2_outl(u32 b, unsigned long addr)
*
*/
+#define t2_set_hae { \
+ msb = addr >> 27; \
+ addr &= T2_MEM_R1_MASK; \
+ set_hae(msb); \
+}
+
__EXTERN_INLINE u8 t2_readb(unsigned long addr)
{
unsigned long result, msb;
- msb = addr & 0xE0000000;
- addr &= T2_MEM_R1_MASK;
- set_hae(msb);
+ t2_set_hae;
result = *(vip) ((addr << 5) + T2_SPARSE_MEM + 0x00);
return __kernel_extbl(result, addr & 3);
@@ -418,9 +422,7 @@ __EXTERN_INLINE u16 t2_readw(unsigned long addr)
{
unsigned long result, msb;
- msb = addr & 0xE0000000;
- addr &= T2_MEM_R1_MASK;
- set_hae(msb);
+ t2_set_hae;
result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08);
return __kernel_extwl(result, addr & 3);
@@ -431,9 +433,7 @@ __EXTERN_INLINE u32 t2_readl(unsigned long addr)
{
unsigned long msb;
- msb = addr & 0xE0000000;
- addr &= T2_MEM_R1_MASK;
- set_hae(msb);
+ t2_set_hae;
return *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18);
}
@@ -442,9 +442,7 @@ __EXTERN_INLINE u64 t2_readq(unsigned long addr)
{
unsigned long r0, r1, work, msb;
- msb = addr & 0xE0000000;
- addr &= T2_MEM_R1_MASK;
- set_hae(msb);
+ t2_set_hae;
work = (addr << 5) + T2_SPARSE_MEM + 0x18;
r0 = *(vuip)(work);
@@ -456,9 +454,7 @@ __EXTERN_INLINE void t2_writeb(u8 b, unsigned long addr)
{
unsigned long msb, w;
- msb = addr & 0xE0000000;
- addr &= T2_MEM_R1_MASK;
- set_hae(msb);
+ t2_set_hae;
w = __kernel_insbl(b, addr & 3);
*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x00) = w;
@@ -468,9 +464,7 @@ __EXTERN_INLINE void t2_writew(u16 b, unsigned long addr)
{
unsigned long msb, w;
- msb = addr & 0xE0000000;
- addr &= T2_MEM_R1_MASK;
- set_hae(msb);
+ t2_set_hae;
w = __kernel_inswl(b, addr & 3);
*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08) = w;
@@ -481,9 +475,7 @@ __EXTERN_INLINE void t2_writel(u32 b, unsigned long addr)
{
unsigned long msb;
- msb = addr & 0xE0000000;
- addr &= T2_MEM_R1_MASK;
- set_hae(msb);
+ t2_set_hae;
*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18) = b;
}
@@ -492,9 +484,7 @@ __EXTERN_INLINE void t2_writeq(u64 b, unsigned long addr)
{
unsigned long msb, work;
- msb = addr & 0xE0000000;
- addr &= T2_MEM_R1_MASK;
- set_hae(msb);
+ t2_set_hae;
work = (addr << 5) + T2_SPARSE_MEM + 0x18;
*(vuip)work = b;
diff --git a/include/asm-alpha/dma.h b/include/asm-alpha/dma.h
index e6d667144b50..97daf7d786aa 100644
--- a/include/asm-alpha/dma.h
+++ b/include/asm-alpha/dma.h
@@ -75,34 +75,49 @@
#define MAX_DMA_CHANNELS 8
-/* The maximum address that we can perform a DMA transfer to on Alpha XL,
- due to a hardware SIO (PCI<->ISA bus bridge) chip limitation, is 64MB.
- See <asm/apecs.h> for more info.
+/*
+ ISA DMA limitations on Alpha platforms,
+
+ These may be due to SIO (PCI<->ISA bridge) chipset limitation, or
+ just a wiring limit.
*/
-/* The maximum address that we can perform a DMA transfer to on RUFFIAN,
- due to a hardware SIO (PCI<->ISA bus bridge) chip limitation, is 16MB.
- See <asm/pyxis.h> for more info.
+
+/* The maximum address for ISA DMA transfer on Alpha XL, due to an
+ hardware SIO limitation, is 64MB.
+*/
+#define ALPHA_XL_MAX_DMA_ADDRESS (IDENT_ADDR+0x04000000UL)
+
+/* The maximum address for ISA DMA transfer on RUFFIAN and NAUTILUS,
+ due to an hardware SIO limitation, is 16MB.
*/
-/* NOTE: we must define the maximum as something less than 64Mb, to prevent
- virt_to_bus() from returning an address in the first window, for a
- data area that goes beyond the 64Mb first DMA window. Sigh...
- We MUST coordinate the maximum with <asm/apecs.h> for consistency.
- For now, this limit is set to 48Mb...
+#define ALPHA_RUFFIAN_MAX_DMA_ADDRESS (IDENT_ADDR+0x01000000UL)
+#define ALPHA_NAUTILUS_MAX_DMA_ADDRESS (IDENT_ADDR+0x01000000UL)
+
+/* The maximum address for ISA DMA transfer on SABLE, and some ALCORs,
+ due to an hardware SIO chip limitation, is 2GB.
+*/
+#define ALPHA_SABLE_MAX_DMA_ADDRESS (IDENT_ADDR+0x80000000UL)
+#define ALPHA_ALCOR_MAX_DMA_ADDRESS (IDENT_ADDR+0x80000000UL)
+
+/*
+ Maximum address for all the others is the complete 32-bit bus
+ address space.
*/
-#define ALPHA_XL_MAX_DMA_ADDRESS (IDENT_ADDR+0x3000000UL)
-#define ALPHA_RUFFIAN_MAX_DMA_ADDRESS (IDENT_ADDR+0x1000000UL)
-#define ALPHA_NAUTILUS_MAX_DMA_ADDRESS (IDENT_ADDR+0x1000000UL)
-#define ALPHA_MAX_DMA_ADDRESS (~0UL)
+#define ALPHA_MAX_DMA_ADDRESS (IDENT_ADDR+0x100000000UL)
#ifdef CONFIG_ALPHA_GENERIC
# define MAX_DMA_ADDRESS (alpha_mv.max_dma_address)
#else
-# ifdef CONFIG_ALPHA_XL
+# if defined(CONFIG_ALPHA_XL)
# define MAX_DMA_ADDRESS ALPHA_XL_MAX_DMA_ADDRESS
# elif defined(CONFIG_ALPHA_RUFFIAN)
# define MAX_DMA_ADDRESS ALPHA_RUFFIAN_MAX_DMA_ADDRESS
# elif defined(CONFIG_ALPHA_NAUTILUS)
# define MAX_DMA_ADDRESS ALPHA_NAUTILUS_MAX_DMA_ADDRESS
+# elif defined(CONFIG_ALPHA_SABLE)
+# define MAX_DMA_ADDRESS ALPHA_SABLE_MAX_DMA_ADDRESS
+# elif defined(CONFIG_ALPHA_ALCOR)
+# define MAX_DMA_ADDRESS ALPHA_ALCOR_MAX_DMA_ADDRESS
# else
# define MAX_DMA_ADDRESS ALPHA_MAX_DMA_ADDRESS
# endif
diff --git a/include/asm-alpha/floppy.h b/include/asm-alpha/floppy.h
index 58d053db1a7f..88049a927ddd 100644
--- a/include/asm-alpha/floppy.h
+++ b/include/asm-alpha/floppy.h
@@ -97,25 +97,22 @@ static int FDC2 = -1;
/*
* Most Alphas have no problems with floppy DMA crossing 64k borders,
- * except for XL and RUFFIAN. They are also the only one with DMA
- * limits, so we use that to test in the generic kernel.
+ * except for certain ones, like XL and RUFFIAN.
+ *
+ * However, the test is simple and fast, and this *is* floppy, after all,
+ * so we do it for all platforms, just to make sure.
+ *
+ * This is advantageous in other circumstances as well, as in moving
+ * about the PCI DMA windows and forcing the floppy to start doing
+ * scatter-gather when it never had before, and there *is* a problem
+ * on that platform... ;-}
*/
-#define __CROSS_64KB(a,s) \
+#define CROSS_64KB(a,s) \
({ unsigned long __s64 = (unsigned long)(a); \
unsigned long __e64 = __s64 + (unsigned long)(s) - 1; \
(__s64 ^ __e64) & ~0xfffful; })
-#ifdef CONFIG_ALPHA_GENERIC
-# define CROSS_64KB(a,s) (__CROSS_64KB(a,s) && ~alpha_mv.max_dma_address)
-#else
-# if defined(CONFIG_ALPHA_XL) || defined(CONFIG_ALPHA_RUFFIAN) || defined(CONFIG_ALPHA_NAUTILUS)
-# define CROSS_64KB(a,s) __CROSS_64KB(a,s)
-# else
-# define CROSS_64KB(a,s) (0)
-# endif
-#endif
-
#define EXTRA_FLOPPY_PARAMS
#endif /* __ASM_ALPHA_FLOPPY_H */
diff --git a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h
index 63bb9f785498..0ca863142cf5 100644
--- a/include/asm-alpha/ide.h
+++ b/include/asm-alpha/ide.h
@@ -80,6 +80,17 @@ static __inline__ void ide_init_default_hwifs(void)
#endif
}
+#define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id))
+#define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id))
+#define ide_check_region(from,extent) check_region((from), (extent))
+#define ide_request_region(from,extent,name) request_region((from), (extent), (name))
+#define ide_release_region(from,extent) release_region((from), (extent))
+
+#define ide_ack_intr(hwif) (1)
+#define ide_fix_driveid(id) do {} while (0)
+#define ide_release_lock(lock) do {} while (0)
+#define ide_get_lock(lock, hdlr, data) do {} while (0)
+
#endif /* __KERNEL__ */
#endif /* __ASMalpha_IDE_H */
diff --git a/include/asm-alpha/kmap_types.h b/include/asm-alpha/kmap_types.h
new file mode 100644
index 000000000000..3e755b973e65
--- /dev/null
+++ b/include/asm-alpha/kmap_types.h
@@ -0,0 +1,31 @@
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+/* Dummy header just to define km_type. */
+
+#include <linux/config.h>
+
+#if CONFIG_DEBUG_HIGHMEM
+# define D(n) __KM_FENCE_##n ,
+#else
+# define D(n)
+#endif
+
+enum km_type {
+D(0) KM_BOUNCE_READ,
+D(1) KM_SKB_SUNRPC_DATA,
+D(2) KM_SKB_DATA_SOFTIRQ,
+D(3) KM_USER0,
+D(4) KM_USER1,
+D(5) KM_BIO_SRC_IRQ,
+D(6) KM_BIO_DST_IRQ,
+D(7) KM_PTE0,
+D(8) KM_PTE1,
+D(9) KM_IRQ0,
+D(10) KM_IRQ1,
+D(11) KM_TYPE_NR
+};
+
+#undef D
+
+#endif
diff --git a/include/asm-alpha/user.h b/include/asm-alpha/user.h
index c5519bf162d7..7e417fc9d491 100644
--- a/include/asm-alpha/user.h
+++ b/include/asm-alpha/user.h
@@ -1,6 +1,7 @@
#ifndef _ALPHA_USER_H
#define _ALPHA_USER_H
+#include <linux/sched.h>
#include <linux/ptrace.h>
#include <asm/page.h>
diff --git a/include/asm-i386/highmem.h b/include/asm-i386/highmem.h
index 1cba7fc45882..0316b53f868f 100644
--- a/include/asm-i386/highmem.h
+++ b/include/asm-i386/highmem.h
@@ -81,7 +81,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type)
enum fixed_addresses idx;
unsigned long vaddr;
- preempt_disable();
+ inc_preempt_count();
if (page < highmem_start_page)
return page_address(page);
@@ -104,7 +104,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type)
enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
if (vaddr < FIXADDR_START) { // FIXME
- preempt_enable();
+ dec_preempt_count();
return;
}
@@ -119,7 +119,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type)
__flush_tlb_one(vaddr);
#endif
- preempt_enable();
+ dec_preempt_count();
}
#endif /* __KERNEL__ */
diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h
index d565c78c2d81..d26bf652d894 100644
--- a/include/asm-i386/spinlock.h
+++ b/include/asm-i386/spinlock.h
@@ -158,6 +158,8 @@ typedef struct {
#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+#define rwlock_is_locked(x) ((x)->lock != RW_LOCK_BIAS)
+
/*
* On x86, we implement read-write locks as a 32-bit counter
* with the high bit (sign) being the "contended" bit.
diff --git a/include/asm-i386/tlbflush.h b/include/asm-i386/tlbflush.h
index c0c0388c9387..8b2e98c1425e 100644
--- a/include/asm-i386/tlbflush.h
+++ b/include/asm-i386/tlbflush.h
@@ -45,11 +45,21 @@ extern unsigned long pgkern_mask;
__flush_tlb(); \
} while (0)
-#ifndef CONFIG_X86_INVLPG
-#define __flush_tlb_one(addr) __flush_tlb()
+#define cpu_has_invlpg (boot_cpu_data.x86 > 3)
+
+#define __flush_tlb_single(addr) \
+ __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))
+
+#ifdef CONFIG_X86_INVLPG
+# define __flush_tlb_one(addr) __flush_tlb_single(addr)
#else
-#define __flush_tlb_one(addr) \
-__asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))
+# define __flush_tlb_one(addr) \
+ do { \
+ if (cpu_has_invlpg) \
+ __flush_tlb_single(addr); \
+ else \
+ __flush_tlb(); \
+ } while (0)
#endif
/*
diff --git a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h
index d56152a03ccc..547f2491000f 100644
--- a/include/asm-ppc/hardirq.h
+++ b/include/asm-ppc/hardirq.h
@@ -85,8 +85,10 @@ typedef struct {
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#if CONFIG_PREEMPT
+# define in_atomic() (preempt_count() != kernel_locked())
# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
#else
+# define in_atomic() (preempt_count() != 0)
# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
#endif
#define irq_exit() \
diff --git a/include/asm-ppc/highmem.h b/include/asm-ppc/highmem.h
index 5a630083d014..472482ca3f36 100644
--- a/include/asm-ppc/highmem.h
+++ b/include/asm-ppc/highmem.h
@@ -88,6 +88,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type)
unsigned int idx;
unsigned long vaddr;
+ inc_preempt_count();
if (page < highmem_start_page)
return page_address(page);
@@ -109,8 +110,10 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type)
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
unsigned int idx = type + KM_TYPE_NR*smp_processor_id();
- if (vaddr < KMAP_FIX_BEGIN) // FIXME
+ if (vaddr < KMAP_FIX_BEGIN) { // FIXME
+ dec_preempt_count();
return;
+ }
if (vaddr != KMAP_FIX_BEGIN + idx * PAGE_SIZE)
BUG();
@@ -122,6 +125,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type)
pte_clear(kmap_pte+idx);
flush_tlb_page(0, vaddr);
#endif
+ dec_preempt_count();
}
#endif /* __KERNEL__ */
diff --git a/include/asm-sparc/hardirq.h b/include/asm-sparc/hardirq.h
index a80212dc3a2a..f77ee7e415cf 100644
--- a/include/asm-sparc/hardirq.h
+++ b/include/asm-sparc/hardirq.h
@@ -113,6 +113,12 @@ do { \
#define irq_exit() br_read_unlock(BR_GLOBALIRQ_LOCK)
#endif
+#if CONFIG_PREEMPT
+# define in_atomic() (preempt_count() != kernel_locked())
+#else
+# define in_atomic() (preempt_count() != 0)
+#endif
+
#ifndef CONFIG_SMP
#define synchronize_irq() barrier()
diff --git a/include/asm-sparc/highmem.h b/include/asm-sparc/highmem.h
index bb2fc2331b5b..2ba438ea6111 100644
--- a/include/asm-sparc/highmem.h
+++ b/include/asm-sparc/highmem.h
@@ -83,6 +83,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type)
unsigned long idx;
unsigned long vaddr;
+ inc_preempt_count();
if (page < highmem_start_page)
return page_address(page);
@@ -116,8 +117,10 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type)
unsigned long vaddr = (unsigned long) kvaddr;
unsigned long idx = type + KM_TYPE_NR*smp_processor_id();
- if (vaddr < FIX_KMAP_BEGIN) // FIXME
+ if (vaddr < FIX_KMAP_BEGIN) { // FIXME
+ dec_preempt_count();
return;
+ }
if (vaddr != FIX_KMAP_BEGIN + idx * PAGE_SIZE)
BUG();
@@ -142,6 +145,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type)
flush_tlb_all();
#endif
#endif
+ dec_preempt_count();
}
#endif /* __KERNEL__ */
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 9f1ac6d07fe8..a11b6181c76f 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -281,10 +281,7 @@ struct sec_size {
extern struct sec_size * blk_sec[MAX_BLKDEV];
extern struct blk_dev_struct blk_dev[MAX_BLKDEV];
-extern void grok_partitions(kdev_t dev, long size);
-extern int wipe_partitions(kdev_t dev);
extern void register_disk(struct gendisk *dev, kdev_t first, unsigned minors, struct block_device_operations *ops, long size);
-extern void check_partition(struct gendisk *disk, struct block_device *bdev);
extern void generic_make_request(struct bio *bio);
extern inline request_queue_t *bdev_get_queue(struct block_device *bdev);
extern void blk_put_request(struct request *);
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index fd9f5a8d7c06..ecd747fbe569 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -62,11 +62,12 @@ struct hd_struct {
unsigned long start_sect;
unsigned long nr_sects;
devfs_handle_t de; /* primary (master) devfs entry */
- int number; /* stupid old code wastes space */
struct device hd_driverfs_dev; /* support driverfs hiearchy */
};
#define GENHD_FL_REMOVABLE 1
+#define GENHD_FL_DRIVERFS 2
+#define GENHD_FL_DEVFS 4
struct gendisk {
int major; /* major number of driver */
@@ -76,24 +77,35 @@ struct gendisk {
get real minor */
struct hd_struct *part; /* [indexed by minor] */
- int nr_real; /* number of real devices */
-
struct gendisk *next;
struct block_device_operations *fops;
-
- devfs_handle_t *de_arr; /* one per physical disc */
- struct device **driverfs_dev_arr;/* support driverfs hierarchy */
- char *flags; /* one per physical disc */
+ sector_t capacity;
+
+ int flags;
+ int number; /* devfs crap */
+ devfs_handle_t de; /* more of the same */
+ devfs_handle_t disk_de; /* piled higher and deeper */
+ struct device *driverfs_dev;
+ struct device disk_dev;
};
/* drivers/block/genhd.c */
extern void add_gendisk(struct gendisk *gp);
extern void del_gendisk(struct gendisk *gp);
+extern void unlink_gendisk(struct gendisk *gp);
extern struct gendisk *get_gendisk(kdev_t dev);
static inline unsigned long get_start_sect(struct block_device *bdev)
{
return bdev->bd_offset;
}
+static inline sector_t get_capacity(struct gendisk *disk)
+{
+ return disk->capacity;
+}
+static inline void set_capacity(struct gendisk *disk, sector_t size)
+{
+ disk->capacity = size;
+}
#endif /* __KERNEL__ */
@@ -242,11 +254,10 @@ struct unixware_disklabel {
#ifdef __KERNEL__
-char *disk_name (struct gendisk *hd, int minor, char *buf);
+char *disk_name (struct gendisk *hd, int part, char *buf);
-extern void devfs_register_partitions (struct gendisk *dev, int minor,
- int unregister);
-extern void driverfs_remove_partitions (struct gendisk *hd, int minor);
+extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
+extern void update_partition(struct gendisk *disk, int part);
static inline unsigned int disk_index (kdev_t dev)
{
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index b389a75be5d7..370177037315 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -24,8 +24,8 @@ static inline void *kmap(struct page *page) { return page_address(page); }
#define kunmap(page) do { (void) (page); } while (0)
-#define kmap_atomic(page,idx) kmap(page)
-#define kunmap_atomic(page,idx) kunmap(page)
+#define kmap_atomic(page, idx) page_address(page)
+#define kunmap_atomic(addr, idx) do { } while (0)
#endif /* CONFIG_HIGHMEM */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 98a2db1db397..1843237adf4a 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -506,7 +506,6 @@ typedef struct ide_drive_s {
unsigned int drive_data; /* for use by tuneproc/selectproc as needed */
struct hwif_s *hwif; /* actually (ide_hwif_t *) */
struct hd_driveid *id; /* drive model identification info */
- struct hd_struct *part; /* drive partition table */
char name[4]; /* drive name, such as "hda" */
struct ide_driver_s *driver; /* (ide_driver_t *) */
void *driver_data; /* extra driver data */
@@ -528,6 +527,7 @@ typedef struct ide_drive_s {
unsigned int failures; /* current failure count */
unsigned int max_failures; /* maximum allowed failure count */
struct list_head list;
+ struct gendisk *disk;
} ide_drive_t;
/*
@@ -714,7 +714,6 @@ typedef struct hwif_s {
*/
hw_regs_t hw; /* Hardware info */
ide_drive_t drives[MAX_DRIVES]; /* drive info */
- struct gendisk *gd[MAX_DRIVES];/* gendisk structure */
int addressing; /* hosts addressing */
void (*tuneproc)(ide_drive_t *, byte); /* routine to tune PIO mode for drives */
int (*speedproc)(ide_drive_t *, byte); /* routine to retune DMA modes for drives */
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 80a57914bccc..bdf03241a009 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -29,10 +29,11 @@
.mmlist = LIST_HEAD_INIT(name.mmlist), \
}
-#define INIT_SIGNALS { \
+#define INIT_SIGNALS(sig) { \
.count = ATOMIC_INIT(1), \
.action = { {{0,}}, }, \
- .siglock = SPIN_LOCK_UNLOCKED \
+ .siglock = SPIN_LOCK_UNLOCKED, \
+ .shared_pending = { NULL, &sig.shared_pending.head, {{0}}}, \
}
/*
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 3c76341f02bf..b82ec8e41174 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -386,6 +386,9 @@ struct pci_dev {
int ro; /* ISAPnP: read only */
unsigned short regs; /* ISAPnP: supported registers */
+ /* These fields are used by common fixups */
+ unsigned short transparent:1; /* Transparent PCI bridge */
+
int (*prepare)(struct pci_dev *dev); /* ISAPnP hooks */
int (*activate)(struct pci_dev *dev);
int (*deactivate)(struct pci_dev *dev);
@@ -406,6 +409,10 @@ struct pci_dev {
#define PCI_ROM_RESOURCE 6
#define PCI_BRIDGE_RESOURCES 7
#define PCI_NUM_RESOURCES 11
+
+#ifndef PCI_BUS_NUM_RESOURCES
+#define PCI_BUS_NUM_RESOURCES 4
+#endif
#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */
@@ -415,7 +422,8 @@ struct pci_bus {
struct list_head children; /* list of child buses */
struct list_head devices; /* list of devices on this bus */
struct pci_dev *self; /* bridge device as seen by parent */
- struct resource *resource[4]; /* address space routed to this bus */
+ struct resource *resource[PCI_BUS_NUM_RESOURCES];
+ /* address space routed to this bus */
struct pci_ops *ops; /* configuration access functions */
void *sysdata; /* hook for sys-specific extension */
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index b4ff1a7c881c..1b227b3c8ccb 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -48,9 +48,6 @@ do { \
preempt_check_resched(); \
} while (0)
-#define inc_preempt_count_non_preempt() do { } while (0)
-#define dec_preempt_count_non_preempt() do { } while (0)
-
#else
#define preempt_disable() do { } while (0)
@@ -58,13 +55,6 @@ do { \
#define preempt_enable() do { } while (0)
#define preempt_check_resched() do { } while (0)
-/*
- * Sometimes we want to increment the preempt count, but we know that it's
- * already incremented if the kernel is compiled for preemptibility.
- */
-#define inc_preempt_count_non_preempt() inc_preempt_count()
-#define dec_preempt_count_non_preempt() dec_preempt_count()
-
#endif
#endif /* __LINUX_PREEMPT_H */
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index a9cca6e4da8f..f95cdf658a39 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -61,7 +61,6 @@
#define MD_PATCHLEVEL_VERSION 0
extern int md_size[MAX_MD_DEVS];
-extern struct hd_struct md_hd_struct[MAX_MD_DEVS];
extern char * partition_name (kdev_t dev);
extern inline char * bdev_partition_name (struct block_device *bdev)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 896b7f59941c..bd7073fdefaf 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -211,6 +211,11 @@ struct signal_struct {
atomic_t count;
struct k_sigaction action[_NSIG];
spinlock_t siglock;
+
+ /* current thread group signal load-balancing target: */
+ task_t *curr_target;
+
+ struct sigpending shared_pending;
};
/*
@@ -356,7 +361,7 @@ struct task_struct {
spinlock_t sigmask_lock; /* Protects signal and blocked */
struct signal_struct *sig;
- sigset_t blocked;
+ sigset_t blocked, real_blocked, shared_unblocked;
struct sigpending pending;
unsigned long sas_ss_sp;
@@ -431,6 +436,7 @@ extern void set_cpus_allowed(task_t *p, unsigned long new_mask);
extern void set_user_nice(task_t *p, long nice);
extern int task_prio(task_t *p);
extern int task_nice(task_t *p);
+extern int task_curr(task_t *p);
extern int idle_cpu(int cpu);
void yield(void);
@@ -535,7 +541,7 @@ extern void proc_caches_init(void);
extern void flush_signals(struct task_struct *);
extern void flush_signal_handlers(struct task_struct *);
extern void sig_exit(int, int, struct siginfo *);
-extern int dequeue_signal(sigset_t *, siginfo_t *);
+extern int dequeue_signal(struct sigpending *pending, sigset_t *mask, siginfo_t *info);
extern void block_all_signals(int (*notifier)(void *priv), void *priv,
sigset_t *mask);
extern void unblock_all_signals(void);
@@ -654,6 +660,7 @@ extern void exit_thread(void);
extern void exit_mm(struct task_struct *);
extern void exit_files(struct task_struct *);
extern void exit_sighand(struct task_struct *);
+extern void remove_thread_group(struct task_struct *tsk, struct signal_struct *sig);
extern void reparent_to_init(void);
extern void daemonize(void);
@@ -786,8 +793,29 @@ static inline struct task_struct *younger_sibling(struct task_struct *p)
#define for_each_thread(task) \
for (task = next_thread(current) ; task != current ; task = next_thread(task))
-#define next_thread(p) \
- list_entry((p)->thread_group.next, struct task_struct, thread_group)
+static inline task_t *next_thread(task_t *p)
+{
+ if (!p->sig)
+ BUG();
+#if CONFIG_SMP
+ if (!spin_is_locked(&p->sig->siglock) &&
+ !rwlock_is_locked(&tasklist_lock))
+ BUG();
+#endif
+ return list_entry((p)->thread_group.next, task_t, thread_group);
+}
+
+static inline task_t *prev_thread(task_t *p)
+{
+ if (!p->sig)
+ BUG();
+#if CONFIG_SMP
+ if (!spin_is_locked(&p->sig->siglock) &&
+ !rwlock_is_locked(&tasklist_lock))
+ BUG();
+#endif
+ return list_entry((p)->thread_group.prev, task_t, thread_group);
+}
#define thread_group_leader(p) (p->pid == p->tgid)
@@ -903,21 +931,8 @@ static inline void cond_resched(void)
This is required every time the blocked sigset_t changes.
Athread cathreaders should have t->sigmask_lock. */
-static inline void recalc_sigpending_tsk(struct task_struct *t)
-{
- if (has_pending_signals(&t->pending.signal, &t->blocked))
- set_tsk_thread_flag(t, TIF_SIGPENDING);
- else
- clear_tsk_thread_flag(t, TIF_SIGPENDING);
-}
-
-static inline void recalc_sigpending(void)
-{
- if (has_pending_signals(&current->pending.signal, &current->blocked))
- set_thread_flag(TIF_SIGPENDING);
- else
- clear_thread_flag(TIF_SIGPENDING);
-}
+extern FASTCALL(void recalc_sigpending_tsk(struct task_struct *t));
+extern void recalc_sigpending(void);
/*
* Wrappers for p->thread_info->cpu access. No-op on UP.
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 8f3246e92e22..f15d8bb2736a 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -28,6 +28,7 @@ extern asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
unsigned long flags, void *data);
extern asmlinkage long sys_mkdir(const char *name, int mode);
extern asmlinkage long sys_chdir(const char *name);
+extern asmlinkage long sys_fchdir(int fd);
extern asmlinkage long sys_chroot(const char *name);
extern asmlinkage long sys_unlink(const char *name);
extern asmlinkage long sys_symlink(const char *old, const char *new);
@@ -730,17 +731,13 @@ static void __init mount_root(void)
}
#ifdef CONFIG_BLK_DEV_INITRD
+static int old_fd, root_fd;
static int do_linuxrc(void * shell)
{
static char *argv[] = { "linuxrc", NULL, };
extern char * envp_init[];
- sys_chdir("/root");
- sys_mount(".", "/", NULL, MS_MOVE, NULL);
- sys_chroot(".");
-
- mount_devfs_fs ();
-
+ close(old_fd);close(root_fd);
close(0);close(1);close(2);
setsid();
(void) open("/dev/console",O_RDWR,0);
@@ -758,9 +755,16 @@ static void __init handle_initrd(void)
int i, pid;
create_dev("/dev/root.old", Root_RAM0, NULL);
+ /* mount initrd on rootfs' /root */
mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
sys_mkdir("/old", 0700);
- sys_chdir("/old");
+ root_fd = open("/", 0, 0);
+ old_fd = open("/old", 0, 0);
+ /* move initrd over / and chdir/chroot in initrd root */
+ sys_chdir("/root");
+ sys_mount(".", "/", NULL, MS_MOVE, NULL);
+ sys_chroot(".");
+ mount_devfs_fs ();
pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
if (pid > 0) {
@@ -768,7 +772,14 @@ static void __init handle_initrd(void)
yield();
}
- sys_mount("..", ".", NULL, MS_MOVE, NULL);
+ /* move initrd to rootfs' /old */
+ sys_fchdir(old_fd);
+ sys_mount("/", ".", NULL, MS_MOVE, NULL);
+ /* switch root and cwd back to / of rootfs */
+ sys_fchdir(root_fd);
+ sys_chroot(".");
+ close(old_fd);
+ close(root_fd);
sys_umount("/old/dev", 0);
if (real_root_dev == Root_RAM0) {
diff --git a/kernel/exit.c b/kernel/exit.c
index fb08ef1cb838..33078e550697 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -36,7 +36,6 @@ static inline void __unhash_process(struct task_struct *p)
nr_threads--;
unhash_pid(p);
REMOVE_LINKS(p);
- list_del(&p->thread_group);
p->pid = 0;
proc_dentry = p->proc_dentry;
if (unlikely(proc_dentry != NULL)) {
@@ -66,9 +65,14 @@ static void release_task(struct task_struct * p)
atomic_dec(&p->user->processes);
security_ops->task_free_security(p);
free_uid(p->user);
- BUG_ON(p->ptrace || !list_empty(&p->ptrace_list) ||
- !list_empty(&p->ptrace_children));
+ if (unlikely(p->ptrace)) {
+ write_lock_irq(&tasklist_lock);
+ __ptrace_unlink(p);
+ write_unlock_irq(&tasklist_lock);
+ }
+ BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
unhash_process(p);
+ exit_sighand(p);
release_thread(p);
if (p != current) {
@@ -240,7 +244,8 @@ void daemonize(void)
static void reparent_thread(task_t *p, task_t *reaper, task_t *child_reaper)
{
/* We dont want people slaying init */
- p->exit_signal = SIGCHLD;
+ if (p->exit_signal != -1)
+ p->exit_signal = SIGCHLD;
p->self_exec_id++;
/* Make sure we're not reparenting to ourselves */
@@ -408,18 +413,15 @@ void exit_mm(struct task_struct *tsk)
*/
static inline void forget_original_parent(struct task_struct * father)
{
- struct task_struct *p, *reaper;
+ struct task_struct *p, *reaper = father;
struct list_head *_p;
- read_lock(&tasklist_lock);
+ write_lock_irq(&tasklist_lock);
- /* Next in our thread group, if they're not already exiting */
- reaper = father;
- do {
- reaper = next_thread(reaper);
- if (!(reaper->flags & PF_EXITING))
- break;
- } while (reaper != father);
+ if (father->exit_signal != -1)
+ reaper = prev_thread(reaper);
+ else
+ reaper = child_reaper;
if (reaper == father)
reaper = child_reaper;
@@ -428,7 +430,7 @@ static inline void forget_original_parent(struct task_struct * father)
* There are only two places where our children can be:
*
* - in our child list
- * - in the global ptrace list
+ * - in our ptraced child list
*
* Search them and reparent children.
*/
@@ -440,17 +442,29 @@ static inline void forget_original_parent(struct task_struct * father)
p = list_entry(_p,struct task_struct,ptrace_list);
reparent_thread(p, reaper, child_reaper);
}
- read_unlock(&tasklist_lock);
+ write_unlock_irq(&tasklist_lock);
}
-static inline void zap_thread(task_t *p, task_t *father)
+static inline void zap_thread(task_t *p, task_t *father, int traced)
{
- ptrace_unlink(p);
- list_del_init(&p->sibling);
- p->ptrace = 0;
+ /* If someone else is tracing this thread, preserve the ptrace links. */
+ if (unlikely(traced)) {
+ task_t *trace_task = p->parent;
+ int ptrace_flag = p->ptrace;
+ BUG_ON (ptrace_flag == 0);
+
+ __ptrace_unlink(p);
+ p->ptrace = ptrace_flag;
+ __ptrace_link(p, trace_task);
+ } else {
+ /* Otherwise, if we were tracing this thread, untrace it. */
+ ptrace_unlink (p);
+
+ list_del_init(&p->sibling);
+ p->parent = p->real_parent;
+ list_add_tail(&p->sibling, &p->parent->children);
+ }
- p->parent = p->real_parent;
- list_add_tail(&p->sibling, &p->parent->children);
if (p->state == TASK_ZOMBIE && p->exit_signal != -1)
do_notify_parent(p, p->exit_signal);
/*
@@ -518,7 +532,7 @@ static void exit_notify(void)
*
*/
- if(current->exit_signal != SIGCHLD &&
+ if (current->exit_signal != SIGCHLD && current->exit_signal != -1 &&
( current->parent_exec_id != t->self_exec_id ||
current->self_exec_id != current->parent_exec_id)
&& !capable(CAP_KILL))
@@ -541,11 +555,11 @@ static void exit_notify(void)
zap_again:
list_for_each_safe(_p, _n, &current->children)
- zap_thread(list_entry(_p,struct task_struct,sibling), current);
+ zap_thread(list_entry(_p,struct task_struct,sibling), current, 0);
list_for_each_safe(_p, _n, &current->ptrace_children)
- zap_thread(list_entry(_p,struct task_struct,ptrace_list), current);
+ zap_thread(list_entry(_p,struct task_struct,ptrace_list), current, 1);
/*
- * reparent_thread might drop the tasklist lock, thus we could
+ * zap_thread might drop the tasklist lock, thus we could
* have new children queued back from the ptrace list into the
* child list:
*/
@@ -588,7 +602,6 @@ fake_volatile:
__exit_files(tsk);
__exit_fs(tsk);
exit_namespace(tsk);
- exit_sighand(tsk);
exit_thread();
if (current->leader)
@@ -634,6 +647,41 @@ asmlinkage long sys_exit(int error_code)
do_exit((error_code&0xff)<<8);
}
+static inline int eligible_child(pid_t pid, int options, task_t *p)
+{
+ if (pid>0) {
+ if (p->pid != pid)
+ return 0;
+ } else if (!pid) {
+ if (p->pgrp != current->pgrp)
+ return 0;
+ } else if (pid != -1) {
+ if (p->pgrp != -pid)
+ return 0;
+ }
+
+ /*
+ * Do not consider detached threads that are
+ * not ptraced:
+ */
+ if (p->exit_signal == -1 && !p->ptrace)
+ return 0;
+
+ /* Wait for all children (clone and not) if __WALL is set;
+ * otherwise, wait for clone children *only* if __WCLONE is
+ * set; otherwise, wait for non-clone children *only*. (Note:
+ * A "clone" child here is one that reports to its parent
+ * using a signal other than SIGCHLD.) */
+ if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0))
+ && !(options & __WALL))
+ return 0;
+
+ if (security_ops->task_wait(p))
+ return 0;
+
+ return 1;
+}
+
asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru)
{
int flag, retval;
@@ -654,34 +702,8 @@ repeat:
struct list_head *_p;
list_for_each(_p,&tsk->children) {
p = list_entry(_p,struct task_struct,sibling);
- if (pid>0) {
- if (p->pid != pid)
- continue;
- } else if (!pid) {
- if (p->pgrp != current->pgrp)
- continue;
- } else if (pid != -1) {
- if (p->pgrp != -pid)
- continue;
- }
- /*
- * Do not consider detached threads that are
- * not ptraced:
- */
- if (p->exit_signal == -1 && !p->ptrace)
- continue;
- /* Wait for all children (clone and not) if __WALL is set;
- * otherwise, wait for clone children *only* if __WCLONE is
- * set; otherwise, wait for non-clone children *only*. (Note:
- * A "clone" child here is one that reports to its parent
- * using a signal other than SIGCHLD.) */
- if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0))
- && !(options & __WALL))
+ if (!eligible_child(pid, options, p))
continue;
-
- if (security_ops->task_wait(p))
- continue;
-
flag = 1;
switch (p->state) {
case TASK_STOPPED:
@@ -716,28 +738,33 @@ repeat:
retval = p->pid;
if (p->real_parent != p->parent) {
write_lock_irq(&tasklist_lock);
- ptrace_unlink(p);
+ __ptrace_unlink(p);
do_notify_parent(p, SIGCHLD);
write_unlock_irq(&tasklist_lock);
- } else {
- if (p->ptrace) {
- write_lock_irq(&tasklist_lock);
- ptrace_unlink(p);
- write_unlock_irq(&tasklist_lock);
- }
+ } else
release_task(p);
- }
goto end_wait4;
default:
continue;
}
}
+ if (!flag) {
+ list_for_each (_p,&tsk->ptrace_children) {
+ p = list_entry(_p,struct task_struct,ptrace_list);
+ if (!eligible_child(pid, options, p))
+ continue;
+ flag = 1;
+ break;
+ }
+ }
if (options & __WNOTHREAD)
break;
tsk = next_thread(tsk);
+ if (tsk->sig != current->sig)
+ BUG();
} while (tsk != current);
read_unlock(&tasklist_lock);
- if (flag || !list_empty(&current->ptrace_children)) {
+ if (flag) {
retval = 0;
if (options & WNOHANG)
goto end_wait4;
diff --git a/kernel/fork.c b/kernel/fork.c
index 7c9dc7841aa2..4e369b9734b6 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -630,6 +630,9 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * t
spin_lock_init(&sig->siglock);
atomic_set(&sig->count, 1);
memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action));
+ sig->curr_target = NULL;
+ init_sigpending(&sig->shared_pending);
+
return 0;
}
@@ -664,6 +667,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
return ERR_PTR(-EINVAL);
+ /*
+ * Thread groups must share signals as well:
+ */
+ if (clone_flags & CLONE_THREAD)
+ clone_flags |= CLONE_SIGHAND;
+
retval = security_ops->task_create(clone_flags);
if (retval)
goto fork_out;
@@ -836,21 +845,22 @@ static struct task_struct *copy_process(unsigned long clone_flags,
write_lock_irq(&tasklist_lock);
/* CLONE_PARENT re-uses the old parent */
- p->real_parent = current->real_parent;
- p->parent = current->parent;
- if (!(clone_flags & CLONE_PARENT)) {
+ if (clone_flags & CLONE_PARENT)
+ p->real_parent = current->real_parent;
+ else
p->real_parent = current;
- if (!(p->ptrace & PT_PTRACED))
- p->parent = current;
- }
+ p->parent = p->real_parent;
if (clone_flags & CLONE_THREAD) {
+ spin_lock(&current->sig->siglock);
p->tgid = current->tgid;
list_add(&p->thread_group, &current->thread_group);
+ spin_unlock(&current->sig->siglock);
}
SET_LINKS(p);
- ptrace_link(p, p->parent);
+ if (p->ptrace & PT_PTRACED)
+ __ptrace_link(p, current->parent);
hash_pid(p);
nr_threads++;
write_unlock_irq(&tasklist_lock);
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index f3e982d4aa52..3b03394fe14d 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -335,17 +335,13 @@ EXPORT_SYMBOL(blk_dev);
EXPORT_SYMBOL(bdev_read_only);
EXPORT_SYMBOL(set_device_ro);
EXPORT_SYMBOL(bmap);
-EXPORT_SYMBOL(devfs_register_partitions);
-EXPORT_SYMBOL(driverfs_remove_partitions);
EXPORT_SYMBOL(blkdev_open);
EXPORT_SYMBOL(blkdev_get);
EXPORT_SYMBOL(blkdev_put);
EXPORT_SYMBOL(ioctl_by_bdev);
-EXPORT_SYMBOL(grok_partitions);
EXPORT_SYMBOL(register_disk);
EXPORT_SYMBOL(read_dev_sector);
EXPORT_SYMBOL(init_buffer);
-EXPORT_SYMBOL(wipe_partitions);
EXPORT_SYMBOL_GPL(generic_file_direct_IO);
/* tty routines */
diff --git a/kernel/sched.c b/kernel/sched.c
index e1e08ecd37b4..625acc09ec17 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1336,6 +1336,15 @@ int task_nice(task_t *p)
}
/**
+ * task_curr - is this task currently executing on a CPU?
+ * @p: the task in question.
+ */
+int task_curr(task_t *p)
+{
+ return cpu_curr(task_cpu(p)) == p;
+}
+
+/**
* idle_cpu - is a given cpu idle currently?
* @cpu: the processor in question.
*/
diff --git a/kernel/signal.c b/kernel/signal.c
index 8de729b6ee20..5ca0ca83eb2f 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -6,6 +6,8 @@
* 1997-11-02 Modified for POSIX.1b signals by Richard Henderson
*/
+#define __KERNEL_SYSCALLS__
+
#include <linux/config.h>
#include <linux/slab.h>
#include <linux/module.h>
@@ -16,7 +18,7 @@
#include <linux/fs.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
-
+#include <asm/param.h>
#include <asm/uaccess.h>
#include <asm/siginfo.h>
@@ -24,40 +26,146 @@
* SLAB caches for signal bits.
*/
-#define DEBUG_SIG 0
-
-#if DEBUG_SIG
-#define SIG_SLAB_DEBUG (SLAB_RED_ZONE /* | SLAB_POISON */)
-#else
-#define SIG_SLAB_DEBUG 0
-#endif
-
static kmem_cache_t *sigqueue_cachep;
atomic_t nr_queued_signals;
int max_queued_signals = 1024;
+/*********************************************************
+
+ POSIX thread group signal behavior:
+
+----------------------------------------------------------
+| | userspace | kernel |
+----------------------------------------------------------
+| SIGHUP | load-balance | kill-all |
+| SIGINT | load-balance | kill-all |
+| SIGQUIT | load-balance | kill-all+core |
+| SIGILL | specific | kill-all+core |
+| SIGTRAP | specific | kill-all+core |
+| SIGABRT/SIGIOT | specific | kill-all+core |
+| SIGBUS | specific | kill-all+core |
+| SIGFPE | specific | kill-all+core |
+| SIGKILL | n/a | kill-all |
+| SIGUSR1 | load-balance | kill-all |
+| SIGSEGV | specific | kill-all+core |
+| SIGUSR2 | load-balance | kill-all |
+| SIGPIPE | specific | kill-all |
+| SIGALRM | load-balance | kill-all |
+| SIGTERM | load-balance | kill-all |
+| SIGCHLD | load-balance | ignore |
+| SIGCONT | specific | continue-all |
+| SIGSTOP | n/a | stop-all |
+| SIGTSTP | load-balance | stop-all |
+| SIGTTIN | load-balance | stop-all |
+| SIGTTOU | load-balance | stop-all |
+| SIGURG | load-balance | ignore |
+| SIGXCPU | specific | kill-all+core |
+| SIGXFSZ | specific | kill-all+core |
+| SIGVTALRM | load-balance | kill-all |
+| SIGPROF | specific | kill-all |
+| SIGPOLL/SIGIO | load-balance | kill-all |
+| SIGSYS/SIGUNUSED | specific | kill-all+core |
+| SIGSTKFLT | specific | kill-all |
+| SIGWINCH | load-balance | ignore |
+| SIGPWR | load-balance | kill-all |
+| SIGRTMIN-SIGRTMAX | load-balance | kill-all |
+----------------------------------------------------------
+*/
+
+#define M(sig) (1UL << (sig))
+
+#define SIG_USER_SPECIFIC_MASK (\
+ M(SIGILL) | M(SIGTRAP) | M(SIGABRT) | M(SIGBUS) | \
+ M(SIGFPE) | M(SIGSEGV) | M(SIGPIPE) | M(SIGXFSZ) | \
+ M(SIGPROF) | M(SIGSYS) | M(SIGSTKFLT) | M(SIGCONT) )
+
+#define SIG_USER_LOAD_BALANCE_MASK (\
+ M(SIGHUP) | M(SIGINT) | M(SIGQUIT) | M(SIGUSR1) | \
+ M(SIGUSR2) | M(SIGALRM) | M(SIGTERM) | M(SIGCHLD) | \
+ M(SIGURG) | M(SIGVTALRM) | M(SIGPOLL) | M(SIGWINCH) | \
+ M(SIGPWR) | M(SIGTSTP) | M(SIGTTIN) | M(SIGTTOU) )
+
+#define SIG_KERNEL_SPECIFIC_MASK (\
+ M(SIGCHLD) | M(SIGURG) | M(SIGWINCH) )
+
+#define SIG_KERNEL_BROADCAST_MASK (\
+ M(SIGHUP) | M(SIGINT) | M(SIGQUIT) | M(SIGILL) | \
+ M(SIGTRAP) | M(SIGABRT) | M(SIGBUS) | M(SIGFPE) | \
+ M(SIGKILL) | M(SIGUSR1) | M(SIGSEGV) | M(SIGUSR2) | \
+ M(SIGPIPE) | M(SIGALRM) | M(SIGTERM) | M(SIGXCPU) | \
+ M(SIGXFSZ) | M(SIGVTALRM) | M(SIGPROF) | M(SIGPOLL) | \
+ M(SIGSYS) | M(SIGSTKFLT) | M(SIGPWR) | M(SIGCONT) | \
+ M(SIGSTOP) | M(SIGTSTP) | M(SIGTTIN) | M(SIGTTOU) )
+
+#define SIG_KERNEL_ONLY_MASK (\
+ M(SIGKILL) | M(SIGSTOP) )
+
+#define SIG_KERNEL_COREDUMP_MASK (\
+ M(SIGQUIT) | M(SIGILL) | M(SIGTRAP) | M(SIGABRT) | \
+ M(SIGFPE) | M(SIGSEGV) | M(SIGBUS) | M(SIGSYS) | \
+ M(SIGXCPU) | M(SIGXFSZ) )
+
+#define T(sig, mask) \
+ ((1UL << (sig)) & mask)
+
+#define sig_user_specific(sig) T(sig, SIG_USER_SPECIFIC_MASK)
+#define sig_user_load_balance(sig) \
+ (T(sig, SIG_USER_LOAD_BALANCE_MASK) || ((sig) >= SIGRTMIN))
+#define sig_kernel_specific(sig) T(sig, SIG_KERNEL_SPECIFIC_MASK)
+#define sig_kernel_broadcast(sig) \
+ (T(sig, SIG_KERNEL_BROADCAST_MASK) || ((sig) >= SIGRTMIN))
+#define sig_kernel_only(sig) T(sig, SIG_KERNEL_ONLY_MASK)
+#define sig_kernel_coredump(sig) T(sig, SIG_KERNEL_COREDUMP_MASK)
+
+#define sig_user_defined(t, sig) \
+ (((t)->sig->action[(sig)-1].sa.sa_handler != SIG_DFL) && \
+ ((t)->sig->action[(sig)-1].sa.sa_handler != SIG_IGN))
+
+#define sig_ignored(t, sig) \
+ (((sig) != SIGCHLD) && \
+ ((t)->sig->action[(sig)-1].sa.sa_handler == SIG_IGN))
+
void __init signals_init(void)
{
sigqueue_cachep =
kmem_cache_create("sigqueue",
sizeof(struct sigqueue),
__alignof__(struct sigqueue),
- SIG_SLAB_DEBUG, NULL, NULL);
+ 0, NULL, NULL);
if (!sigqueue_cachep)
panic("signals_init(): cannot create sigqueue SLAB cache");
}
+#define PENDING(p,b) has_pending_signals(&(p)->signal, (b))
+
+void recalc_sigpending_tsk(struct task_struct *t)
+{
+ if (PENDING(&t->pending, &t->blocked) ||
+ PENDING(&t->sig->shared_pending, &t->blocked))
+ set_tsk_thread_flag(t, TIF_SIGPENDING);
+ else
+ clear_tsk_thread_flag(t, TIF_SIGPENDING);
+}
+
+void recalc_sigpending(void)
+{
+ if (PENDING(&current->pending, &current->blocked) ||
+ PENDING(&current->sig->shared_pending, &current->blocked))
+ set_thread_flag(TIF_SIGPENDING);
+ else
+ clear_thread_flag(TIF_SIGPENDING);
+}
/* Given the mask, find the first available signal that should be serviced. */
static int
-next_signal(struct task_struct *tsk, sigset_t *mask)
+next_signal(struct sigpending *pending, sigset_t *mask)
{
unsigned long i, *s, *m, x;
int sig = 0;
- s = tsk->pending.signal.sig;
+ s = pending->signal.sig;
m = mask->sig;
switch (_NSIG_WORDS) {
default:
@@ -113,15 +221,36 @@ flush_signals(struct task_struct *t)
flush_sigqueue(&t->pending);
}
+void remove_thread_group(struct task_struct *tsk, struct signal_struct *sig)
+{
+ write_lock_irq(&tasklist_lock);
+ spin_lock(&tsk->sig->siglock);
+
+ if (tsk == sig->curr_target)
+ sig->curr_target = next_thread(tsk);
+ list_del_init(&tsk->thread_group);
+
+ spin_unlock(&tsk->sig->siglock);
+ write_unlock_irq(&tasklist_lock);
+}
+
void exit_sighand(struct task_struct *tsk)
{
struct signal_struct * sig = tsk->sig;
+ if (!sig)
+ BUG();
+ if (!atomic_read(&sig->count))
+ BUG();
+ remove_thread_group(tsk, sig);
+
spin_lock_irq(&tsk->sigmask_lock);
if (sig) {
tsk->sig = NULL;
- if (atomic_dec_and_test(&sig->count))
+ if (atomic_dec_and_test(&sig->count)) {
+ flush_sigqueue(&sig->shared_pending);
kmem_cache_free(sigact_cachep, sig);
+ }
}
clear_tsk_thread_flag(tsk,TIF_SIGPENDING);
flush_sigqueue(&tsk->pending);
@@ -153,24 +282,10 @@ flush_signal_handlers(struct task_struct *t)
void
sig_exit(int sig, int exit_code, struct siginfo *info)
{
- struct task_struct *t;
-
sigaddset(&current->pending.signal, sig);
recalc_sigpending();
current->flags |= PF_SIGNALED;
- /* Propagate the signal to all the tasks in
- * our thread group
- */
- if (info && (unsigned long)info != 1
- && info->si_code != SI_TKILL) {
- read_lock(&tasklist_lock);
- for_each_thread(t) {
- force_sig_info(sig, info, t);
- }
- read_unlock(&tasklist_lock);
- }
-
do_exit(exit_code);
/* NOTREACHED */
}
@@ -209,7 +324,7 @@ unblock_all_signals(void)
spin_unlock_irqrestore(&current->sigmask_lock, flags);
}
-static int collect_signal(int sig, struct sigpending *list, siginfo_t *info)
+static inline int collect_signal(int sig, struct sigpending *list, siginfo_t *info)
{
if (sigismember(&list->signal, sig)) {
/* Collect the siginfo appropriate to this signal. */
@@ -221,9 +336,10 @@ static int collect_signal(int sig, struct sigpending *list, siginfo_t *info)
pp = &q->next;
}
- /* Ok, it wasn't in the queue. We must have
- been out of queue space. So zero out the
- info. */
+ /* Ok, it wasn't in the queue. This must be
+ a fast-pathed signal or we must have been
+ out of queue space. So zero out the info.
+ */
sigdelset(&list->signal, sig);
info->si_signo = sig;
info->si_errno = 0;
@@ -261,20 +377,14 @@ found_another:
* Dequeue a signal and return the element to the caller, which is
* expected to free it.
*
- * All callers must be holding current->sigmask_lock.
+ * All callers have to hold the siglock and the sigmask_lock.
*/
-int
-dequeue_signal(sigset_t *mask, siginfo_t *info)
+int dequeue_signal(struct sigpending *pending, sigset_t *mask, siginfo_t *info)
{
int sig = 0;
-#if DEBUG_SIG
-printk(KERN_DEBUG "SIG dequeue (%s:%d): %d ", current->comm, current->pid,
- signal_pending(current));
-#endif
-
- sig = next_signal(current, mask);
+ sig = next_signal(pending, mask);
if (sig) {
if (current->notifier) {
if (sigismember(current->notifier_mask, sig)) {
@@ -285,7 +395,7 @@ printk(KERN_DEBUG "SIG dequeue (%s:%d): %d ", current->comm, current->pid,
}
}
- if (!collect_signal(sig, &current->pending, info))
+ if (!collect_signal(sig, pending, info))
sig = 0;
/* XXX: Once POSIX.1b timers are in, if si_code == SI_TIMER,
@@ -293,10 +403,6 @@ printk(KERN_DEBUG "SIG dequeue (%s:%d): %d ", current->comm, current->pid,
}
recalc_sigpending();
-#if DEBUG_SIG
-printk(KERN_DEBUG " %d -> %d\n", signal_pending(current), sig);
-#endif
-
return sig;
}
@@ -338,9 +444,10 @@ static int rm_sig_from_queue(int sig, struct task_struct *t)
/*
* Bad permissions for sending the signal
*/
-int bad_signal(int sig, struct siginfo *info, struct task_struct *t)
+static inline int bad_signal(int sig, struct siginfo *info, struct task_struct *t)
{
- return (!info || ((unsigned long)info != 1 && SI_FROMUSER(info)))
+ return (!info || ((unsigned long)info != 1 &&
+ (unsigned long)info != 2 && SI_FROMUSER(info)))
&& ((sig != SIGCONT) || (current->session != t->session))
&& (current->euid ^ t->suid) && (current->euid ^ t->uid)
&& (current->uid ^ t->suid) && (current->uid ^ t->uid)
@@ -436,6 +543,13 @@ static int send_signal(int sig, struct siginfo *info, struct sigpending *signals
{
struct sigqueue * q = NULL;
+ /*
+ * fast-pathed signals for kernel-internal things like SIGSTOP
+ * or SIGKILL.
+ */
+ if ((unsigned long)info == 2)
+ goto out_set;
+
/* Real-time signals must be queued if sent by sigqueue, or
some other real-time mechanism. It is implementation
defined whether kill() does so. We attempt to do so, on
@@ -444,9 +558,8 @@ static int send_signal(int sig, struct siginfo *info, struct sigpending *signals
make sure at least one signal gets delivered and don't
pass on the info struct. */
- if (atomic_read(&nr_queued_signals) < max_queued_signals) {
+ if (atomic_read(&nr_queued_signals) < max_queued_signals)
q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
- }
if (q) {
atomic_inc(&nr_queued_signals);
@@ -473,14 +586,14 @@ static int send_signal(int sig, struct siginfo *info, struct sigpending *signals
break;
}
} else if (sig >= SIGRTMIN && info && (unsigned long)info != 1
- && info->si_code != SI_USER) {
+ && info->si_code != SI_USER)
/*
* Queue overflow, abort. We may abort if the signal was rt
* and sent by user using something other than kill().
*/
return -EAGAIN;
- }
+out_set:
sigaddset(&signals->signal, sig);
return 0;
}
@@ -528,17 +641,17 @@ static int deliver_signal(int sig, struct siginfo *info, struct task_struct *t)
return retval;
}
-int
-send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
+static int
+__send_sig_info(int sig, struct siginfo *info, struct task_struct *t, int shared)
{
- unsigned long flags;
int ret;
-
-#if DEBUG_SIG
-printk(KERN_DEBUG "SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
+ if (!irqs_disabled())
+ BUG();
+#if CONFIG_SMP
+ if (!spin_is_locked(&t->sig->siglock))
+ BUG();
#endif
-
ret = -EINVAL;
if (sig < 0 || sig > _NSIG)
goto out_nolock;
@@ -556,7 +669,7 @@ printk(KERN_DEBUG "SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
if (!sig || !t->sig)
goto out_nolock;
- spin_lock_irqsave(&t->sigmask_lock, flags);
+ spin_lock(&t->sigmask_lock);
handle_stop_signal(sig, t);
/* Optimize away the signal, if it's a signal that can be
@@ -566,20 +679,25 @@ printk(KERN_DEBUG "SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
if (ignored_signal(sig, t))
goto out;
- /* Support queueing exactly one non-rt signal, so that we
- can get more detailed information about the cause of
- the signal. */
- if (sig < SIGRTMIN && sigismember(&t->pending.signal, sig))
- goto out;
+#define LEGACY_QUEUE(sigptr, sig) \
+ (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
+
+ if (!shared) {
+ /* Support queueing exactly one non-rt signal, so that we
+ can get more detailed information about the cause of
+ the signal. */
+ if (LEGACY_QUEUE(&t->pending, sig))
+ goto out;
- ret = deliver_signal(sig, info, t);
+ ret = deliver_signal(sig, info, t);
+ } else {
+ if (LEGACY_QUEUE(&t->sig->shared_pending, sig))
+ goto out;
+ ret = send_signal(sig, info, &t->sig->shared_pending);
+ }
out:
- spin_unlock_irqrestore(&t->sigmask_lock, flags);
+ spin_unlock(&t->sigmask_lock);
out_nolock:
-#if DEBUG_SIG
-printk(KERN_DEBUG " %d -> %d\n", signal_pending(t), ret);
-#endif
-
return ret;
}
@@ -605,7 +723,157 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
recalc_sigpending_tsk(t);
spin_unlock_irqrestore(&t->sigmask_lock, flags);
- return send_sig_info(sig, info, t);
+ return send_sig_info(sig, (void *)1, t);
+}
+
+static int
+__force_sig_info(int sig, struct task_struct *t)
+{
+ unsigned long int flags;
+
+ spin_lock_irqsave(&t->sigmask_lock, flags);
+ if (t->sig == NULL) {
+ spin_unlock_irqrestore(&t->sigmask_lock, flags);
+ return -ESRCH;
+ }
+
+ if (t->sig->action[sig-1].sa.sa_handler == SIG_IGN)
+ t->sig->action[sig-1].sa.sa_handler = SIG_DFL;
+ sigdelset(&t->blocked, sig);
+ recalc_sigpending_tsk(t);
+ spin_unlock_irqrestore(&t->sigmask_lock, flags);
+
+ return __send_sig_info(sig, (void *)2, t, 0);
+}
+
+#define can_take_signal(p, sig) \
+ (((unsigned long) p->sig->action[sig-1].sa.sa_handler > 1) && \
+ !sigismember(&p->blocked, sig) && (task_curr(p) || !signal_pending(p)))
+
+static inline
+int load_balance_thread_group(struct task_struct *p, int sig,
+ struct siginfo *info)
+{
+ struct task_struct *tmp;
+ int ret;
+
+ /*
+ * if the specified thread is not blocking this signal
+ * then deliver it.
+ */
+ if (can_take_signal(p, sig))
+ return __send_sig_info(sig, info, p, 0);
+
+ /*
+ * Otherwise try to find a suitable thread.
+ * If no such thread is found then deliver to
+ * the original thread.
+ */
+
+ tmp = p->sig->curr_target;
+
+ if (!tmp || tmp->tgid != p->tgid)
+ /* restart balancing at this thread */
+ p->sig->curr_target = p;
+
+ else for (;;) {
+ if (list_empty(&p->thread_group))
+ BUG();
+ if (!tmp || tmp->tgid != p->tgid)
+ BUG();
+
+ /*
+ * Do not send signals that are ignored or blocked,
+ * or to not-running threads that are overworked:
+ */
+ if (!can_take_signal(tmp, sig)) {
+ tmp = next_thread(tmp);
+ p->sig->curr_target = tmp;
+ if (tmp == p)
+ break;
+ continue;
+ }
+ ret = __send_sig_info(sig, info, tmp, 0);
+ return ret;
+ }
+ /*
+ * No suitable thread was found - put the signal
+ * into the shared-pending queue.
+ */
+ return __send_sig_info(sig, info, p, 1);
+}
+
+int __broadcast_thread_group(struct task_struct *p, int sig)
+{
+ struct task_struct *tmp;
+ struct list_head *entry;
+ int err = 0;
+
+ /* send a signal to the head of the list */
+ err = __force_sig_info(sig, p);
+
+ /* send a signal to all members of the list */
+ list_for_each(entry, &p->thread_group) {
+ tmp = list_entry(entry, task_t, thread_group);
+ err = __force_sig_info(sig, tmp);
+ }
+ return err;
+}
+
+int
+send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ if (!p)
+ BUG();
+ if (!p->sig)
+ BUG();
+ spin_lock_irqsave(&p->sig->siglock, flags);
+
+ /* not a thread group - normal signal behavior */
+ if (list_empty(&p->thread_group) || !sig)
+ goto out_send;
+
+ if (sig_user_defined(p, sig)) {
+ if (sig_user_specific(sig))
+ goto out_send;
+ if (sig_user_load_balance(sig)) {
+ ret = load_balance_thread_group(p, sig, info);
+ goto out_unlock;
+ }
+
+ /* must not happen */
+ BUG();
+ }
+ /* optimize away ignored signals: */
+ if (sig_ignored(p, sig))
+ goto out_unlock;
+
+ /* blocked (or ptraced) signals get posted */
+ spin_lock(&p->sigmask_lock);
+ if ((p->ptrace & PT_PTRACED) || sigismember(&p->blocked, sig) ||
+ sigismember(&p->real_blocked, sig)) {
+ spin_unlock(&p->sigmask_lock);
+ goto out_send;
+ }
+ spin_unlock(&p->sigmask_lock);
+
+ if (sig_kernel_broadcast(sig) || sig_kernel_coredump(sig)) {
+ ret = __broadcast_thread_group(p, sig);
+ goto out_unlock;
+ }
+ if (sig_kernel_specific(sig))
+ goto out_send;
+
+ /* must not happen */
+ BUG();
+out_send:
+ ret = __send_sig_info(sig, info, p, 0);
+out_unlock:
+ spin_unlock_irqrestore(&p->sig->siglock, flags);
+ return ret;
}
/*
@@ -670,15 +938,8 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
error = -ESRCH;
- if (p) {
- if (!thread_group_leader(p)) {
- struct task_struct *tg;
- tg = find_task_by_pid(p->tgid);
- if (tg)
- p = tg;
- }
+ if (p)
error = send_sig_info(sig, info, p);
- }
read_unlock(&tasklist_lock);
return error;
}
@@ -755,25 +1016,36 @@ kill_proc(pid_t pid, int sig, int priv)
* Joy. Or not. Pthread wants us to wake up every thread
* in our parent group.
*/
-static void wake_up_parent(struct task_struct *parent)
+static inline void wake_up_parent(struct task_struct *p)
{
- struct task_struct *tsk = parent;
+ struct task_struct *parent = p->parent, *tsk = parent;
+ /*
+ * Fortunately this is not necessary for thread groups:
+ */
+ if (p->tgid == tsk->tgid) {
+ wake_up_interruptible(&tsk->wait_chldexit);
+ return;
+ }
+ spin_lock_irq(&parent->sig->siglock);
do {
wake_up_interruptible(&tsk->wait_chldexit);
tsk = next_thread(tsk);
+ if (tsk->sig != parent->sig)
+ BUG();
} while (tsk != parent);
+ spin_unlock_irq(&parent->sig->siglock);
}
/*
* Let a parent know about a status change of a child.
*/
+
void do_notify_parent(struct task_struct *tsk, int sig)
{
struct siginfo info;
int why, status;
- /* is the thread detached? */
if (sig == -1)
BUG();
@@ -812,7 +1084,7 @@ void do_notify_parent(struct task_struct *tsk, int sig)
info.si_status = status;
send_sig_info(sig, &info, tsk->parent);
- wake_up_parent(tsk->parent);
+ wake_up_parent(tsk);
}
@@ -837,13 +1109,24 @@ notify_parent(struct task_struct *tsk, int sig)
int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs)
{
+ sigset_t *mask = &current->blocked;
+
for (;;) {
- unsigned long signr;
+ unsigned long signr = 0;
struct k_sigaction *ka;
- spin_lock_irq(&current->sigmask_lock);
- signr = dequeue_signal(&current->blocked, info);
- spin_unlock_irq(&current->sigmask_lock);
+ local_irq_disable();
+ if (current->sig->shared_pending.head) {
+ spin_lock(&current->sig->siglock);
+ signr = dequeue_signal(&current->sig->shared_pending, mask, info);
+ spin_unlock(&current->sig->siglock);
+ }
+ if (!signr) {
+ spin_lock(&current->sigmask_lock);
+ signr = dequeue_signal(&current->pending, mask, info);
+ spin_unlock(&current->sigmask_lock);
+ }
+ local_irq_enable();
if (!signr)
break;
@@ -1137,8 +1420,11 @@ sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
return -EINVAL;
}
- spin_lock_irq(&current->sigmask_lock);
- sig = dequeue_signal(&these, &info);
+ spin_lock_irq(&current->sig->siglock);
+ spin_lock(&current->sigmask_lock);
+ sig = dequeue_signal(&current->sig->shared_pending, &these, &info);
+ if (!sig)
+ sig = dequeue_signal(&current->pending, &these, &info);
if (!sig) {
timeout = MAX_SCHEDULE_TIMEOUT;
if (uts)
@@ -1149,21 +1435,27 @@ sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
/* None ready -- temporarily unblock those we're
* interested while we are sleeping in so that we'll
* be awakened when they arrive. */
- sigset_t oldblocked = current->blocked;
+ current->real_blocked = current->blocked;
sigandsets(&current->blocked, &current->blocked, &these);
recalc_sigpending();
- spin_unlock_irq(&current->sigmask_lock);
+ spin_unlock(&current->sigmask_lock);
+ spin_unlock_irq(&current->sig->siglock);
current->state = TASK_INTERRUPTIBLE;
timeout = schedule_timeout(timeout);
- spin_lock_irq(&current->sigmask_lock);
- sig = dequeue_signal(&these, &info);
- current->blocked = oldblocked;
+ spin_lock_irq(&current->sig->siglock);
+ spin_lock(&current->sigmask_lock);
+ sig = dequeue_signal(&current->sig->shared_pending, &these, &info);
+ if (!sig)
+ sig = dequeue_signal(&current->pending, &these, &info);
+ current->blocked = current->real_blocked;
+ siginitset(&current->real_blocked, 0);
recalc_sigpending();
}
}
- spin_unlock_irq(&current->sigmask_lock);
+ spin_unlock(&current->sigmask_lock);
+ spin_unlock_irq(&current->sig->siglock);
if (sig) {
ret = sig;
@@ -1195,33 +1487,35 @@ sys_kill(int pid, int sig)
}
/*
- * Kill only one task, even if it's a CLONE_THREAD task.
+ * Send a signal to only one task, even if it's a CLONE_THREAD task.
*/
asmlinkage long
sys_tkill(int pid, int sig)
{
- struct siginfo info;
- int error;
- struct task_struct *p;
-
- /* This is only valid for single tasks */
- if (pid <= 0)
- return -EINVAL;
-
- info.si_signo = sig;
- info.si_errno = 0;
- info.si_code = SI_TKILL;
- info.si_pid = current->pid;
- info.si_uid = current->uid;
-
- read_lock(&tasklist_lock);
- p = find_task_by_pid(pid);
- error = -ESRCH;
- if (p) {
- error = send_sig_info(sig, &info, p);
- }
- read_unlock(&tasklist_lock);
- return error;
+ struct siginfo info;
+ int error;
+ struct task_struct *p;
+
+ /* This is only valid for single tasks */
+ if (pid <= 0)
+ return -EINVAL;
+
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = SI_TKILL;
+ info.si_pid = current->pid;
+ info.si_uid = current->uid;
+
+ read_lock(&tasklist_lock);
+ p = find_task_by_pid(pid);
+ error = -ESRCH;
+ if (p) {
+ spin_lock_irq(&p->sig->siglock);
+ error = __send_sig_info(sig, &info, p, 0);
+ spin_unlock_irq(&p->sig->siglock);
+ }
+ read_unlock(&tasklist_lock);
+ return error;
}
asmlinkage long
@@ -1247,13 +1541,12 @@ do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
{
struct k_sigaction *k;
- if (sig < 1 || sig > _NSIG ||
- (act && (sig == SIGKILL || sig == SIGSTOP)))
+ if (sig < 1 || sig > _NSIG || (act && sig_kernel_only(sig)))
return -EINVAL;
k = &current->sig->action[sig-1];
- spin_lock(&current->sig->siglock);
+ spin_lock_irq(&current->sig->siglock);
if (oact)
*oact = *k;
@@ -1292,7 +1585,7 @@ do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
}
}
- spin_unlock(&current->sig->siglock);
+ spin_unlock_irq(&current->sig->siglock);
return 0;
}
diff --git a/mm/filemap.c b/mm/filemap.c
index 771676ff57a9..4360f4a8c690 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1036,7 +1036,52 @@ no_cached_page:
UPDATE_ATIME(inode);
}
-int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
+/*
+ * Fault a userspace page into pagetables. Return non-zero on a fault.
+ *
+ * FIXME: this assumes that two userspace pages are always sufficient. That's
+ * not true if PAGE_CACHE_SIZE > PAGE_SIZE.
+ */
+static inline int fault_in_pages_writeable(char *uaddr, int size)
+{
+ int ret;
+
+ /*
+ * Writing zeroes into userspace here is OK, because we know that if
+ * the zero gets there, we'll be overwriting it.
+ */
+ ret = __put_user(0, uaddr);
+ if (ret == 0) {
+ char *end = uaddr + size - 1;
+
+ /*
+ * If the page was already mapped, this will get a cache miss
+ * for sure, so try to avoid doing it.
+ */
+ if (((unsigned long)uaddr & PAGE_MASK) !=
+ ((unsigned long)end & PAGE_MASK))
+ ret = __put_user(0, end);
+ }
+ return ret;
+}
+
+static inline void fault_in_pages_readable(const char *uaddr, int size)
+{
+ volatile char c;
+ int ret;
+
+ ret = __get_user(c, (char *)uaddr);
+ if (ret == 0) {
+ const char *end = uaddr + size - 1;
+
+ if (((unsigned long)uaddr & PAGE_MASK) !=
+ ((unsigned long)end & PAGE_MASK))
+ __get_user(c, (char *)end);
+ }
+}
+
+int file_read_actor(read_descriptor_t *desc, struct page *page,
+ unsigned long offset, unsigned long size)
{
char *kaddr;
unsigned long left, count = desc->count;
@@ -1044,14 +1089,28 @@ int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long o
if (size > count)
size = count;
+ /*
+ * Faults on the destination of a read are common, so do it before
+ * taking the kmap.
+ */
+ if (!fault_in_pages_writeable(desc->buf, size)) {
+ kaddr = kmap_atomic(page, KM_USER0);
+ left = __copy_to_user(desc->buf, kaddr + offset, size);
+ kunmap_atomic(kaddr, KM_USER0);
+ if (left == 0)
+ goto success;
+ }
+
+ /* Do it the slow way */
kaddr = kmap(page);
left = __copy_to_user(desc->buf, kaddr + offset, size);
kunmap(page);
-
+
if (left) {
size -= left;
desc->error = -EFAULT;
}
+success:
desc->count = count - size;
desc->written += size;
desc->buf += size;
@@ -1838,6 +1897,26 @@ inline void remove_suid(struct dentry *dentry)
}
}
+static inline int
+filemap_copy_from_user(struct page *page, unsigned long offset,
+ const char *buf, unsigned bytes)
+{
+ char *kaddr;
+ int left;
+
+ kaddr = kmap_atomic(page, KM_USER0);
+ left = __copy_from_user(kaddr + offset, buf, bytes);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ if (left != 0) {
+ /* Do it the slow way */
+ kaddr = kmap(page);
+ left = __copy_from_user(kaddr + offset, buf, bytes);
+ kunmap(page);
+ }
+ return left;
+}
+
/*
* Write to a file through the page cache.
*
@@ -1990,7 +2069,6 @@ ssize_t generic_file_write_nolock(struct file *file, const char *buf,
unsigned long index;
unsigned long offset;
long page_fault;
- char *kaddr;
offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
index = pos >> PAGE_CACHE_SHIFT;
@@ -2004,10 +2082,7 @@ ssize_t generic_file_write_nolock(struct file *file, const char *buf,
* same page as we're writing to, without it being marked
* up-to-date.
*/
- { volatile unsigned char dummy;
- __get_user(dummy, buf);
- __get_user(dummy, buf+bytes-1);
- }
+ fault_in_pages_readable(buf, bytes);
page = __grab_cache_page(mapping, index, &cached_page, &lru_pvec);
if (!page) {
@@ -2015,22 +2090,19 @@ ssize_t generic_file_write_nolock(struct file *file, const char *buf,
break;
}
- kaddr = kmap(page);
status = a_ops->prepare_write(file, page, offset, offset+bytes);
if (unlikely(status)) {
/*
* prepare_write() may have instantiated a few blocks
* outside i_size. Trim these off again.
*/
- kunmap(page);
unlock_page(page);
page_cache_release(page);
if (pos + bytes > inode->i_size)
vmtruncate(inode, inode->i_size);
break;
}
- page_fault = __copy_from_user(kaddr + offset, buf, bytes);
- flush_dcache_page(page);
+ page_fault = filemap_copy_from_user(page, offset, buf, bytes);
status = a_ops->commit_write(file, page, offset, offset+bytes);
if (unlikely(page_fault)) {
status = -EFAULT;
@@ -2045,7 +2117,6 @@ ssize_t generic_file_write_nolock(struct file *file, const char *buf,
buf += status;
}
}
- kunmap(page);
if (!PageReferenced(page))
SetPageReferenced(page);
unlock_page(page);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index b3da592923f4..1dc363b27b98 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -782,10 +782,9 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
const unsigned long zone_required_alignment = 1UL << (MAX_ORDER-1);
totalpages = 0;
- for (i = 0; i < MAX_NR_ZONES; i++) {
- unsigned long size = zones_size[i];
- totalpages += size;
- }
+ for (i = 0; i < MAX_NR_ZONES; i++)
+ totalpages += zones_size[i];
+
realtotalpages = totalpages;
if (zholes_size)
for (i = 0; i < MAX_NR_ZONES; i++)
@@ -823,7 +822,7 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
if (zholes_size)
realsize -= zholes_size[j];
- printk("zone(%lu): %lu pages.\n", j, size);
+ printk(" %s zone: %lu pages\n", zone_names[j], realsize);
zone->size = size;
zone->name = zone_names[j];
spin_lock_init(&zone->lock);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index a00fe27159d9..5ed1ec3eda52 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -483,7 +483,7 @@ shrink_zone(struct zone *zone, int priority,
ratio = (unsigned long)nr_pages * zone->nr_active /
((zone->nr_inactive | 1) * 2);
atomic_add(ratio+1, &zone->refill_counter);
- if (atomic_read(&zone->refill_counter) > SWAP_CLUSTER_MAX) {
+ while (atomic_read(&zone->refill_counter) > SWAP_CLUSTER_MAX) {
atomic_sub(SWAP_CLUSTER_MAX, &zone->refill_counter);
refill_inactive_zone(zone, SWAP_CLUSTER_MAX);
}
@@ -517,7 +517,7 @@ shrink_caches(struct zone *classzone, int priority,
first_classzone = classzone->zone_pgdat->node_zones;
zone = classzone;
- while (zone >= first_classzone) {
+ while (zone >= first_classzone && nr_pages > 0) {
if (zone->free_pages <= zone->pages_high) {
nr_pages = shrink_zone(zone, priority,
gfp_mask, nr_pages);