summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2002-09-09 08:01:06 +1000
committerAnton Blanchard <anton@samba.org>2002-09-09 08:01:06 +1000
commitb2a5f08a83d248313436b1a6d83eec1cfd4eaf63 (patch)
treef4a26ba9089791e3499efa9bcabc4f24048a0e84
parent17659443e63dd859e4ca035a20ea89e6773fc385 (diff)
parent165088f970e9baa5a0b3d63313c869605e8f99f8 (diff)
Merge samba.org:/scratch/anton/linux-2.5
into samba.org:/scratch/anton/linux-2.5_bar
-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--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/paride/pcd.c1045
-rw-r--r--drivers/block/paride/pd.c10
-rw-r--r--drivers/block/ps2esdi.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/s390/block/dasd.c4
-rw-r--r--drivers/s390/block/dasd_genhd.c16
-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--fs/block_dev.c62
-rw-r--r--fs/partitions/check.c464
-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/linux/blkdev.h3
-rw-r--r--include/linux/genhd.h33
-rw-r--r--include/linux/ide.h3
-rw-r--r--include/linux/raid/md.h1
-rw-r--r--kernel/exit.c124
-rw-r--r--kernel/fork.c13
-rw-r--r--kernel/ksyms.c4
76 files changed, 2565 insertions, 2846 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/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/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/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/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/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/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/partitions/check.c b/fs/partitions/check.c
index 907cb1faf056..75f096ff1e9a 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,92 @@ 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);
+ dev_t dev = bdev->bd_dev;
char buf[64];
struct parsed_partitions *state;
int i;
@@ -267,17 +222,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 +245,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(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 +313,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 +358,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 +379,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 +462,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/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/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/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/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/kernel/exit.c b/kernel/exit.c
index fb08ef1cb838..7fe43d30ef87 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -66,8 +66,12 @@ 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);
release_thread(p);
@@ -428,7 +432,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.
*/
@@ -443,14 +447,26 @@ static inline void forget_original_parent(struct task_struct * father)
read_unlock(&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);
/*
@@ -541,11 +557,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:
*/
@@ -634,6 +650,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 +705,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))
- continue;
-
- if (security_ops->task_wait(p))
+ if (!eligible_child(pid, options, p))
continue;
-
flag = 1;
switch (p->state) {
case TASK_STOPPED:
@@ -716,28 +741,31 @@ 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);
} 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..7166c99e9f9c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -836,13 +836,11 @@ 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) {
p->tgid = current->tgid;
@@ -850,7 +848,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
}
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 */