Commit 5d7fa0ad authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/sparc-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents dff076a0 6ecabc8f
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
export-objs := backend.o export-objs := backend.o
agpgart-y := backend.o frontend.o generic.o agpgart-y := backend.o frontend.o generic.o
agpgart-$(CONFIG_AGP3) += generic-3.0.o
agpgart-objs := $(agpgart-y) agpgart-objs := $(agpgart-y)
obj-$(CONFIG_AGP) += agpgart.o obj-$(CONFIG_AGP) += agpgart.o
obj-$(CONFIG_AGP3) += generic-3.0.o
obj-$(CONFIG_AGP_INTEL) += intel-agp.o obj-$(CONFIG_AGP_INTEL) += intel-agp.o
obj-$(CONFIG_AGP_VIA) += via-agp.o obj-$(CONFIG_AGP_VIA) += via-agp.o
......
...@@ -33,6 +33,7 @@ extern struct agp_bridge_data agp_bridge; ...@@ -33,6 +33,7 @@ extern struct agp_bridge_data agp_bridge;
/* Generic routines. */ /* Generic routines. */
void agp_generic_agp_enable(u32 mode); void agp_generic_agp_enable(u32 mode);
int agp_generic_agp_3_0_enable(u32 mode);
int agp_generic_create_gatt_table(void); int agp_generic_create_gatt_table(void);
int agp_generic_free_gatt_table(void); int agp_generic_free_gatt_table(void);
agp_memory *agp_create_memory(int scratch_pages); agp_memory *agp_create_memory(int scratch_pages);
...@@ -290,6 +291,9 @@ struct agp_bridge_data { ...@@ -290,6 +291,9 @@ struct agp_bridge_data {
#define VIA_APSIZE 0x84 #define VIA_APSIZE 0x84
#define VIA_ATTBASE 0x88 #define VIA_ATTBASE 0x88
/* VIA KT400 */
#define VIA_AGPSEL 0xfd
/* SiS registers */ /* SiS registers */
#define SIS_APBASE 0x10 #define SIS_APBASE 0x10
#define SIS_ATTBASE 0x90 #define SIS_ATTBASE 0x90
......
...@@ -195,7 +195,7 @@ static struct aper_size_info_32 ali_generic_sizes[7] = ...@@ -195,7 +195,7 @@ static struct aper_size_info_32 ali_generic_sizes[7] =
{4, 1024, 0, 3} {4, 1024, 0, 3}
}; };
int __init ali_generic_setup (struct pci_dev *pdev) static int __init ali_generic_setup (struct pci_dev *pdev)
{ {
agp_bridge.masks = ali_generic_masks; agp_bridge.masks = ali_generic_masks;
agp_bridge.num_of_masks = 1; agp_bridge.num_of_masks = 1;
...@@ -338,17 +338,20 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev) ...@@ -338,17 +338,20 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
} }
static int __init agp_ali_probe (struct pci_dev *dev, const struct pci_device_id *ent)
static int agp_ali_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0) u8 cap_ptr = 0;
return -ENODEV;
agp_bridge.dev = dev; cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (cap_ptr == 0)
return -ENODEV;
/* probe for known chipsets */ /* probe for known chipsets */
if (agp_lookup_host_bridge (dev) != -ENODEV ) { if (agp_lookup_host_bridge(dev) != -ENODEV) {
agp_bridge.dev = dev;
agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
agp_register_driver(dev); agp_register_driver(dev);
return 0; return 0;
} }
...@@ -369,7 +372,7 @@ static struct pci_device_id agp_ali_pci_table[] __initdata = { ...@@ -369,7 +372,7 @@ static struct pci_device_id agp_ali_pci_table[] __initdata = {
MODULE_DEVICE_TABLE(pci, agp_ali_pci_table); MODULE_DEVICE_TABLE(pci, agp_ali_pci_table);
static struct pci_driver agp_ali_pci_driver = { static struct __initdata pci_driver agp_ali_pci_driver = {
.name = "agpgart-ali", .name = "agpgart-ali",
.id_table = agp_ali_pci_table, .id_table = agp_ali_pci_table,
.probe = agp_ali_probe, .probe = agp_ali_probe,
......
...@@ -351,7 +351,7 @@ static struct gatt_mask amd_irongate_masks[] = ...@@ -351,7 +351,7 @@ static struct gatt_mask amd_irongate_masks[] =
{.mask = 0x00000001, .type = 0} {.mask = 0x00000001, .type = 0}
}; };
int __init amd_irongate_setup (struct pci_dev *pdev) static int __init amd_irongate_setup (struct pci_dev *pdev)
{ {
agp_bridge.masks = amd_irongate_masks; agp_bridge.masks = amd_irongate_masks;
agp_bridge.num_of_masks = 1; agp_bridge.num_of_masks = 1;
...@@ -439,21 +439,19 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev) ...@@ -439,21 +439,19 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
/* Supported Device Scanning routine */ /* Supported Device Scanning routine */
static int __init agp_find_supported_device(struct pci_dev *dev) static int __init agp_amdk7_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
agp_bridge.dev = dev; u8 cap_ptr = 0;
if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0) cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (cap_ptr == 0)
return -ENODEV; return -ENODEV;
/* probe for known chipsets */ if (agp_lookup_host_bridge(dev) != -ENODEV) {
return agp_lookup_host_bridge (dev); agp_bridge.dev = dev;
} agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
static int agp_amdk7_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
if (agp_find_supported_device(dev) == 0) {
agp_register_driver(dev); agp_register_driver(dev);
return 0; return 0;
} }
...@@ -474,7 +472,7 @@ static struct pci_device_id agp_amdk7_pci_table[] __initdata = { ...@@ -474,7 +472,7 @@ static struct pci_device_id agp_amdk7_pci_table[] __initdata = {
MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table); MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table);
static struct pci_driver agp_amdk7_pci_driver = { static struct __initdata pci_driver agp_amdk7_pci_driver = {
.name = "agpgart-amdk7", .name = "agpgart-amdk7",
.id_table = agp_amdk7_pci_table, .id_table = agp_amdk7_pci_table,
.probe = agp_amdk7_probe, .probe = agp_amdk7_probe,
......
...@@ -370,7 +370,7 @@ static void agp_x86_64_agp_enable(u32 mode) ...@@ -370,7 +370,7 @@ static void agp_x86_64_agp_enable(u32 mode)
} }
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &command); pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &command);
/* /*
* PASS2: go through all devices that claim to be * PASS2: go through all devices that claim to be
...@@ -429,7 +429,7 @@ static void agp_x86_64_agp_enable(u32 mode) ...@@ -429,7 +429,7 @@ static void agp_x86_64_agp_enable(u32 mode)
command |= 0x100; command |= 0x100;
pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx + 8, command); pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx+8, command);
/* /*
* PASS4: Go through all AGP devices and update the * PASS4: Go through all AGP devices and update the
...@@ -475,11 +475,19 @@ static int __init amd_8151_setup (struct pci_dev *pdev) ...@@ -475,11 +475,19 @@ static int __init amd_8151_setup (struct pci_dev *pdev)
} }
static int agp_amdk8_probe (struct pci_dev *dev, const struct pci_device_id *ent) static int __init agp_amdk8_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0) u8 cap_ptr = 0;
cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (cap_ptr == 0)
return -ENODEV; return -ENODEV;
agp_bridge.dev = dev;
agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
amd_8151_setup(dev); amd_8151_setup(dev);
agp_register_driver(dev); agp_register_driver(dev);
return 0; return 0;
...@@ -499,7 +507,7 @@ static struct pci_device_id agp_amdk8_pci_table[] __initdata = { ...@@ -499,7 +507,7 @@ static struct pci_device_id agp_amdk8_pci_table[] __initdata = {
MODULE_DEVICE_TABLE(pci, agp_amdk8_pci_table); MODULE_DEVICE_TABLE(pci, agp_amdk8_pci_table);
static struct pci_driver agp_amdk8_pci_driver = { static struct __initdata pci_driver agp_amdk8_pci_driver = {
.name = "agpgart-amd-k8", .name = "agpgart-amd-k8",
.id_table = agp_amdk8_pci_table, .id_table = agp_amdk8_pci_table,
.probe = agp_amdk8_probe, .probe = agp_amdk8_probe,
......
...@@ -112,23 +112,13 @@ static struct agp_version agp_current_version = ...@@ -112,23 +112,13 @@ static struct agp_version agp_current_version =
.minor = AGPGART_VERSION_MINOR, .minor = AGPGART_VERSION_MINOR,
}; };
static int __init agp_backend_initialize(struct pci_dev *dev) static int agp_backend_initialize(struct pci_dev *dev)
{ {
int size_value, rc, got_gatt=0, got_keylist=0; int size_value, rc, got_gatt=0, got_keylist=0;
u8 cap_ptr = 0;
agp_bridge.max_memory_agp = agp_find_max(); agp_bridge.max_memory_agp = agp_find_max();
agp_bridge.version = &agp_current_version; agp_bridge.version = &agp_current_version;
cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (cap_ptr == 0)
return -ENODEV;
agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &agp_bridge.mode);
if (agp_bridge.needs_scratch_page == TRUE) { if (agp_bridge.needs_scratch_page == TRUE) {
void *addr; void *addr;
addr = agp_bridge.agp_alloc_page(); addr = agp_bridge.agp_alloc_page();
...@@ -272,13 +262,6 @@ int agp_unregister_driver(void) ...@@ -272,13 +262,6 @@ int agp_unregister_driver(void)
return 0; return 0;
} }
int __exit agp_exit(void)
{
if (agp_count==0)
return -EBUSY;
return 0;
}
int __init agp_init(void) int __init agp_init(void)
{ {
...@@ -297,6 +280,12 @@ int __init agp_init(void) ...@@ -297,6 +280,12 @@ int __init agp_init(void)
return 0; return 0;
} }
void __exit agp_exit(void)
{
if (agp_count!=0)
BUG();
}
#ifndef CONFIG_GART_IOMMU #ifndef CONFIG_GART_IOMMU
module_init(agp_init); module_init(agp_init);
module_exit(agp_exit); module_exit(agp_exit);
......
...@@ -1067,7 +1067,7 @@ static struct miscdevice agp_miscdev = ...@@ -1067,7 +1067,7 @@ static struct miscdevice agp_miscdev =
.fops = &agp_fops .fops = &agp_fops
}; };
int __init agp_frontend_initialize(void) int agp_frontend_initialize(void)
{ {
memset(&agp_fe, 0, sizeof(struct agp_front_data)); memset(&agp_fe, 0, sizeof(struct agp_front_data));
AGP_LOCK_INIT(); AGP_LOCK_INIT();
......
#include <linux/list.h> #include <linux/list.h>
#include <linux/pci.h> #include <linux/pci.h>
//#include <linux/pagemap.h>
//#include <linux/miscdevice.h>
//#include <linux/pm.h>
#include <linux/agp_backend.h> #include <linux/agp_backend.h>
#include <linux/module.h>
#include "agp.h" #include "agp.h"
...@@ -529,7 +525,7 @@ static int agp_3_0_node_enable(u32 mode, u32 minor) ...@@ -529,7 +525,7 @@ static int agp_3_0_node_enable(u32 mode, u32 minor)
* (AGP 3.0 devices are required to operate as AGP 2.0 devices * (AGP 3.0 devices are required to operate as AGP 2.0 devices
* when not using 3.0 electricals. * when not using 3.0 electricals.
*/ */
void agp_generic_agp_3_0_enable(u32 mode) int agp_generic_agp_3_0_enable(u32 mode)
{ {
u32 ncapid, major, minor, agp_3_0; u32 ncapid, major, minor, agp_3_0;
...@@ -548,9 +544,11 @@ void agp_generic_agp_3_0_enable(u32 mode) ...@@ -548,9 +544,11 @@ void agp_generic_agp_3_0_enable(u32 mode)
*/ */
if((agp_3_0 >> 3) & 0x1) { if((agp_3_0 >> 3) & 0x1) {
agp_3_0_node_enable(mode, minor); agp_3_0_node_enable(mode, minor);
return; return TRUE;
} }
} }
agp_generic_agp_enable(mode); return FALSE;
} }
EXPORT_SYMBOL(agp_generic_agp_3_0_enable);
...@@ -216,8 +216,7 @@ static void hp_zx1_tlbflush(agp_memory * mem) ...@@ -216,8 +216,7 @@ static void hp_zx1_tlbflush(agp_memory * mem)
{ {
struct _hp_private *hp = &hp_private; struct _hp_private *hp = &hp_private;
OUTREG64(hp->registers, HP_ZX1_PCOM, OUTREG64(hp->registers, HP_ZX1_PCOM, hp->gart_base | log2(hp->gart_size));
hp->gart_base | log2(hp->gart_size));
INREG64(hp->registers, HP_ZX1_PCOM); INREG64(hp->registers, HP_ZX1_PCOM);
} }
...@@ -329,7 +328,7 @@ static unsigned long hp_zx1_mask_memory(unsigned long addr, int type) ...@@ -329,7 +328,7 @@ static unsigned long hp_zx1_mask_memory(unsigned long addr, int type)
return HP_ZX1_PDIR_VALID_BIT | addr; return HP_ZX1_PDIR_VALID_BIT | addr;
} }
int __init hp_zx1_setup (struct pci_dev *pdev __attribute__((unused))) static int __init hp_zx1_setup (struct pci_dev *pdev __attribute__((unused)))
{ {
agp_bridge.masks = hp_zx1_masks; agp_bridge.masks = hp_zx1_masks;
agp_bridge.num_of_masks = 1; agp_bridge.num_of_masks = 1;
...@@ -368,8 +367,9 @@ static int __init agp_find_supported_device(struct pci_dev *dev) ...@@ -368,8 +367,9 @@ static int __init agp_find_supported_device(struct pci_dev *dev)
return hp_zx1_setup(dev); return hp_zx1_setup(dev);
} }
return -ENODEV; return -ENODEV;
}
static int agp_hp_probe (struct pci_dev *dev, const struct pci_device_id *ent) static int __init agp_hp_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
if (agp_find_supported_device(dev) == 0) { if (agp_find_supported_device(dev) == 0) {
agp_register_driver(dev); agp_register_driver(dev);
...@@ -382,7 +382,7 @@ static struct pci_device_id agp_hp_pci_table[] __initdata = { ...@@ -382,7 +382,7 @@ static struct pci_device_id agp_hp_pci_table[] __initdata = {
{ {
.class = (PCI_CLASS_BRIDGE_HOST << 8), .class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0, .class_mask = ~0,
.vendor_id = PCI_VENDOR_ID_HP, .vendor = PCI_VENDOR_ID_HP,
.device = PCI_DEVICE_ID_HP_ZX1_LBA, .device = PCI_DEVICE_ID_HP_ZX1_LBA,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
...@@ -392,7 +392,7 @@ static struct pci_device_id agp_hp_pci_table[] __initdata = { ...@@ -392,7 +392,7 @@ static struct pci_device_id agp_hp_pci_table[] __initdata = {
MODULE_DEVICE_TABLE(pci, agp_pci_table); MODULE_DEVICE_TABLE(pci, agp_pci_table);
static struct pci_driver agp_hp_pci_driver = { static struct __initdata pci_driver agp_hp_pci_driver = {
.name = "agpgart-hp", .name = "agpgart-hp",
.id_table = agp_hp_pci_table, .id_table = agp_hp_pci_table,
.probe = agp_hp_probe, .probe = agp_hp_probe,
...@@ -412,7 +412,7 @@ static int __init agp_hp_init(void) ...@@ -412,7 +412,7 @@ static int __init agp_hp_init(void)
static void __exit agp_hp_cleanup(void) static void __exit agp_hp_cleanup(void)
{ {
agp_unregister_driver(); agp_unregister_driver();
pci_unregister_driver(&agp_pci_driver); pci_unregister_driver(&agp_hp_pci_driver);
} }
module_init(agp_hp_init); module_init(agp_hp_init);
......
...@@ -523,7 +523,7 @@ static unsigned long i460_mask_memory (unsigned long addr, int type) ...@@ -523,7 +523,7 @@ static unsigned long i460_mask_memory (unsigned long addr, int type)
| (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12)); | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12));
} }
int __init intel_i460_setup (struct pci_dev *pdev __attribute__((unused))) static int __init intel_i460_setup (struct pci_dev *pdev __attribute__((unused)))
{ {
agp_bridge.num_of_masks = 1; agp_bridge.num_of_masks = 1;
agp_bridge.masks = i460_masks; agp_bridge.masks = i460_masks;
...@@ -560,55 +560,60 @@ int __init intel_i460_setup (struct pci_dev *pdev __attribute__((unused))) ...@@ -560,55 +560,60 @@ int __init intel_i460_setup (struct pci_dev *pdev __attribute__((unused)))
return 0; return 0;
} }
static int agp_intel_i460_probe (struct pci_dev *dev, const struct pci_device_id *ent) static int __init agp_intel_i460_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0) u8 cap_ptr = 0;
cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (cap_ptr == 0)
return -ENODEV; return -ENODEV;
agp_bridge.dev = dev;
agp_bridge.capndx = cap_ptr;
intel_i460_setup(dev); intel_i460_setup(dev);
agp_register_driver(dev); agp_register_driver(dev);
return 0; return 0;
} }
static struct pci_device_id agp_i460_pci_table[] __initdata = { static struct pci_device_id agp_intel_i460_pci_table[] __initdata = {
{ {
.class = (PCI_CLASS_BRIDGE_HOST << 8), .class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0, .class_mask = ~0,
.vendor = PCI_VENDOR_ID_INTEL, .vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_460GX, .device = PCI_DEVICE_ID_INTEL_84460GX,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
}, },
{ } { }
}; };
MODULE_DEVICE_TABLE(pci, agp_i460_pci_table); MODULE_DEVICE_TABLE(pci, agp_intel_i460_pci_table);
static struct pci_driver agp_i460_pci_driver = { static struct __initdata pci_driver agp_intel_i460_pci_driver = {
.name = "agpgart-intel-i460", .name = "agpgart-intel-i460",
.id_table = agp_i460_pci_table, .id_table = agp_intel_i460_pci_table,
.probe = agp_i460_probe, .probe = agp_intel_i460_probe,
}; };
static int __init agp_i460_init(void) static int __init agp_intel_i460_init(void)
{ {
int ret_val; int ret_val;
ret_val = pci_module_init(&agp_i460_pci_driver); ret_val = pci_module_init(&agp_intel_i460_pci_driver);
if (ret_val) if (ret_val)
agp_bridge.type = NOT_SUPPORTED; agp_bridge.type = NOT_SUPPORTED;
return ret_val; return ret_val;
} }
static void __exit agp_i460_cleanup(void) static void __exit agp_intel_i460_cleanup(void)
{ {
agp_unregister_driver(); agp_unregister_driver();
pci_unregister_driver(&agp_i460_pci_driver); pci_unregister_driver(&agp_intel_i460_pci_driver);
} }
module_init(agp_i460_init); module_init(agp_intel_i460_init);
module_exit(agp_i460_cleanup); module_exit(agp_intel_i460_cleanup);
MODULE_AUTHOR("Chris Ahna <Christopher.J.Ahna@intel.com>"); MODULE_AUTHOR("Chris Ahna <Christopher.J.Ahna@intel.com>");
MODULE_LICENSE("GPL and additional rights"); MODULE_LICENSE("GPL and additional rights");
...@@ -87,6 +87,11 @@ static aper_size_info_16 intel_7505_sizes[7] = ...@@ -87,6 +87,11 @@ static aper_size_info_16 intel_7505_sizes[7] =
{4, 1024, 0, 0xf3f} {4, 1024, 0, 0xf3f}
}; };
static void i7505_setup (u32 mode)
{
if ((agp_generic_agp_3_0_enable)==FALSE)
agp_generic_agp_enable(mode);
}
static int __init intel_7505_setup (struct pci_dev *pdev) static int __init intel_7505_setup (struct pci_dev *pdev)
{ {
...@@ -102,7 +107,7 @@ static int __init intel_7505_setup (struct pci_dev *pdev) ...@@ -102,7 +107,7 @@ static int __init intel_7505_setup (struct pci_dev *pdev)
agp_bridge.cleanup = intel_7505_cleanup; agp_bridge.cleanup = intel_7505_cleanup;
agp_bridge.tlb_flush = intel_7505_tlbflush; agp_bridge.tlb_flush = intel_7505_tlbflush;
agp_bridge.mask_memory = intel_mask_memory; agp_bridge.mask_memory = intel_mask_memory;
agp_bridge.agp_enable = agp_generic_agp_3_0_enable; agp_bridge.agp_enable = i7505_enable;
agp_bridge.cache_flush = global_cache_flush; agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = agp_generic_create_gatt_table; agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
agp_bridge.free_gatt_table = agp_generic_free_gatt_table; agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
...@@ -161,27 +166,26 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev) ...@@ -161,27 +166,26 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
} }
static int __init agp_find_supported_device(struct pci_dev *dev) static int __init agp_i7x05_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
agp_bridge.dev = dev; u8 cap_ptr = 0;
if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0) cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (cap_ptr == 0)
return -ENODEV; return -ENODEV;
/* probe for known chipsets */ if (agp_lookup_host_bridge(dev) != -ENODEV) {
return agp_lookup_host_bridge(dev); agp_bridge.dev = dev;
} agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode)
static int agp_i7x05_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
if (agp_find_supported_device(dev) == 0) {
agp_register_driver(dev); agp_register_driver(dev);
return 0; return 0;
} }
return -ENODEV; return -ENODEV;
} }
static struct pci_device_id agp_i7x05_pci_table[] __initdata = { static struct pci_device_id agp_i7x05_pci_table[] __initdata = {
{ {
.class = (PCI_CLASS_BRIDGE_HOST << 8), .class = (PCI_CLASS_BRIDGE_HOST << 8),
...@@ -196,7 +200,7 @@ static struct pci_device_id agp_i7x05_pci_table[] __initdata = { ...@@ -196,7 +200,7 @@ static struct pci_device_id agp_i7x05_pci_table[] __initdata = {
MODULE_DEVICE_TABLE(pci, agp_i7x05_pci_table); MODULE_DEVICE_TABLE(pci, agp_i7x05_pci_table);
static struct pci_driver agp_i7x05_pci_driver = { static struct __initdata pci_driver agp_i7x05_pci_driver = {
.name = "agpgart-i7x05", .name = "agpgart-i7x05",
.id_table = agp_i7x05_pci_table, .id_table = agp_i7x05_pci_table,
.probe = agp_i7x05_probe, .probe = agp_i7x05_probe,
......
...@@ -72,8 +72,7 @@ static int intel_i810_configure(void) ...@@ -72,8 +72,7 @@ static int intel_i810_configure(void)
pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp); pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
temp &= 0xfff80000; temp &= 0xfff80000;
intel_i810_private.registers = intel_i810_private.registers = (volatile u8 *) ioremap(temp, 128 * 4096);
(volatile u8 *) ioremap(temp, 128 * 4096);
if ((INREG32(intel_i810_private.registers, I810_DRAM_CTL) if ((INREG32(intel_i810_private.registers, I810_DRAM_CTL)
& I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) { & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
...@@ -132,12 +131,10 @@ static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start, ...@@ -132,12 +131,10 @@ static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start,
} }
if (type != 0 || mem->type != 0) { if (type != 0 || mem->type != 0) {
if ((type == AGP_DCACHE_MEMORY) && if ((type == AGP_DCACHE_MEMORY) && (mem->type == AGP_DCACHE_MEMORY)) {
(mem->type == AGP_DCACHE_MEMORY)) {
/* special insert */ /* special insert */
CACHE_FLUSH(); CACHE_FLUSH();
for (i = pg_start; for (i = pg_start; i < (pg_start + mem->page_count); i++) {
i < (pg_start + mem->page_count); i++) {
OUTREG32(intel_i810_private.registers, OUTREG32(intel_i810_private.registers,
I810_PTE_BASE + (i * 4), I810_PTE_BASE + (i * 4),
(i * 4096) | I810_PTE_LOCAL | (i * 4096) | I810_PTE_LOCAL |
...@@ -147,10 +144,8 @@ static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start, ...@@ -147,10 +144,8 @@ static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start,
agp_bridge.tlb_flush(mem); agp_bridge.tlb_flush(mem);
return 0; return 0;
} }
if((type == AGP_PHYS_MEMORY) && if((type == AGP_PHYS_MEMORY) && (mem->type == AGP_PHYS_MEMORY))
(mem->type == AGP_PHYS_MEMORY)) {
goto insert; goto insert;
}
return -EINVAL; return -EINVAL;
} }
...@@ -209,14 +204,13 @@ static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type) ...@@ -209,14 +204,13 @@ static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
* Xserver still writes to it through the agp * Xserver still writes to it through the agp
* aperture * aperture
*/ */
if (pg_count != 1) { if (pg_count != 1)
return NULL; return NULL;
}
new = agp_create_memory(1);
if (new == NULL) { new = agp_create_memory(1);
if (new == NULL)
return NULL; return NULL;
}
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
addr = agp_bridge.agp_alloc_page(); addr = agp_bridge.agp_alloc_page();
...@@ -232,7 +226,6 @@ static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type) ...@@ -232,7 +226,6 @@ static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
new->physical = virt_to_phys((void *) new->memory[0]); new->physical = virt_to_phys((void *) new->memory[0]);
return new; return new;
} }
return NULL; return NULL;
} }
...@@ -240,8 +233,7 @@ static void intel_i810_free_by_type(agp_memory * curr) ...@@ -240,8 +233,7 @@ static void intel_i810_free_by_type(agp_memory * curr)
{ {
agp_free_key(curr->key); agp_free_key(curr->key);
if(curr->type == AGP_PHYS_MEMORY) { if(curr->type == AGP_PHYS_MEMORY) {
agp_bridge.agp_destroy_page( agp_bridge.agp_destroy_page(phys_to_virt(curr->memory[0]));
phys_to_virt(curr->memory[0]));
vfree(curr->memory); vfree(curr->memory);
} }
kfree(curr); kfree(curr);
...@@ -254,7 +246,7 @@ static unsigned long intel_i810_mask_memory(unsigned long addr, int type) ...@@ -254,7 +246,7 @@ static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
return addr | agp_bridge.masks[type].mask; return addr | agp_bridge.masks[type].mask;
} }
int __init intel_i810_setup(struct pci_dev *i810_dev) static int __init intel_i810_setup(struct pci_dev *i810_dev)
{ {
intel_i810_private.i810_dev = i810_dev; intel_i810_private.i810_dev = i810_dev;
...@@ -533,7 +525,7 @@ static agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type) ...@@ -533,7 +525,7 @@ static agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
return(NULL); return(NULL);
} }
int __init intel_i830_setup(struct pci_dev *i830_dev) static int __init intel_i830_setup(struct pci_dev *i830_dev)
{ {
intel_i830_private.i830_dev = i830_dev; intel_i830_private.i830_dev = i830_dev;
...@@ -581,8 +573,7 @@ static int intel_fetch_size(void) ...@@ -581,8 +573,7 @@ static int intel_fetch_size(void)
for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
if (temp == values[i].size_value) { if (temp == values[i].size_value) {
agp_bridge.previous_size = agp_bridge.previous_size = agp_bridge.current_size = (void *) (values + i);
agp_bridge.current_size = (void *) (values + i);
agp_bridge.aperture_size_idx = i; agp_bridge.aperture_size_idx = i;
return values[i].size; return values[i].size;
} }
...@@ -1338,6 +1329,7 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev) ...@@ -1338,6 +1329,7 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
static int __init agp_find_supported_device(struct pci_dev *dev) static int __init agp_find_supported_device(struct pci_dev *dev)
{ {
struct pci_dev *i810_dev; struct pci_dev *i810_dev;
u8 cap_ptr = 0;
agp_bridge.dev = dev; agp_bridge.dev = dev;
...@@ -1433,15 +1425,20 @@ static int __init agp_find_supported_device(struct pci_dev *dev) ...@@ -1433,15 +1425,20 @@ static int __init agp_find_supported_device(struct pci_dev *dev)
break; break;
} }
if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0) cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (cap_ptr == 0)
return -ENODEV; return -ENODEV;
agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
/* probe for known chipsets */ /* probe for known chipsets */
return agp_lookup_host_bridge(dev); return agp_lookup_host_bridge(dev);
} }
static int agp_intel_probe (struct pci_dev *dev, const struct pci_device_id *ent) static int __init agp_intel_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
if (agp_find_supported_device(dev) == 0) { if (agp_find_supported_device(dev) == 0) {
agp_register_driver(dev); agp_register_driver(dev);
...@@ -1464,7 +1461,7 @@ static struct pci_device_id agp_intel_pci_table[] __initdata = { ...@@ -1464,7 +1461,7 @@ static struct pci_device_id agp_intel_pci_table[] __initdata = {
MODULE_DEVICE_TABLE(pci, agp_intel_pci_table); MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
static struct pci_driver agp_intel_pci_driver = { static struct __initdata pci_driver agp_intel_pci_driver = {
.name = "agpgart-intel", .name = "agpgart-intel",
.id_table = agp_intel_pci_table, .id_table = agp_intel_pci_table,
.probe = agp_intel_probe, .probe = agp_intel_probe,
...@@ -1498,4 +1495,3 @@ module_exit(agp_intel_cleanup); ...@@ -1498,4 +1495,3 @@ module_exit(agp_intel_cleanup);
MODULE_PARM(agp_try_unsupported, "1i"); MODULE_PARM(agp_try_unsupported, "1i");
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
MODULE_LICENSE("GPL and additional rights"); MODULE_LICENSE("GPL and additional rights");
...@@ -86,7 +86,7 @@ static struct gatt_mask sis_generic_masks[] = ...@@ -86,7 +86,7 @@ static struct gatt_mask sis_generic_masks[] =
{.mask = 0x00000000, .type = 0} {.mask = 0x00000000, .type = 0}
}; };
int __init sis_generic_setup (struct pci_dev *pdev) static int __init sis_generic_setup (struct pci_dev *pdev)
{ {
agp_bridge.masks = sis_generic_masks; agp_bridge.masks = sis_generic_masks;
agp_bridge.num_of_masks = 1; agp_bridge.num_of_masks = 1;
...@@ -223,21 +223,20 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev) ...@@ -223,21 +223,20 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
} }
static int __init agp_find_supported_device(struct pci_dev *dev) static int __init agp_sis_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
agp_bridge.dev = dev; u8 cap_ptr = 0;
if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0) cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (cap_ptr == 0)
return -ENODEV; return -ENODEV;
/* probe for known chipsets */ /* probe for known chipsets */
return agp_lookup_host_bridge (dev); if (agp_lookup_host_bridge(dev) != -ENODEV) {
} agp_bridge.dev = dev;
agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
static int agp_sis_probe (struct pci_dev *dev, const struct pci_device_id *ent) pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
{
if (agp_find_supported_device(dev) == 0) {
agp_register_driver(dev); agp_register_driver(dev);
return 0; return 0;
} }
...@@ -258,13 +257,13 @@ static struct pci_device_id agp_sis_pci_table[] __initdata = { ...@@ -258,13 +257,13 @@ static struct pci_device_id agp_sis_pci_table[] __initdata = {
MODULE_DEVICE_TABLE(pci, agp_sis_pci_table); MODULE_DEVICE_TABLE(pci, agp_sis_pci_table);
static struct pci_driver agp_sis_pci_driver = { static struct __initdata pci_driver agp_sis_pci_driver = {
.name = "agpgart-sis", .name = "agpgart-sis",
.id_table = agp_sis_pci_table, .id_table = agp_sis_pci_table,
.probe = agp_sis_probe, .probe = agp_sis_probe,
}; };
int __init agp_sis_init(void) static int __init agp_sis_init(void)
{ {
int ret_val; int ret_val;
......
...@@ -169,9 +169,7 @@ static int serverworks_create_gatt_table(void) ...@@ -169,9 +169,7 @@ static int serverworks_create_gatt_table(void)
* used to program the agp master not the cpu * used to program the agp master not the cpu
*/ */
pci_read_config_dword(agp_bridge.dev, pci_read_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,&temp);
serverworks_private.gart_addr_ofs,
&temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* Calculate the agp offset */ /* Calculate the agp offset */
...@@ -206,18 +204,11 @@ static int serverworks_fetch_size(void) ...@@ -206,18 +204,11 @@ static int serverworks_fetch_size(void)
struct aper_size_info_lvl2 *values; struct aper_size_info_lvl2 *values;
values = A_SIZE_LVL2(agp_bridge.aperture_sizes); values = A_SIZE_LVL2(agp_bridge.aperture_sizes);
pci_read_config_dword(agp_bridge.dev, pci_read_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,&temp);
serverworks_private.gart_addr_ofs, pci_write_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,
&temp);
pci_write_config_dword(agp_bridge.dev,
serverworks_private.gart_addr_ofs,
SVWRKS_SIZE_MASK); SVWRKS_SIZE_MASK);
pci_read_config_dword(agp_bridge.dev, pci_read_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,&temp2);
serverworks_private.gart_addr_ofs, pci_write_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,temp);
&temp2);
pci_write_config_dword(agp_bridge.dev,
serverworks_private.gart_addr_ofs,
temp);
temp2 &= SVWRKS_SIZE_MASK; temp2 &= SVWRKS_SIZE_MASK;
for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
...@@ -245,9 +236,7 @@ static int serverworks_configure(void) ...@@ -245,9 +236,7 @@ static int serverworks_configure(void)
current_size = A_SIZE_LVL2(agp_bridge.current_size); current_size = A_SIZE_LVL2(agp_bridge.current_size);
/* Get the memory mapped registers */ /* Get the memory mapped registers */
pci_read_config_dword(agp_bridge.dev, pci_read_config_dword(agp_bridge.dev, serverworks_private.mm_addr_ofs, &temp);
serverworks_private.mm_addr_ofs,
&temp);
temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
serverworks_private.registers = (volatile u8 *) ioremap(temp, 4096); serverworks_private.registers = (volatile u8 *) ioremap(temp, 4096);
...@@ -269,7 +258,7 @@ static int serverworks_configure(void) ...@@ -269,7 +258,7 @@ static int serverworks_configure(void)
agp_bridge.tlb_flush(NULL); agp_bridge.tlb_flush(NULL);
pci_read_config_byte(serverworks_private.svrwrks_dev, 0x34, &cap_ptr); pci_read_config_byte(serverworks_private.svrwrks_dev, 0x34, &cap_ptr);
if (cap_ptr != 0x00) { if (cap_ptr != 0) {
do { do {
pci_read_config_dword(serverworks_private.svrwrks_dev, pci_read_config_dword(serverworks_private.svrwrks_dev,
cap_ptr, &cap_id); cap_ptr, &cap_id);
...@@ -277,30 +266,21 @@ static int serverworks_configure(void) ...@@ -277,30 +266,21 @@ static int serverworks_configure(void)
if ((cap_id & 0xff) != 0x02) if ((cap_id & 0xff) != 0x02)
cap_ptr = (cap_id >> 8) & 0xff; cap_ptr = (cap_id >> 8) & 0xff;
} }
while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00)); while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0));
} }
agp_bridge.capndx = cap_ptr; agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */ /* Fill in the mode register */
pci_read_config_dword(serverworks_private.svrwrks_dev, pci_read_config_dword(serverworks_private.svrwrks_dev,
agp_bridge.capndx + 4, agp_bridge.capndx+4, &agp_bridge.mode);
&agp_bridge.mode);
pci_read_config_byte(agp_bridge.dev, pci_read_config_byte(agp_bridge.dev, SVWRKS_CACHING, &enable_reg);
SVWRKS_CACHING,
&enable_reg);
enable_reg &= ~0x3; enable_reg &= ~0x3;
pci_write_config_byte(agp_bridge.dev, pci_write_config_byte(agp_bridge.dev, SVWRKS_CACHING, enable_reg);
SVWRKS_CACHING,
enable_reg);
pci_read_config_byte(agp_bridge.dev, pci_read_config_byte(agp_bridge.dev, SVWRKS_FEATURE, &enable_reg);
SVWRKS_FEATURE,
&enable_reg);
enable_reg |= (1<<6); enable_reg |= (1<<6);
pci_write_config_byte(agp_bridge.dev, pci_write_config_byte(agp_bridge.dev,SVWRKS_FEATURE, enable_reg);
SVWRKS_FEATURE,
enable_reg);
return 0; return 0;
} }
...@@ -532,7 +512,7 @@ static void serverworks_agp_enable(u32 mode) ...@@ -532,7 +512,7 @@ static void serverworks_agp_enable(u32 mode)
} }
} }
int __init serverworks_setup (struct pci_dev *pdev) static int __init serverworks_setup (struct pci_dev *pdev)
{ {
u32 temp; u32 temp;
u32 temp2; u32 temp2;
...@@ -606,7 +586,6 @@ int __init serverworks_setup (struct pci_dev *pdev) ...@@ -606,7 +586,6 @@ int __init serverworks_setup (struct pci_dev *pdev)
static int __init agp_find_supported_device(struct pci_dev *dev) static int __init agp_find_supported_device(struct pci_dev *dev)
{ {
struct pci_dev *bridge_dev; struct pci_dev *bridge_dev;
agp_bridge.dev = dev;
/* Everything is on func 1 here so we are hardcoding function one */ /* Everything is on func 1 here so we are hardcoding function one */
bridge_dev = pci_find_slot ((unsigned int)dev->bus->number, PCI_DEVFN(0, 1)); bridge_dev = pci_find_slot ((unsigned int)dev->bus->number, PCI_DEVFN(0, 1));
...@@ -617,6 +596,8 @@ static int __init agp_find_supported_device(struct pci_dev *dev) ...@@ -617,6 +596,8 @@ static int __init agp_find_supported_device(struct pci_dev *dev)
return -ENODEV; return -ENODEV;
} }
agp_bridge.dev = dev;
switch (dev->device) { switch (dev->device) {
case PCI_DEVICE_ID_SERVERWORKS_HE: case PCI_DEVICE_ID_SERVERWORKS_HE:
agp_bridge.type = SVWRKS_HE; agp_bridge.type = SVWRKS_HE;
...@@ -638,7 +619,7 @@ static int __init agp_find_supported_device(struct pci_dev *dev) ...@@ -638,7 +619,7 @@ static int __init agp_find_supported_device(struct pci_dev *dev)
} }
static int agp_serverworks_probe (struct pci_dev *dev, const struct pci_device_id *ent) static int __init agp_serverworks_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
if (agp_find_supported_device(dev) == 0) { if (agp_find_supported_device(dev) == 0) {
agp_register_driver(dev); agp_register_driver(dev);
...@@ -661,7 +642,7 @@ static struct pci_device_id agp_serverworks_pci_table[] __initdata = { ...@@ -661,7 +642,7 @@ static struct pci_device_id agp_serverworks_pci_table[] __initdata = {
MODULE_DEVICE_TABLE(pci, agp_serverworks_pci_table); MODULE_DEVICE_TABLE(pci, agp_serverworks_pci_table);
static struct pci_driver agp_serverworks_pci_driver = { static struct __initdata pci_driver agp_serverworks_pci_driver = {
.name = "agpgart-serverworks", .name = "agpgart-serverworks",
.id_table = agp_serverworks_pci_table, .id_table = agp_serverworks_pci_table,
.probe = agp_serverworks_probe, .probe = agp_serverworks_probe,
......
...@@ -94,7 +94,7 @@ static struct gatt_mask via_generic_masks[] = ...@@ -94,7 +94,7 @@ static struct gatt_mask via_generic_masks[] =
{.mask = 0x00000000, .type = 0} {.mask = 0x00000000, .type = 0}
}; };
int __init via_generic_setup (struct pci_dev *pdev) static int __init via_generic_setup (struct pci_dev *pdev)
{ {
agp_bridge.masks = via_generic_masks; agp_bridge.masks = via_generic_masks;
agp_bridge.num_of_masks = 1; agp_bridge.num_of_masks = 1;
...@@ -124,13 +124,64 @@ int __init via_generic_setup (struct pci_dev *pdev) ...@@ -124,13 +124,64 @@ int __init via_generic_setup (struct pci_dev *pdev)
return 0; return 0;
} }
struct agp_device_ids via_agp_device_ids[] __initdata =
/*
* The KT400 does magick to put the AGP bridge compliant with the same
* standards version as the graphics card. If we haven't fallen into
* 2.0 compatability mode, we run the normal 3.0 code, and fall back
* if something nasty happens.
*/
static void __init via_kt400_enable(u32 mode)
{
if ((agp_generic_agp_3_0_enable(mode))==FALSE)
/* Something weird happened, fall back to 2.0 */
agp_generic_agp_enable(mode);
}
static int __init via_kt400_setup(struct pci_dev *pdev)
{
u8 reg;
agp_bridge.masks = via_generic_masks;
agp_bridge.num_of_masks = 1;
agp_bridge.aperture_sizes = (void *) via_generic_sizes;
agp_bridge.size_type = U8_APER_SIZE;
agp_bridge.num_aperture_sizes = 7;
agp_bridge.dev_private_data = NULL;
agp_bridge.needs_scratch_page = FALSE;
agp_bridge.configure = via_configure;
agp_bridge.fetch_size = via_fetch_size;
agp_bridge.cleanup = via_cleanup;
agp_bridge.tlb_flush = via_tlbflush;
agp_bridge.mask_memory = via_mask_memory;
agp_bridge.cache_flush = global_cache_flush;
agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
agp_bridge.insert_memory = agp_generic_insert_memory;
agp_bridge.remove_memory = agp_generic_remove_memory;
agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
pci_read_config_byte(agp_bridge.dev, VIA_AGPSEL, &reg);
if ((reg & (1<<1))==1) {
/* AGP 2.0 compatability mode. */
agp_bridge.agp_enable = agp_generic_agp_enable;
} else {
/* AGP 3.0 mode */
agp_bridge.agp_enable = via_kt400_enable;
}
return 0;
}
static struct agp_device_ids via_agp_device_ids[] __initdata =
{ {
{
.device_id = PCI_DEVICE_ID_VIA_8501_0,
.chipset = VIA_MVP4,
.chipset_name = "MVP4",
},
{ {
.device_id = PCI_DEVICE_ID_VIA_82C597_0, .device_id = PCI_DEVICE_ID_VIA_82C597_0,
.chipset = VIA_VP3, .chipset = VIA_VP3,
...@@ -141,6 +192,11 @@ struct agp_device_ids via_agp_device_ids[] __initdata = ...@@ -141,6 +192,11 @@ struct agp_device_ids via_agp_device_ids[] __initdata =
.chipset = VIA_MVP3, .chipset = VIA_MVP3,
.chipset_name = "MVP3", .chipset_name = "MVP3",
}, },
{
.device_id = PCI_DEVICE_ID_VIA_8501_0,
.chipset = VIA_MVP4,
.chipset_name = "MVP4",
},
{ {
.device_id = PCI_DEVICE_ID_VIA_82C691, .device_id = PCI_DEVICE_ID_VIA_82C691,
.chipset = VIA_APOLLO_PRO, .chipset = VIA_APOLLO_PRO,
...@@ -166,20 +222,22 @@ struct agp_device_ids via_agp_device_ids[] __initdata = ...@@ -166,20 +222,22 @@ struct agp_device_ids via_agp_device_ids[] __initdata =
.chipset = VIA_APOLLO_KT133, .chipset = VIA_APOLLO_KT133,
.chipset_name = "Apollo Pro KT266", .chipset_name = "Apollo Pro KT266",
}, },
{
.device_id = PCI_DEVICE_ID_VIA_8653_0,
.chipset = VIA_APOLLO_PRO,
.chipset_name = "Apollo Pro 266T",
},
{ {
.device_id = PCI_DEVICE_ID_VIA_8377_0, .device_id = PCI_DEVICE_ID_VIA_8377_0,
.chipset = VIA_APOLLO_KT400, .chipset = VIA_APOLLO_KT400,
.chipset_name = "Apollo Pro KT400", .chipset_name = "Apollo Pro KT400",
.chipset_setup = via_kt400_setup,
}, },
{ {
.device_id = PCI_DEVICE_ID_VIA_8653_0, /* VIA ProSavage PM133 (Apollo Pro133A chipset with S3 Savage4) */
.chipset = VIA_APOLLO_PRO,
.chipset_name = "Apollo Pro266T",
},
{
.device_id = PCI_DEVICE_ID_VIA_82C694X_0, .device_id = PCI_DEVICE_ID_VIA_82C694X_0,
.chipset = VIA_VT8605, .chipset = VIA_VT8605,
.chipset_name = "PM133" .chipset_name = "Apollo ProSavage PM133"
}, },
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
...@@ -220,15 +278,20 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev) ...@@ -220,15 +278,20 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
} }
static int agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent) static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0) u8 cap_ptr = 0;
return -ENODEV;
agp_bridge.dev = dev; cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (cap_ptr == 0)
return -ENODEV;
/* probe for known chipsets */ /* probe for known chipsets */
if (agp_lookup_host_bridge (dev) != -ENODEV) { if (agp_lookup_host_bridge (dev) != -ENODEV) {
agp_bridge.dev = dev;
agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
agp_register_driver(dev); agp_register_driver(dev);
return 0; return 0;
} }
...@@ -249,7 +312,7 @@ static struct pci_device_id agp_via_pci_table[] __initdata = { ...@@ -249,7 +312,7 @@ static struct pci_device_id agp_via_pci_table[] __initdata = {
MODULE_DEVICE_TABLE(pci, agp_via_pci_table); MODULE_DEVICE_TABLE(pci, agp_via_pci_table);
static struct pci_driver agp_via_pci_driver = { static struct __initdata pci_driver agp_via_pci_driver = {
.name = "agpgart-via", .name = "agpgart-via",
.id_table = agp_via_pci_table, .id_table = agp_via_pci_table,
.probe = agp_via_probe, .probe = agp_via_probe,
......
...@@ -6736,12 +6736,12 @@ aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device) ...@@ -6736,12 +6736,12 @@ aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device)
* prepare for this device to go away * prepare for this device to go away
*-F*************************************************************************/ *-F*************************************************************************/
static void static void
aic7xxx_slave_destroy(Scsi_Device *sdpnt) aic7xxx_slave_destroy(Scsi_Device *SDptr)
{ {
struct aic_dev_data *aic_dev = sdpnt->hostdata; struct aic_dev_data *aic_dev = SDptr->hostdata;
list_del(&aic_dev->list); list_del(&aic_dev->list);
sdpnt->hostdata = NULL; SDptr->hostdata = NULL;
kfree(aic_dev); kfree(aic_dev);
return; return;
} }
...@@ -6756,16 +6756,16 @@ aic7xxx_slave_destroy(Scsi_Device *sdpnt) ...@@ -6756,16 +6756,16 @@ aic7xxx_slave_destroy(Scsi_Device *sdpnt)
* depths, allocate command structs, etc. * depths, allocate command structs, etc.
*-F*************************************************************************/ *-F*************************************************************************/
static int static int
aic7xxx_slave_configure(Scsi_Device *sdpnt) aic7xxx_slave_configure(Scsi_Device *SDptr)
{ {
struct aic7xxx_host *p = (struct aic7xxx_host *) sdpnt->host->hostdata; struct aic7xxx_host *p = (struct aic7xxx_host *) SDptr->host->hostdata;
struct aic_dev_data *aic_dev; struct aic_dev_data *aic_dev;
int scbnum; int scbnum;
aic_dev = (struct aic_dev_data *)sdpnt->hostdata; aic_dev = (struct aic_dev_data *)SDptr->hostdata;
aic7xxx_init_transinfo(p, aic_dev); aic7xxx_init_transinfo(p, aic_dev);
aic7xxx_device_queue_depth(p, sdpnt); aic7xxx_device_queue_depth(p, SDptr);
if(list_empty(&aic_dev->list)) if(list_empty(&aic_dev->list))
list_add_tail(&aic_dev->list, &p->aic_devs); list_add_tail(&aic_dev->list, &p->aic_devs);
...@@ -9024,7 +9024,6 @@ aic7xxx_detect(Scsi_Host_Template *template) ...@@ -9024,7 +9024,6 @@ aic7xxx_detect(Scsi_Host_Template *template)
template->proc_name = "aic7xxx"; template->proc_name = "aic7xxx";
template->sg_tablesize = AIC7XXX_MAX_SG; template->sg_tablesize = AIC7XXX_MAX_SG;
template->max_sectors = 2048;
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
...@@ -9246,12 +9245,22 @@ aic7xxx_detect(Scsi_Host_Template *template) ...@@ -9246,12 +9245,22 @@ aic7xxx_detect(Scsi_Host_Template *template)
{ {
/* duplicate PCI entry, skip it */ /* duplicate PCI entry, skip it */
kfree(temp_p); kfree(temp_p);
temp_p = NULL; continue;
} }
current_p = current_p->next; current_p = current_p->next;
} }
if ( temp_p == NULL ) if(pci_request_regions(temp_p->pdev, "aic7xxx"))
{
printk("aic7xxx: <%s> at PCI %d/%d/%d\n",
board_names[aic_pdevs[i].board_name_index],
temp_p->pci_bus,
PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn));
printk("aic7xxx: I/O ports already in use, ignoring.\n");
kfree(temp_p);
continue; continue;
}
if (aic7xxx_verbose & VERBOSE_PROBE2) if (aic7xxx_verbose & VERBOSE_PROBE2)
printk("aic7xxx: <%s> at PCI %d/%d\n", printk("aic7xxx: <%s> at PCI %d/%d\n",
board_names[aic_pdevs[i].board_name_index], board_names[aic_pdevs[i].board_name_index],
...@@ -9283,20 +9292,6 @@ aic7xxx_detect(Scsi_Host_Template *template) ...@@ -9283,20 +9292,6 @@ aic7xxx_detect(Scsi_Host_Template *template)
pci_write_config_dword(pdev, DEVCONFIG, devconfig); pci_write_config_dword(pdev, DEVCONFIG, devconfig);
#endif /* AIC7XXX_STRICT_PCI_SETUP */ #endif /* AIC7XXX_STRICT_PCI_SETUP */
if(temp_p->base && !request_region(temp_p->base, MAXREG - MINREG,
"aic7xxx"))
{
printk("aic7xxx: <%s> at PCI %d/%d/%d\n",
board_names[aic_pdevs[i].board_name_index],
temp_p->pci_bus,
PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn));
printk("aic7xxx: I/O ports already in use, ignoring.\n");
kfree(temp_p);
temp_p = NULL;
continue;
}
temp_p->unpause = INTEN; temp_p->unpause = INTEN;
temp_p->pause = temp_p->unpause | PAUSE; temp_p->pause = temp_p->unpause | PAUSE;
if ( ((temp_p->base == 0) && if ( ((temp_p->base == 0) &&
...@@ -9309,9 +9304,7 @@ aic7xxx_detect(Scsi_Host_Template *template) ...@@ -9309,9 +9304,7 @@ aic7xxx_detect(Scsi_Host_Template *template)
PCI_SLOT(temp_p->pci_device_fn), PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn)); PCI_FUNC(temp_p->pci_device_fn));
printk("aic7xxx: Controller disabled by BIOS, ignoring.\n"); printk("aic7xxx: Controller disabled by BIOS, ignoring.\n");
kfree(temp_p); goto skip_pci_controller;
temp_p = NULL;
continue;
} }
#ifdef MMAPIO #ifdef MMAPIO
...@@ -9353,9 +9346,7 @@ aic7xxx_detect(Scsi_Host_Template *template) ...@@ -9353,9 +9346,7 @@ aic7xxx_detect(Scsi_Host_Template *template)
PCI_SLOT(temp_p->pci_device_fn), PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn)); PCI_FUNC(temp_p->pci_device_fn));
printk("aic7xxx: Controller disabled by BIOS, ignoring.\n"); printk("aic7xxx: Controller disabled by BIOS, ignoring.\n");
kfree(temp_p); goto skip_pci_controller;
temp_p = NULL;
continue;
} }
} }
} }
...@@ -9398,10 +9389,7 @@ aic7xxx_detect(Scsi_Host_Template *template) ...@@ -9398,10 +9389,7 @@ aic7xxx_detect(Scsi_Host_Template *template)
if (aic7xxx_chip_reset(temp_p) == -1) if (aic7xxx_chip_reset(temp_p) == -1)
{ {
release_region(temp_p->base, MAXREG - MINREG); goto skip_pci_controller;
kfree(temp_p);
temp_p = NULL;
continue;
} }
/* /*
* Very quickly put the term setting back into the register since * Very quickly put the term setting back into the register since
...@@ -9687,6 +9675,10 @@ aic7xxx_detect(Scsi_Host_Template *template) ...@@ -9687,6 +9675,10 @@ aic7xxx_detect(Scsi_Host_Template *template)
} }
temp_p->next = NULL; temp_p->next = NULL;
found++; found++;
continue;
skip_pci_controller:
pci_release_regions(temp_p->pdev);
kfree(temp_p);
} /* Found an Adaptec PCI device. */ } /* Found an Adaptec PCI device. */
else /* Well, we found one, but we couldn't get any memory */ else /* Well, we found one, but we couldn't get any memory */
{ {
...@@ -10969,14 +10961,16 @@ aic7xxx_release(struct Scsi_Host *host) ...@@ -10969,14 +10961,16 @@ aic7xxx_release(struct Scsi_Host *host)
if(p->irq) if(p->irq)
free_irq(p->irq, p); free_irq(p->irq, p);
if(p->base)
release_region(p->base, MAXREG - MINREG);
#ifdef MMAPIO #ifdef MMAPIO
if(p->maddr) if(p->maddr)
{ {
iounmap((void *) (((unsigned long) p->maddr) & PAGE_MASK)); iounmap((void *) (((unsigned long) p->maddr) & PAGE_MASK));
} }
#endif /* MMAPIO */ #endif /* MMAPIO */
if(!p->pdev)
release_region(p->base, MAXREG - MINREG);
else
pci_release_regions(p->pdev);
prev = NULL; prev = NULL;
next = first_aic7xxx; next = first_aic7xxx;
while(next != NULL) while(next != NULL)
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
can_queue: 255, /* max simultaneous cmds */\ can_queue: 255, /* max simultaneous cmds */\
this_id: -1, /* scsi id of host adapter */\ this_id: -1, /* scsi id of host adapter */\
sg_tablesize: 0, /* max scatter-gather cmds */\ sg_tablesize: 0, /* max scatter-gather cmds */\
max_sectors: 2048, /* max physical sectors in 1 cmd */\
cmd_per_lun: 3, /* cmds per lun (linked cmds) */\ cmd_per_lun: 3, /* cmds per lun (linked cmds) */\
present: 0, /* number of 7xxx's present */\ present: 0, /* number of 7xxx's present */\
unchecked_isa_dma: 0, /* no memory DMA restrictions */\ unchecked_isa_dma: 0, /* no memory DMA restrictions */\
......
...@@ -160,15 +160,13 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt); ...@@ -160,15 +160,13 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt);
*/ */
void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt) void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt)
{ {
request_queue_t *q = &SDpnt->request_queue; request_queue_t *q = SDpnt->request_queue;
/* /*
* tell block layer about assigned host_lock for this host * tell block layer about assigned host_lock for this host
*/ */
blk_init_queue(q, scsi_request_fn, SHpnt->host_lock); blk_init_queue(q, scsi_request_fn, SHpnt->host_lock);
q->queuedata = (void *) SDpnt;
/* Hardware imposed limit. */ /* Hardware imposed limit. */
blk_queue_max_hw_segments(q, SHpnt->sg_tablesize); blk_queue_max_hw_segments(q, SHpnt->sg_tablesize);
...@@ -223,7 +221,7 @@ __setup("scsi_logging=", scsi_logging_setup); ...@@ -223,7 +221,7 @@ __setup("scsi_logging=", scsi_logging_setup);
static void scsi_wait_done(Scsi_Cmnd * SCpnt) static void scsi_wait_done(Scsi_Cmnd * SCpnt)
{ {
struct request *req = SCpnt->request; struct request *req = SCpnt->request;
struct request_queue *q = &SCpnt->device->request_queue; struct request_queue *q = SCpnt->device->request_queue;
unsigned long flags; unsigned long flags;
ASSERT_LOCK(q->queue_lock, 0); ASSERT_LOCK(q->queue_lock, 0);
...@@ -656,17 +654,14 @@ int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason) ...@@ -656,17 +654,14 @@ int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason)
*/ */
void scsi_release_command(Scsi_Cmnd * SCpnt) void scsi_release_command(Scsi_Cmnd * SCpnt)
{ {
request_queue_t *q = &SCpnt->device->request_queue;
__scsi_release_command(SCpnt); __scsi_release_command(SCpnt);
/* /*
* Finally, hit the queue request function to make sure that * Finally, hit the queue request function to make sure that
* the device is actually busy if there are requests present. * the device is actually busy if there are requests present.
* This won't block - if the device cannot take any more, life * This won't block - if the device cannot take any more, life
* will go on. * will go on.
*/ */
scsi_queue_next_request(q, NULL); scsi_queue_next_request(SCpnt->device->request_queue, NULL);
} }
/* /*
...@@ -810,13 +805,12 @@ void scsi_wait_req (Scsi_Request * SRpnt, const void *cmnd , ...@@ -810,13 +805,12 @@ void scsi_wait_req (Scsi_Request * SRpnt, const void *cmnd ,
int timeout, int retries) int timeout, int retries)
{ {
DECLARE_COMPLETION(wait); DECLARE_COMPLETION(wait);
request_queue_t *q = &SRpnt->sr_device->request_queue;
SRpnt->sr_request->waiting = &wait; SRpnt->sr_request->waiting = &wait;
SRpnt->sr_request->rq_status = RQ_SCSI_BUSY; SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
scsi_do_req (SRpnt, (void *) cmnd, scsi_do_req (SRpnt, (void *) cmnd,
buffer, bufflen, scsi_wait_done, timeout, retries); buffer, bufflen, scsi_wait_done, timeout, retries);
generic_unplug_device(q); generic_unplug_device(SRpnt->sr_device->request_queue);
wait_for_completion(&wait); wait_for_completion(&wait);
SRpnt->sr_request->waiting = NULL; SRpnt->sr_request->waiting = NULL;
if( SRpnt->sr_command != NULL ) if( SRpnt->sr_command != NULL )
...@@ -1912,10 +1906,8 @@ void scsi_device_put(struct scsi_device *sdev) ...@@ -1912,10 +1906,8 @@ void scsi_device_put(struct scsi_device *sdev)
*/ */
int scsi_slave_attach(struct scsi_device *sdev) int scsi_slave_attach(struct scsi_device *sdev)
{ {
/* all this code is now handled elsewhere
if (sdev->attached++ == 0) { if (sdev->attached++ == 0) {
/*
* No one was attached.
*/
scsi_build_commandblocks(sdev); scsi_build_commandblocks(sdev);
if (sdev->current_queue_depth == 0) { if (sdev->current_queue_depth == 0) {
printk(KERN_ERR "scsi: Allocation failure during" printk(KERN_ERR "scsi: Allocation failure during"
...@@ -1935,6 +1927,8 @@ int scsi_slave_attach(struct scsi_device *sdev) ...@@ -1935,6 +1927,8 @@ int scsi_slave_attach(struct scsi_device *sdev)
scsi_adjust_queue_depth(sdev, 0, scsi_adjust_queue_depth(sdev, 0,
sdev->host->cmd_per_lun); sdev->host->cmd_per_lun);
} }
*/
sdev->attached++;
return 0; return 0;
} }
...@@ -1950,9 +1944,12 @@ int scsi_slave_attach(struct scsi_device *sdev) ...@@ -1950,9 +1944,12 @@ int scsi_slave_attach(struct scsi_device *sdev)
*/ */
void scsi_slave_detach(struct scsi_device *sdev) void scsi_slave_detach(struct scsi_device *sdev)
{ {
/*
if (--sdev->attached == 0) { if (--sdev->attached == 0) {
scsi_release_commandblocks(sdev); scsi_release_commandblocks(sdev);
} }
*/
sdev->attached--;
} }
/* /*
* This entry point should be called by a loadable module if it is trying * This entry point should be called by a loadable module if it is trying
......
...@@ -569,14 +569,12 @@ struct scsi_device { ...@@ -569,14 +569,12 @@ struct scsi_device {
/* /*
* This information is private to the scsi mid-layer. * This information is private to the scsi mid-layer.
*/ */
struct scsi_device *next; /* Used for linked list */
struct scsi_device *prev; /* Used for linked list */
struct list_head siblings; /* list of all devices on this host */ struct list_head siblings; /* list of all devices on this host */
struct list_head same_target_siblings; /* just the devices sharing same target id */ struct list_head same_target_siblings; /* just the devices sharing same target id */
wait_queue_head_t scpnt_wait; /* Used to wait if wait_queue_head_t scpnt_wait; /* Used to wait if
device is busy */ device is busy */
struct Scsi_Host *host; struct Scsi_Host *host;
request_queue_t request_queue; request_queue_t *request_queue;
atomic_t device_active; /* commands checked out for device */ atomic_t device_active; /* commands checked out for device */
volatile unsigned short device_busy; /* commands actually active on low-level */ volatile unsigned short device_busy; /* commands actually active on low-level */
struct list_head free_cmnds; /* list of available Scsi_Cmnd structs */ struct list_head free_cmnds; /* list of available Scsi_Cmnd structs */
...@@ -894,11 +892,9 @@ extern int scsi_reset_provider(Scsi_Device *, int); ...@@ -894,11 +892,9 @@ extern int scsi_reset_provider(Scsi_Device *, int);
* would be adjustable from 0 to depth. * would be adjustable from 0 to depth.
**/ **/
static inline void scsi_activate_tcq(Scsi_Device *SDpnt, int depth) { static inline void scsi_activate_tcq(Scsi_Device *SDpnt, int depth) {
request_queue_t *q = &SDpnt->request_queue;
if(SDpnt->tagged_supported) { if(SDpnt->tagged_supported) {
if(!blk_queue_tagged(q)) if(!blk_queue_tagged(SDpnt->request_queue))
blk_queue_init_tags(q, depth); blk_queue_init_tags(SDpnt->request_queue, depth);
scsi_adjust_queue_depth(SDpnt, MSG_ORDERED_TAG, depth); scsi_adjust_queue_depth(SDpnt, MSG_ORDERED_TAG, depth);
} }
} }
...@@ -908,10 +904,8 @@ static inline void scsi_activate_tcq(Scsi_Device *SDpnt, int depth) { ...@@ -908,10 +904,8 @@ static inline void scsi_activate_tcq(Scsi_Device *SDpnt, int depth) {
* @SDpnt: device to turn off TCQ for * @SDpnt: device to turn off TCQ for
**/ **/
static inline void scsi_deactivate_tcq(Scsi_Device *SDpnt, int depth) { static inline void scsi_deactivate_tcq(Scsi_Device *SDpnt, int depth) {
request_queue_t *q = &SDpnt->request_queue; if(blk_queue_tagged(SDpnt->request_queue))
blk_queue_free_tags(SDpnt->request_queue);
if(blk_queue_tagged(q))
blk_queue_free_tags(q);
scsi_adjust_queue_depth(SDpnt, 0, depth); scsi_adjust_queue_depth(SDpnt, 0, depth);
} }
...@@ -957,7 +951,7 @@ static inline Scsi_Cmnd *scsi_find_tag(Scsi_Device *SDpnt, int tag) { ...@@ -957,7 +951,7 @@ static inline Scsi_Cmnd *scsi_find_tag(Scsi_Device *SDpnt, int tag) {
/* single command, look in space */ /* single command, look in space */
return SDpnt->current_cmnd; return SDpnt->current_cmnd;
req = blk_queue_find_tag(&SDpnt->request_queue, tag); req = blk_queue_find_tag(SDpnt->request_queue, tag);
if(req == NULL) if(req == NULL)
return NULL; return NULL;
......
...@@ -1487,7 +1487,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost) ...@@ -1487,7 +1487,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
break; break;
} }
__blk_run_queue(&sdev->request_queue); __blk_run_queue(sdev->request_queue);
} }
spin_unlock_irqrestore(shost->host_lock, flags); spin_unlock_irqrestore(shost->host_lock, flags);
} }
......
...@@ -57,9 +57,8 @@ struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR] = { ...@@ -57,9 +57,8 @@ struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR] = {
*/ */
int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head) int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head)
{ {
request_queue_t *q = &SCpnt->device->request_queue; blk_insert_request(SCpnt->device->request_queue, SCpnt->request,
at_head, SCpnt);
blk_insert_request(q, SCpnt->request, at_head, SCpnt);
return 0; return 0;
} }
...@@ -85,16 +84,13 @@ int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head) ...@@ -85,16 +84,13 @@ int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head)
*/ */
int scsi_insert_special_req(Scsi_Request * SRpnt, int at_head) int scsi_insert_special_req(Scsi_Request * SRpnt, int at_head)
{ {
request_queue_t *q = &SRpnt->sr_device->request_queue;
/* This is used to insert SRpnt specials. Because users of /* This is used to insert SRpnt specials. Because users of
* this function are apt to reuse requests with no modification, * this function are apt to reuse requests with no modification,
* we have to sanitise the request flags here * we have to sanitise the request flags here
*/ */
SRpnt->sr_request->flags &= ~REQ_DONTPREP; SRpnt->sr_request->flags &= ~REQ_DONTPREP;
blk_insert_request(SRpnt->sr_device->request_queue, SRpnt->sr_request,
blk_insert_request(q, SRpnt->sr_request, at_head, SRpnt); at_head, SRpnt);
return 0; return 0;
} }
...@@ -215,7 +211,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) ...@@ -215,7 +211,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
{ {
int all_clear; int all_clear;
unsigned long flags; unsigned long flags;
Scsi_Device *SDpnt; Scsi_Device *SDpnt, *SDpnt2;
struct Scsi_Host *SHpnt; struct Scsi_Host *SHpnt;
ASSERT_LOCK(q->queue_lock, 0); ASSERT_LOCK(q->queue_lock, 0);
...@@ -256,17 +252,17 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) ...@@ -256,17 +252,17 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
* with special case code, then spin off separate versions and * with special case code, then spin off separate versions and
* use function pointers to pick the right one. * use function pointers to pick the right one.
*/ */
if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0) { if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0 &&
list_for_each_entry(SDpnt, &SHpnt->my_devices, siblings) { !SHpnt->host_blocked && !SHpnt->host_self_blocked &&
if (((SHpnt->can_queue > 0) !((SHpnt->can_queue > 0) && (SHpnt->host_busy >=
&& (SHpnt->host_busy >= SHpnt->can_queue)) SHpnt->can_queue))) {
|| (SHpnt->host_blocked) list_for_each_entry(SDpnt2, &SDpnt->same_target_siblings,
|| (SHpnt->host_self_blocked) same_target_siblings) {
|| (SDpnt->device_blocked)) { if (!SDpnt2->device_blocked &&
!blk_queue_empty(SDpnt2->request_queue)) {
__blk_run_queue(SDpnt2->request_queue);
break; break;
} }
__blk_run_queue(&SDpnt->request_queue);
} }
} }
...@@ -289,7 +285,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) ...@@ -289,7 +285,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
if (SDpnt->device_blocked || !SDpnt->starved) { if (SDpnt->device_blocked || !SDpnt->starved) {
continue; continue;
} }
__blk_run_queue(&SDpnt->request_queue); __blk_run_queue(SDpnt->request_queue);
all_clear = 0; all_clear = 0;
} }
if (SDpnt == NULL && all_clear) { if (SDpnt == NULL && all_clear) {
...@@ -327,7 +323,7 @@ static Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, ...@@ -327,7 +323,7 @@ static Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt,
int sectors, int sectors,
int requeue) int requeue)
{ {
request_queue_t *q = &SCpnt->device->request_queue; request_queue_t *q = SCpnt->device->request_queue;
struct request *req = SCpnt->request; struct request *req = SCpnt->request;
unsigned long flags; unsigned long flags;
...@@ -497,7 +493,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, ...@@ -497,7 +493,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
{ {
int result = SCpnt->result; int result = SCpnt->result;
int this_count = SCpnt->bufflen >> 9; int this_count = SCpnt->bufflen >> 9;
request_queue_t *q = &SCpnt->device->request_queue; request_queue_t *q = SCpnt->device->request_queue;
struct request *req = SCpnt->request; struct request *req = SCpnt->request;
/* /*
...@@ -1094,7 +1090,7 @@ void scsi_unblock_requests(struct Scsi_Host * SHpnt) ...@@ -1094,7 +1090,7 @@ void scsi_unblock_requests(struct Scsi_Host * SHpnt)
SHpnt->host_self_blocked = FALSE; SHpnt->host_self_blocked = FALSE;
/* Now that we are unblocked, try to start the queues. */ /* Now that we are unblocked, try to start the queues. */
list_for_each_entry(SDloop, &SHpnt->my_devices, siblings) list_for_each_entry(SDloop, &SHpnt->my_devices, siblings)
scsi_queue_next_request(&SDloop->request_queue, NULL); scsi_queue_next_request(SDloop->request_queue, NULL);
} }
/* /*
......
...@@ -371,7 +371,7 @@ static void print_inquiry(unsigned char *inq_result) ...@@ -371,7 +371,7 @@ static void print_inquiry(unsigned char *inq_result)
*/ */
static void scsi_initialize_merge_fn(struct scsi_device *sd) static void scsi_initialize_merge_fn(struct scsi_device *sd)
{ {
request_queue_t *q = &sd->request_queue; request_queue_t *q = sd->request_queue;
struct Scsi_Host *sh = sd->host; struct Scsi_Host *sh = sd->host;
struct device *dev = scsi_get_device(sh); struct device *dev = scsi_get_device(sh);
u64 bounce_limit; u64 bounce_limit;
...@@ -407,14 +407,12 @@ static void scsi_initialize_merge_fn(struct scsi_device *sd) ...@@ -407,14 +407,12 @@ static void scsi_initialize_merge_fn(struct scsi_device *sd)
* Scsi_Device pointer, or NULL on failure. * Scsi_Device pointer, or NULL on failure.
**/ **/
static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
uint channel, uint id, uint lun) struct request_queue **q, uint channel, uint id, uint lun)
{ {
struct scsi_device *sdev, *device; struct scsi_device *sdev, *device;
sdev = kmalloc(sizeof(*sdev), GFP_ATOMIC); sdev = kmalloc(sizeof(*sdev), GFP_ATOMIC);
if (sdev == NULL) if (sdev != NULL) {
printk(ALLOC_FAILURE_MSG, __FUNCTION__);
else {
memset(sdev, 0, sizeof(Scsi_Device)); memset(sdev, 0, sizeof(Scsi_Device));
sdev->vendor = scsi_null_device_strs; sdev->vendor = scsi_null_device_strs;
sdev->model = scsi_null_device_strs; sdev->model = scsi_null_device_strs;
...@@ -436,18 +434,32 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, ...@@ -436,18 +434,32 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
* doesn't * doesn't
*/ */
sdev->borken = 1; sdev->borken = 1;
if (shost->hostt->slave_alloc)
if (shost->hostt->slave_alloc(sdev)) {
kfree(sdev);
return NULL;
}
if(!q || *q == NULL) {
sdev->request_queue = kmalloc(sizeof(struct request_queue), GFP_ATOMIC);
if(sdev->request_queue == NULL) {
goto out_bail;
}
memset(sdev->request_queue, 0,
sizeof(struct request_queue));
scsi_initialize_queue(sdev, shost); scsi_initialize_queue(sdev, shost);
sdev->request_queue.queuedata = (void *) sdev;
scsi_initialize_merge_fn(sdev); scsi_initialize_merge_fn(sdev);
} else {
sdev->request_queue = *q;
*q = NULL;
}
sdev->request_queue->queuedata = sdev;
scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
scsi_build_commandblocks(sdev);
if (sdev->current_queue_depth == 0) {
goto out_bail;
}
init_waitqueue_head(&sdev->scpnt_wait); init_waitqueue_head(&sdev->scpnt_wait);
if (shost->hostt->slave_alloc)
if (shost->hostt->slave_alloc(sdev)) {
goto out_bail;
}
/* /*
* If there are any same target siblings, add this to the * If there are any same target siblings, add this to the
* sibling list * sibling list
...@@ -457,15 +469,35 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, ...@@ -457,15 +469,35 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
device->channel == sdev->channel) { device->channel == sdev->channel) {
list_add_tail(&sdev->same_target_siblings, list_add_tail(&sdev->same_target_siblings,
&device->same_target_siblings); &device->same_target_siblings);
sdev->scsi_level = device->scsi_level;
break; break;
} }
} }
/*
* If there wasn't another lun already configured at this
* target, then default this device to SCSI_2 until we
* know better
*/
if(!sdev->scsi_level)
sdev->scsi_level = SCSI_2;
/* /*
* Add it to the end of the shost->my_devices list. * Add it to the end of the shost->my_devices list.
*/ */
list_add_tail(&sdev->siblings, &shost->my_devices); list_add_tail(&sdev->siblings, &shost->my_devices);
}
return (sdev); return (sdev);
}
out_bail:
printk(ALLOC_FAILURE_MSG, __FUNCTION__);
if(q && sdev->request_queue) {
*q = sdev->request_queue;
sdev->request_queue = NULL;
} else if(sdev->request_queue) {
blk_cleanup_queue(sdev->request_queue);
kfree(sdev->request_queue);
}
scsi_release_commandblocks(sdev);
kfree(sdev);
return NULL;
} }
/** /**
...@@ -481,7 +513,10 @@ static void scsi_free_sdev(struct scsi_device *sdev) ...@@ -481,7 +513,10 @@ static void scsi_free_sdev(struct scsi_device *sdev)
list_del(&sdev->siblings); list_del(&sdev->siblings);
list_del(&sdev->same_target_siblings); list_del(&sdev->same_target_siblings);
blk_cleanup_queue(&sdev->request_queue); if(sdev->request_queue != NULL) {
blk_cleanup_queue(sdev->request_queue);
kfree(sdev->request_queue);
}
scsi_release_commandblocks(sdev); scsi_release_commandblocks(sdev);
if (sdev->host->hostt->slave_destroy) if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev); sdev->host->hostt->slave_destroy(sdev);
...@@ -1188,18 +1223,11 @@ static void scsi_probe_lun(Scsi_Request *sreq, char *inq_result, ...@@ -1188,18 +1223,11 @@ static void scsi_probe_lun(Scsi_Request *sreq, char *inq_result,
* SCSI_SCAN_NO_RESPONSE: could not allocate or setup a Scsi_Device * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a Scsi_Device
* SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized * SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized
**/ **/
static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, static int scsi_add_lun(Scsi_Device *sdev, Scsi_Request *sreq,
Scsi_Request *sreq, char *inq_result, int *bflags) char *inq_result, int *bflags)
{ {
Scsi_Device *sdev;
char devname[64]; char devname[64];
sdev = scsi_alloc_sdev(sdevscan->host, sdevscan->channel,
sdevscan->id, sdevscan->lun);
if (sdev == NULL)
return SCSI_SCAN_NO_RESPONSE;
sdev->scsi_level = sdevscan->scsi_level;
/* /*
* XXX do not save the inquiry, since it can change underneath us, * XXX do not save the inquiry, since it can change underneath us,
* save just vendor/model/rev. * save just vendor/model/rev.
...@@ -1210,10 +1238,8 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, ...@@ -1210,10 +1238,8 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
* scanning run at their own risk, or supply a user level program * scanning run at their own risk, or supply a user level program
* that can correctly scan. * that can correctly scan.
*/ */
sdev->inquiry_len = sdevscan->inquiry_len;
sdev->inquiry = kmalloc(sdev->inquiry_len, GFP_ATOMIC); sdev->inquiry = kmalloc(sdev->inquiry_len, GFP_ATOMIC);
if (sdev->inquiry == NULL) { if (sdev->inquiry == NULL) {
scsi_free_sdev(sdev);
return SCSI_SCAN_NO_RESPONSE; return SCSI_SCAN_NO_RESPONSE;
} }
...@@ -1335,8 +1361,8 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, ...@@ -1335,8 +1361,8 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
* function */ * function */
sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED; sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED;
if (sdevnew != NULL) if(sdev->host->hostt->slave_configure)
*sdevnew = sdev; sdev->host->hostt->slave_configure(sdev);
return SCSI_SCAN_LUN_PRESENT; return SCSI_SCAN_LUN_PRESENT;
} }
...@@ -1365,8 +1391,9 @@ static void scsi_remove_lun(struct scsi_device *sdev) ...@@ -1365,8 +1391,9 @@ static void scsi_remove_lun(struct scsi_device *sdev)
* attached at the LUN * attached at the LUN
* SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized * SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized
**/ **/
static int scsi_probe_and_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, static int scsi_probe_and_add_lun(struct Scsi_Host *host,
int *bflagsp) struct request_queue **q, uint channel, uint id,
uint lun, int *bflagsp)
{ {
Scsi_Device *sdev = NULL; Scsi_Device *sdev = NULL;
Scsi_Request *sreq = NULL; Scsi_Request *sreq = NULL;
...@@ -1374,47 +1401,27 @@ static int scsi_probe_and_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, ...@@ -1374,47 +1401,27 @@ static int scsi_probe_and_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
int bflags; int bflags;
int res; int res;
/* sdev = scsi_alloc_sdev(host, q, channel, id, lun);
* Any command blocks allocated are fixed to use sdevscan->lun, if (sdev == NULL)
* so they must be allocated and released if sdevscan->lun return SCSI_SCAN_NO_RESPONSE;
* changes. sreq = scsi_allocate_request(sdev);
* if (sreq == NULL) {
* XXX optimize and don't call build/release commandblocks, instead printk(ALLOC_FAILURE_MSG, __FUNCTION__);
* modify the LUN value of the existing command block - this means res = SCSI_SCAN_NO_RESPONSE;
* the build/release calls would be moved to the alloc/free of goto bail_out;
* sdevscan, and the modifying function would be called here. }
*
* XXX maybe change scsi_release_commandblocks to not reset
* queue_depth to 0.
*/
sdevscan->new_queue_depth = 1;
scsi_build_commandblocks(sdevscan);
if (sdevscan->current_queue_depth == 0)
goto alloc_failed;
/*
* Since we reuse the same sdevscan over and over with different
* target and lun values, we have to destroy and then recreate
* any possible low level attachments since they very will might
* also store the id and lun numbers in some form and need updating
* with each scan.
*/
if (sdevscan->host->hostt->slave_destroy)
sdevscan->host->hostt->slave_destroy(sdevscan);
if (sdevscan->host->hostt->slave_alloc)
sdevscan->host->hostt->slave_alloc(sdevscan);
sreq = scsi_allocate_request(sdevscan);
if (sreq == NULL)
goto alloc_failed;
/* /*
* The sreq is for use only with sdevscan. * The sreq is for use only with sdevscan.
*/ */
scsi_result = kmalloc(256, GFP_ATOMIC | scsi_result = kmalloc(256, GFP_ATOMIC |
(sdevscan->host->unchecked_isa_dma) ? (host->unchecked_isa_dma) ?
GFP_DMA : 0); GFP_DMA : 0);
if (scsi_result == NULL) if (scsi_result == NULL) {
goto alloc_failed; printk(ALLOC_FAILURE_MSG, __FUNCTION__);
res = SCSI_SCAN_NO_RESPONSE;
goto bail_out;
}
scsi_probe_lun(sreq, scsi_result, &bflags); scsi_probe_lun(sreq, scsi_result, &bflags);
if (sreq->sr_result) if (sreq->sr_result)
...@@ -1439,10 +1446,8 @@ static int scsi_probe_and_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, ...@@ -1439,10 +1446,8 @@ static int scsi_probe_and_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
" no device added\n")); " no device added\n"));
res = SCSI_SCAN_TARGET_PRESENT; res = SCSI_SCAN_TARGET_PRESENT;
} else { } else {
res = scsi_add_lun(sdevscan, &sdev, sreq, scsi_result, res = scsi_add_lun(sdev, sreq, scsi_result, &bflags);
&bflags);
if (res == SCSI_SCAN_LUN_PRESENT) { if (res == SCSI_SCAN_LUN_PRESENT) {
BUG_ON(sdev == NULL);
if ((bflags & BLIST_KEY) != 0) { if ((bflags & BLIST_KEY) != 0) {
sdev->lockable = 0; sdev->lockable = 0;
scsi_unlock_floptical(sreq, scsi_unlock_floptical(sreq,
...@@ -1452,31 +1457,25 @@ static int scsi_probe_and_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, ...@@ -1452,31 +1457,25 @@ static int scsi_probe_and_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
* the INQUIRY data. * the INQUIRY data.
*/ */
} }
/*
* "hardcoded" scans of a single LUN need
* to know the sdev just allocated.
*/
if (sdevnew != NULL)
*sdevnew = sdev;
if (bflagsp != NULL) if (bflagsp != NULL)
*bflagsp = bflags; *bflagsp = bflags;
} }
} }
} }
kfree(scsi_result); bail_out:
scsi_release_request(sreq);
scsi_release_commandblocks(sdevscan);
return res;
alloc_failed:
printk(ALLOC_FAILURE_MSG, __FUNCTION__);
if (scsi_result != NULL) if (scsi_result != NULL)
kfree(scsi_result); kfree(scsi_result);
if (sreq != NULL) if (sreq != NULL)
scsi_release_request(sreq); scsi_release_request(sreq);
if (sdevscan->current_queue_depth != 0) if (res != SCSI_SCAN_LUN_PRESENT) {
scsi_release_commandblocks(sdevscan); if(q) {
return SCSI_SCAN_NO_RESPONSE; *q = sdev->request_queue;
sdev->request_queue = NULL;
}
scsi_free_sdev(sdev);
}
return res;
} }
/** /**
...@@ -1492,16 +1491,15 @@ static int scsi_probe_and_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, ...@@ -1492,16 +1491,15 @@ static int scsi_probe_and_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
* *
* Modifies sdevscan->lun. * Modifies sdevscan->lun.
**/ **/
static void scsi_sequential_lun_scan(Scsi_Device *sdevscan, int bflags, static void scsi_sequential_lun_scan(struct Scsi_Host *shost,
int lun0_res) struct request_queue **q, uint channel, uint id,
int bflags, int lun0_res, int scsi_level)
{ {
struct Scsi_Host *shost = sdevscan->host; unsigned int sparse_lun, lun, max_dev_lun;
unsigned int sparse_lun;
unsigned int max_dev_lun;
SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: Sequential scan of" SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: Sequential scan of"
" host %d channel %d id %d\n", sdevscan->host->host_no, " host %d channel %d id %d\n", shost->host_no,
sdevscan->channel, sdevscan->id)); channel, id));
max_dev_lun = min(max_scsi_luns, shost->max_lun); max_dev_lun = min(max_scsi_luns, shost->max_lun);
/* /*
...@@ -1526,11 +1524,19 @@ static void scsi_sequential_lun_scan(Scsi_Device *sdevscan, int bflags, ...@@ -1526,11 +1524,19 @@ static void scsi_sequential_lun_scan(Scsi_Device *sdevscan, int bflags,
* If less than SCSI_1_CSS, and no special lun scaning, stop * If less than SCSI_1_CSS, and no special lun scaning, stop
* scanning; this matches 2.4 behaviour, but could just be a bug * scanning; this matches 2.4 behaviour, but could just be a bug
* (to continue scanning a SCSI_1_CSS device). * (to continue scanning a SCSI_1_CSS device).
*/ *
* This test is broken. We might not have any device on lun0 for
* a sparselun device, and if that's the case then how would we
* know the real scsi_level, eh? It might make sense to just not
* scan any SCSI_1 device for non-0 luns, but that check would best
* go into scsi_alloc_sdev() and just have it return null when asked
* to alloc an sdev for lun > 0 on an already found SCSI_1 device.
*
if ((sdevscan->scsi_level < SCSI_1_CCS) && if ((sdevscan->scsi_level < SCSI_1_CCS) &&
((bflags & (BLIST_FORCELUN | BLIST_SPARSELUN | BLIST_MAX5LUN)) ((bflags & (BLIST_FORCELUN | BLIST_SPARSELUN | BLIST_MAX5LUN))
== 0)) == 0))
return; return;
*/
/* /*
* If this device is known to support multiple units, override * If this device is known to support multiple units, override
* the other settings, and scan all of them. * the other settings, and scan all of them.
...@@ -1546,7 +1552,7 @@ static void scsi_sequential_lun_scan(Scsi_Device *sdevscan, int bflags, ...@@ -1546,7 +1552,7 @@ static void scsi_sequential_lun_scan(Scsi_Device *sdevscan, int bflags,
* Do not scan SCSI-2 or lower device past LUN 7, unless * Do not scan SCSI-2 or lower device past LUN 7, unless
* BLIST_LARGELUN. * BLIST_LARGELUN.
*/ */
if ((sdevscan->scsi_level < SCSI_3) && !(bflags & BLIST_LARGELUN)) if (scsi_level < SCSI_3 && !(bflags & BLIST_LARGELUN))
max_dev_lun = min(8U, max_dev_lun); max_dev_lun = min(8U, max_dev_lun);
/* /*
...@@ -1554,8 +1560,8 @@ static void scsi_sequential_lun_scan(Scsi_Device *sdevscan, int bflags, ...@@ -1554,8 +1560,8 @@ static void scsi_sequential_lun_scan(Scsi_Device *sdevscan, int bflags,
* until we reach the max, or no LUN is found and we are not * until we reach the max, or no LUN is found and we are not
* sparse_lun. * sparse_lun.
*/ */
for (sdevscan->lun = 1; sdevscan->lun < max_dev_lun; ++sdevscan->lun) for (lun = 1; lun < max_dev_lun; ++lun)
if ((scsi_probe_and_add_lun(sdevscan, NULL, NULL) if ((scsi_probe_and_add_lun(shost, q, channel, id, lun, NULL)
!= SCSI_SCAN_LUN_PRESENT) && !sparse_lun) != SCSI_SCAN_LUN_PRESENT) && !sparse_lun)
return; return;
} }
...@@ -1608,7 +1614,8 @@ static int scsilun_to_int(ScsiLun *scsilun) ...@@ -1608,7 +1614,8 @@ static int scsilun_to_int(ScsiLun *scsilun)
* 0: scan completed (or no memory, so further scanning is futile) * 0: scan completed (or no memory, so further scanning is futile)
* 1: no report lun scan, or not configured * 1: no report lun scan, or not configured
**/ **/
static int scsi_report_lun_scan(Scsi_Device *sdevscan) static int scsi_report_lun_scan(Scsi_Device *sdev, struct request_queue **q,
int bflags)
{ {
#ifdef CONFIG_SCSI_REPORT_LUNS #ifdef CONFIG_SCSI_REPORT_LUNS
...@@ -1625,38 +1632,19 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan) ...@@ -1625,38 +1632,19 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan)
/* /*
* Only support SCSI-3 and up devices. * Only support SCSI-3 and up devices.
*/ */
if (sdevscan->scsi_level < SCSI_3) if (sdev->scsi_level < SCSI_3)
return 1; return 1;
if (bflags & BLIST_NOLUN)
return 0;
sdevscan->new_queue_depth = 1; sreq = scsi_allocate_request(sdev);
scsi_build_commandblocks(sdevscan); if (sreq == NULL) {
if (sdevscan->current_queue_depth == 0) {
printk(ALLOC_FAILURE_MSG, __FUNCTION__); printk(ALLOC_FAILURE_MSG, __FUNCTION__);
/*
* We are out of memory, don't try scanning any further.
*/
return 0; return 0;
} }
/*
* Since we reuse the same sdevscan over and over with different
* target and lun values, we have to destroy and then recreate
* any possible low level attachments since they very will might
* also store the id and lun numbers in some form and need updating
* with each scan.
*
* This is normally handled in probe_and_add_lun, but since this
* one particular function wants to scan lun 0 on each device
* itself and will possibly pick up a resed sdevscan when doing
* so, it also needs this hack.
*/
if (sdevscan->host->hostt->slave_destroy)
sdevscan->host->hostt->slave_destroy(sdevscan);
if (sdevscan->host->hostt->slave_alloc)
sdevscan->host->hostt->slave_alloc(sdevscan);
sreq = scsi_allocate_request(sdevscan);
sprintf(devname, "host %d channel %d id %d", sdevscan->host->host_no, sprintf(devname, "host %d channel %d id %d", sdev->host->host_no,
sdevscan->channel, sdevscan->id); sdev->channel, sdev->id);
/* /*
* Allocate enough to hold the header (the same size as one ScsiLun) * Allocate enough to hold the header (the same size as one ScsiLun)
* plus the max number of luns we are requesting. * plus the max number of luns we are requesting.
...@@ -1669,11 +1657,11 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan) ...@@ -1669,11 +1657,11 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan)
*/ */
length = (max_scsi_report_luns + 1) * sizeof(ScsiLun); length = (max_scsi_report_luns + 1) * sizeof(ScsiLun);
lun_data = (ScsiLun *) kmalloc(length, GFP_ATOMIC | lun_data = (ScsiLun *) kmalloc(length, GFP_ATOMIC |
(sdevscan->host->unchecked_isa_dma ? (sdev->host->unchecked_isa_dma ?
GFP_DMA : 0)); GFP_DMA : 0));
if (lun_data == NULL) { if (lun_data == NULL) {
printk(ALLOC_FAILURE_MSG, __FUNCTION__); printk(ALLOC_FAILURE_MSG, __FUNCTION__);
scsi_release_commandblocks(sdevscan); scsi_release_request(sreq);
/* /*
* We are out of memory, don't try scanning any further. * We are out of memory, don't try scanning any further.
*/ */
...@@ -1723,7 +1711,6 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan) ...@@ -1723,7 +1711,6 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan)
|| sreq->sr_sense_buffer[2] != UNIT_ATTENTION) || sreq->sr_sense_buffer[2] != UNIT_ATTENTION)
break; break;
} }
scsi_release_commandblocks(sdevscan);
if (sreq->sr_result) { if (sreq->sr_result) {
/* /*
...@@ -1751,8 +1738,8 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan) ...@@ -1751,8 +1738,8 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan)
num_luns = (length / sizeof(ScsiLun)); num_luns = (length / sizeof(ScsiLun));
SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUN scan of" SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUN scan of"
" host %d channel %d id %d\n", sdevscan->host->host_no, " host %d channel %d id %d\n", sdev->host->host_no,
sdevscan->channel, sdevscan->id)); sdev->channel, sdev->id));
/* /*
* Scan the luns in lun_data. The entry at offset 0 is really * Scan the luns in lun_data. The entry at offset 0 is really
* the header, so start at 1 and go up to and including num_luns. * the header, so start at 1 and go up to and including num_luns.
...@@ -1782,22 +1769,22 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan) ...@@ -1782,22 +1769,22 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan)
/* /*
* LUN 0 has already been scanned. * LUN 0 has already been scanned.
*/ */
} else if (lun > sdevscan->host->max_lun) { } else if (lun > sdev->host->max_lun) {
printk(KERN_WARNING "scsi: %s lun%d has a LUN larger" printk(KERN_WARNING "scsi: %s lun%d has a LUN larger"
" than allowed by the host adapter\n", " than allowed by the host adapter\n",
devname, lun); devname, lun);
} else { } else {
int res; int res;
sdevscan->lun = lun; res = scsi_probe_and_add_lun(sdev->host, q,
res = scsi_probe_and_add_lun(sdevscan, NULL, NULL); sdev->channel, sdev->id, lun, NULL);
if (res == SCSI_SCAN_NO_RESPONSE) { if (res == SCSI_SCAN_NO_RESPONSE) {
/* /*
* Got some results, but now none, abort. * Got some results, but now none, abort.
*/ */
printk(KERN_ERR "scsi: Unexpected response" printk(KERN_ERR "scsi: Unexpected response"
" from %s lun %d while scanning, scan" " from %s lun %d while scanning, scan"
" aborted\n", devname, sdevscan->lun); " aborted\n", devname, lun);
break; break;
} }
} }
...@@ -1814,38 +1801,22 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan) ...@@ -1814,38 +1801,22 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan)
int scsi_add_single_device(uint host, uint channel, uint id, uint lun) int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
{ {
struct scsi_device *sdevscan, *sdev;
struct Scsi_Host *shost; struct Scsi_Host *shost;
int error = -ENODEV; int error = -ENODEV;
struct scsi_device *sdev;
shost = scsi_host_hn_get(host); shost = scsi_host_hn_get(host);
if (!shost) if (!shost)
return -ENODEV; return -ENODEV;
sdev = scsi_find_device(shost, channel, id, lun); if(scsi_find_device(shost, channel, id, lun) != NULL)
if (sdev)
goto out;
error = -ENOMEM;
sdevscan = scsi_alloc_sdev(shost, channel, id, lun);
if (!sdevscan)
goto out; goto out;
if(!list_empty(&sdevscan->same_target_siblings)) { if (scsi_probe_and_add_lun(shost, NULL, channel, id, lun, NULL) ==
sdev = list_entry(&sdevscan->same_target_siblings, Scsi_Device, SCSI_SCAN_LUN_PRESENT) {
same_target_siblings);
sdevscan->scsi_level = sdev->scsi_level;
sdev = NULL;
} else
sdevscan->scsi_level = SCSI_2;
error = scsi_probe_and_add_lun(sdevscan, &sdev, NULL);
scsi_free_sdev(sdevscan);
if (error != SCSI_SCAN_LUN_PRESENT)
goto out;
scsi_attach_device(sdev);
error = 0; error = 0;
sdev = scsi_find_device(shost, channel, id, lun);
scsi_attach_device(sdev);
}
out: out:
scsi_host_put(shost); scsi_host_put(shost);
return error; return error;
...@@ -1898,11 +1869,12 @@ int scsi_remove_single_device(uint host, uint channel, uint id, uint lun) ...@@ -1898,11 +1869,12 @@ int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
* First try a REPORT LUN scan, if that does not scan the target, do a * First try a REPORT LUN scan, if that does not scan the target, do a
* sequential scan of LUNs on the target id. * sequential scan of LUNs on the target id.
**/ **/
static void scsi_scan_target(Scsi_Device *sdevscan, struct Scsi_Host *shost, static void scsi_scan_target(struct Scsi_Host *shost, struct request_queue **q,
unsigned int channel, unsigned int id) unsigned int channel, unsigned int id)
{ {
int bflags; int bflags = 0;
int res; int res;
struct scsi_device *sdev;
if (shost->this_id == id) if (shost->this_id == id)
/* /*
...@@ -1910,36 +1882,29 @@ static void scsi_scan_target(Scsi_Device *sdevscan, struct Scsi_Host *shost, ...@@ -1910,36 +1882,29 @@ static void scsi_scan_target(Scsi_Device *sdevscan, struct Scsi_Host *shost,
*/ */
return; return;
sdevscan->host = shost;
sdevscan->id = id;
sdevscan->channel = channel;
/* /*
* Scan LUN 0, if there is some response, scan further. Ideally, we * Scan LUN 0, if there is some response, scan further. Ideally, we
* would not configure LUN 0 until all LUNs are scanned. * would not configure LUN 0 until all LUNs are scanned.
*
* The scsi_level is set (in scsi_probe_lun) if a target responds.
*/
sdevscan->lun = 0;
res = scsi_probe_and_add_lun(sdevscan, NULL, &bflags);
if (res != SCSI_SCAN_NO_RESPONSE) {
/*
* Some scsi devices cannot properly handle a lun != 0.
* BLIST_NOLUN also prevents a REPORT LUN from being sent.
* Any multi-lun SCSI-3 device that hangs because of a
* REPORT LUN command is seriously broken.
*/
if (!(bflags & BLIST_NOLUN))
/*
* Ending the scan here if max_scsi_luns == 1
* breaks scanning of SPARSE, FORCE, MAX5 LUN
* devices, and the report lun scan.
*/ */
if (scsi_report_lun_scan(sdevscan) != 0) res = scsi_probe_and_add_lun(shost, q, channel, id, 0, &bflags);
if (res == SCSI_SCAN_LUN_PRESENT) {
sdev = scsi_find_device(shost, channel, id, 0);
if (scsi_report_lun_scan(sdev, q, bflags) != 0)
/* /*
* The REPORT LUN did not scan the target, * The REPORT LUN did not scan the target,
* do a sequential scan. * do a sequential scan.
*/ */
scsi_sequential_lun_scan(sdevscan, bflags, res); scsi_sequential_lun_scan(shost, q, channel, id, bflags,
res, sdev->scsi_level);
} else if (res == SCSI_SCAN_TARGET_PRESENT) {
/*
* There's a target here, but lun 0 is offline so we
* can't use the report_lun scan. Fall back to a
* sequential lun scan with a bflags of SPARSELUN and
* a default scsi level of SCSI_2
*/
scsi_sequential_lun_scan(shost, q, channel, id, BLIST_SPARSELUN,
SCSI_SCAN_TARGET_PRESENT, SCSI_2);
} }
} }
...@@ -1953,22 +1918,9 @@ static void scsi_scan_target(Scsi_Device *sdevscan, struct Scsi_Host *shost, ...@@ -1953,22 +1918,9 @@ static void scsi_scan_target(Scsi_Device *sdevscan, struct Scsi_Host *shost,
**/ **/
void scsi_scan_host(struct Scsi_Host *shost) void scsi_scan_host(struct Scsi_Host *shost)
{ {
struct scsi_device *sdevscan; struct request_queue *q = NULL;
uint channel, id, order_id; uint channel, id, order_id;
/*
* The blk layer queue allocation is a bit expensive to
* repeat for each channel and id - for FCP max_id is near
* 255: each call to scsi_alloc_sdev() implies a call to
* blk_init_queue, and then blk_init_free_list, where 2 *
* queue_nr_requests requests are allocated. Don't do so
* here for scsi_scan_selected_lun, since we end up
* calling select_queue_depths with an extra Scsi_Device
* on the host_queue list.
*/
sdevscan = scsi_alloc_sdev(shost, 0, 0, 0);
if (sdevscan == NULL)
return;
/* /*
* The sdevscan host, channel, id and lun are filled in as * The sdevscan host, channel, id and lun are filled in as
* needed to scan. * needed to scan.
...@@ -1991,11 +1943,13 @@ void scsi_scan_host(struct Scsi_Host *shost) ...@@ -1991,11 +1943,13 @@ void scsi_scan_host(struct Scsi_Host *shost)
order_id = shost->max_id - id - 1; order_id = shost->max_id - id - 1;
else else
order_id = id; order_id = id;
scsi_scan_target(sdevscan, shost, channel, scsi_scan_target(shost, &q, channel, order_id);
order_id);
} }
} }
scsi_free_sdev(sdevscan); if(q) {
blk_cleanup_queue(q);
kfree(q);
}
} }
void scsi_forget_host(struct Scsi_Host *shost) void scsi_forget_host(struct Scsi_Host *shost)
...@@ -2030,19 +1984,11 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) ...@@ -2030,19 +1984,11 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
{ {
struct scsi_device *sdev; struct scsi_device *sdev;
sdev = scsi_alloc_sdev(shost, 0, shost->this_id, 0); sdev = scsi_alloc_sdev(shost, NULL, 0, shost->this_id, 0);
if (sdev) { if (sdev) {
scsi_build_commandblocks(sdev);
if (sdev->current_queue_depth == 0)
goto fail;
sdev->borken = 0; sdev->borken = 0;
} }
return sdev; return sdev;
fail:
kfree(sdev);
return NULL;
} }
/* /*
......
...@@ -301,10 +301,10 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) ...@@ -301,10 +301,10 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
if (block > 0xffffffff) { if (block > 0xffffffff) {
SCpnt->cmnd[0] += READ_16 - READ_6; SCpnt->cmnd[0] += READ_16 - READ_6;
SCpnt->cmnd[2] = (unsigned char) (block >> 56) & 0xff; SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0;
SCpnt->cmnd[3] = (unsigned char) (block >> 48) & 0xff; SCpnt->cmnd[3] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0;
SCpnt->cmnd[4] = (unsigned char) (block >> 40) & 0xff; SCpnt->cmnd[4] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0;
SCpnt->cmnd[5] = (unsigned char) (block >> 32) & 0xff; SCpnt->cmnd[5] = sizeof(block) > 4 ? (unsigned char) (block >> 32) & 0xff : 0;
SCpnt->cmnd[6] = (unsigned char) (block >> 24) & 0xff; SCpnt->cmnd[6] = (unsigned char) (block >> 24) & 0xff;
SCpnt->cmnd[7] = (unsigned char) (block >> 16) & 0xff; SCpnt->cmnd[7] = (unsigned char) (block >> 16) & 0xff;
SCpnt->cmnd[8] = (unsigned char) (block >> 8) & 0xff; SCpnt->cmnd[8] = (unsigned char) (block >> 8) & 0xff;
...@@ -931,7 +931,7 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname, ...@@ -931,7 +931,7 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
if (longrc) { if (longrc) {
memset((void *) cmd, 0, 16); memset((void *) cmd, 0, 16);
cmd[0] = SERVICE_ACTION_IN; cmd[0] = SERVICE_ACTION_IN;
cmd[1] = 0x10; /* READ CAPACITY (16) */ cmd[1] = SAI_READ_CAPACITY_16;
cmd[13] = 12; cmd[13] = 12;
memset((void *) buffer, 0, 12); memset((void *) buffer, 0, 12);
} else { } else {
...@@ -1003,20 +1003,24 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname, ...@@ -1003,20 +1003,24 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
(buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
if (buffer[0] == 0xff && buffer[1] == 0xff && if (buffer[0] == 0xff && buffer[1] == 0xff &&
buffer[2] == 0xff && buffer[3] == 0xff) { buffer[2] == 0xff && buffer[3] == 0xff) {
if(sizeof(sdkp->capacity) > 4) {
printk(KERN_NOTICE "%s : very big device. try to use" printk(KERN_NOTICE "%s : very big device. try to use"
" READ CAPACITY(16).\n", diskname); " READ CAPACITY(16).\n", diskname);
longrc = 1; longrc = 1;
goto repeat; goto repeat;
} else {
printk(KERN_ERR "%s: too big for kernel. Assuming maximum 2Tb\n", diskname);
}
} }
sdkp->capacity = 1 + (((sector_t)buffer[0] << 24) | sdkp->capacity = 1 + (((sector_t)buffer[0] << 24) |
(buffer[1] << 16) | (buffer[1] << 16) |
(buffer[2] << 8) | (buffer[2] << 8) |
buffer[3]); buffer[3]);
} else { } else {
sdkp->capacity = 1 + (((sector_t)buffer[0] << 56) | sdkp->capacity = 1 + (((u64)buffer[0] << 56) |
((sector_t)buffer[1] << 48) | ((u64)buffer[1] << 48) |
((sector_t)buffer[2] << 40) | ((u64)buffer[2] << 40) |
((sector_t)buffer[3] << 32) | ((u64)buffer[3] << 32) |
((sector_t)buffer[4] << 24) | ((sector_t)buffer[4] << 24) |
((sector_t)buffer[5] << 16) | ((sector_t)buffer[5] << 16) |
((sector_t)buffer[6] << 8) | ((sector_t)buffer[6] << 8) |
...@@ -1056,7 +1060,7 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname, ...@@ -1056,7 +1060,7 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
*/ */
int hard_sector = sector_size; int hard_sector = sector_size;
sector_t sz = sdkp->capacity * (hard_sector/256); sector_t sz = sdkp->capacity * (hard_sector/256);
request_queue_t *queue = &sdp->request_queue; request_queue_t *queue = sdp->request_queue;
sector_t mb; sector_t mb;
blk_queue_hardsect_size(queue, hard_sector); blk_queue_hardsect_size(queue, hard_sector);
...@@ -1291,7 +1295,7 @@ static int sd_attach(struct scsi_device * sdp) ...@@ -1291,7 +1295,7 @@ static int sd_attach(struct scsi_device * sdp)
if (sdp->removable) if (sdp->removable)
gd->flags |= GENHD_FL_REMOVABLE; gd->flags |= GENHD_FL_REMOVABLE;
gd->private_data = &sdkp->driver; gd->private_data = &sdkp->driver;
gd->queue = &sdkp->device->request_queue; gd->queue = sdkp->device->request_queue;
sd_devlist_insert(sdkp); sd_devlist_insert(sdkp);
set_capacity(gd, sdkp->capacity); set_capacity(gd, sdkp->capacity);
......
...@@ -695,7 +695,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, ...@@ -695,7 +695,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
} }
srp->my_cmdp = SRpnt; srp->my_cmdp = SRpnt;
q = &SRpnt->sr_device->request_queue; q = SRpnt->sr_device->request_queue;
SRpnt->sr_request->rq_disk = sdp->disk; SRpnt->sr_request->rq_disk = sdp->disk;
SRpnt->sr_sense_buffer[0] = 0; SRpnt->sr_sense_buffer[0] = 0;
SRpnt->sr_cmd_len = hp->cmd_len; SRpnt->sr_cmd_len = hp->cmd_len;
......
...@@ -563,7 +563,7 @@ static int sr_attach(struct scsi_device *sdev) ...@@ -563,7 +563,7 @@ static int sr_attach(struct scsi_device *sdev)
register_cdrom(&cd->cdi); register_cdrom(&cd->cdi);
set_capacity(disk, cd->capacity); set_capacity(disk, cd->capacity);
disk->private_data = &cd->driver; disk->private_data = &cd->driver;
disk->queue = &sdev->request_queue; disk->queue = sdev->request_queue;
add_disk(disk); add_disk(disk);
sr_devlist_insert(cd); sr_devlist_insert(cd);
...@@ -672,7 +672,7 @@ static void get_sectorsize(struct scsi_cd *cd) ...@@ -672,7 +672,7 @@ static void get_sectorsize(struct scsi_cd *cd)
set_capacity(cd->disk, cd->capacity); set_capacity(cd->disk, cd->capacity);
} }
queue = &cd->device->request_queue; queue = cd->device->request_queue;
blk_queue_hardsect_size(queue, sector_size); blk_queue_hardsect_size(queue, sector_size);
out: out:
kfree(buffer); kfree(buffer);
......
...@@ -99,6 +99,8 @@ extern const unsigned char scsi_command_size[8]; ...@@ -99,6 +99,8 @@ extern const unsigned char scsi_command_size[8];
#define READ_16 0x88 #define READ_16 0x88
#define WRITE_16 0x8a #define WRITE_16 0x8a
#define SERVICE_ACTION_IN 0x9e #define SERVICE_ACTION_IN 0x9e
/* values for service action in */
#define SAI_READ_CAPACITY_16 0x10
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment