Commit 6ed83574 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.35pre6

parent 159f5e24
......@@ -30,7 +30,6 @@
struct pci_bus *pci_root;
struct pci_dev *pci_devices = NULL;
static struct pci_dev **pci_last_dev_p = &pci_devices;
static int pci_reverse __initdata = 0;
struct pci_dev *
pci_find_slot(unsigned int bus, unsigned int devfn)
......@@ -270,7 +269,7 @@ static inline unsigned int pci_resource_flags(unsigned int flags)
return IORESOURCE_MEM;
}
void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
static void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
{
unsigned int pos, reg, next;
u32 l, sz, tmp;
......@@ -433,7 +432,7 @@ static __init struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci
/*
* Set up the primary, secondary and subordinate
* bus numbers. Read resource ranges behind the bridge.
* bus numbers.
*/
child->number = child->secondary = busnr;
child->primary = parent->secondary;
......@@ -578,24 +577,29 @@ static __init void pci_read_irq(struct pci_dev *dev)
}
/*
* Read the config data for a PCI device
* and sanity-check it and fill in the dev
* structure...
* Read the config data for a PCI device, sanity-check it
* and fill in the dev structure...
*/
static __init int pci_scan_device(struct pci_bus *bus, struct pci_dev *dev, unsigned int devfn)
static struct pci_dev * __init pci_scan_device(struct pci_dev *temp)
{
unsigned int l, class;
struct pci_dev *dev;
u32 l, class;
if (pci_read_config_dword(dev, PCI_VENDOR_ID, &l))
return -1;
if (pci_read_config_dword(temp, PCI_VENDOR_ID, &l))
return NULL;
/* some broken boards return 0 if a slot is empty: */
/* some broken boards return 0 or ~0 if a slot is empty: */
if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000)
return -1;
return NULL;
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return NULL;
memcpy(dev, temp, sizeof(*dev));
dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff;
sprintf(dev->slot_name, "%02x:%02x.%d", bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
sprintf(dev->slot_name, "%02x:%02x.%d", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
pci_name_device(dev);
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
......@@ -631,7 +635,8 @@ static __init int pci_scan_device(struct pci_bus *bus, struct pci_dev *dev, unsi
default: /* unknown header */
printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n",
dev->slot_name, dev->hdr_type);
return -1;
kfree(dev);
return NULL;
bad:
printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n",
......@@ -640,47 +645,32 @@ static __init int pci_scan_device(struct pci_bus *bus, struct pci_dev *dev, unsi
}
/* We found a fine healthy device, go go go... */
return 0;
return dev;
}
static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
struct pci_dev * __init pci_scan_slot(struct pci_dev *temp)
{
unsigned int devfn, max;
struct pci_dev *dev, **bus_last;
struct pci_bus *bus = temp->bus;
struct pci_dev *dev;
struct pci_dev *first_dev = NULL;
int func = 0;
int is_multi = 0;
u8 hdr_type;
DBG("pci_do_scan_bus for bus %d\n", bus->number);
bus_last = &bus->devices;
max = bus->secondary;
/* Allocate the device ahead of time.. */
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return max;
/* Go find them, Rover! */
for (devfn = 0; devfn < 0xff; ++devfn) {
unsigned char hdr_type;
/* not a multi-function device */
if (PCI_FUNC(devfn) && !is_multi)
for (func = 0; func < 8; func++, temp->devfn++) {
if (func && !is_multi) /* not a multi-function device */
continue;
memset(dev, 0, sizeof(*dev));
dev->bus = bus;
dev->sysdata = bus->sysdata;
dev->devfn = devfn;
if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
continue;
temp->hdr_type = hdr_type & 0x7f;
if (!PCI_FUNC(devfn))
is_multi = hdr_type & 0x80;
dev->hdr_type = hdr_type & 0x7f;
if (pci_scan_device(bus, dev, devfn))
dev = pci_scan_device(temp);
if (!dev)
continue;
if (!func) {
is_multi = hdr_type & 0x80;
first_dev = dev;
}
DBG("PCI: %02x:%02x [%04x/%04x] %06x %02x\n", bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type);
......@@ -688,37 +678,41 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
* Put it into the global PCI device chain. It's used to
* find devices once everything is set up.
*/
if (!pci_reverse) {
*pci_last_dev_p = dev;
pci_last_dev_p = &dev->next;
} else {
dev->next = pci_devices;
pci_devices = dev;
}
*pci_last_dev_p = dev;
pci_last_dev_p = &dev->next;
/*
* Now insert it into the list of devices held
* by the parent bus.
*/
*bus_last = dev;
bus_last = &dev->sibling;
*bus->last_dev_p = dev;
bus->last_dev_p = &dev->sibling;
/* Fix up broken headers */
pci_fixup_device(PCI_FIXUP_HEADER, dev);
}
return first_dev;
}
#if 0
/*
* Setting of latency timer in case it was less than 32 was
* a great idea, but it confused several broken devices. Grrr.
*/
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp);
if (tmp < 32)
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
#endif
static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
{
unsigned int devfn, max;
struct pci_dev *dev, dev0;
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
DBG("pci_do_scan_bus for bus %d\n", bus->number);
bus->last_dev_p = &bus->devices;
max = bus->secondary;
/* Create a device template */
memset(&dev0, 0, sizeof(dev0));
dev0.bus = bus;
dev0.sysdata = bus->sysdata;
/* Go find them, Rover! */
for (devfn = 0; devfn < 0x100; devfn += 8) {
dev0.devfn = devfn;
pci_scan_slot(&dev0);
}
kfree(dev);
/*
* After performing arch-dependent fixup of the bus, look behind
......@@ -759,7 +753,7 @@ static int __init pci_bus_exists(struct pci_bus *b, int nr)
return 0;
}
struct pci_bus * __init pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
struct pci_bus * __init pci_alloc_primary_bus(int bus)
{
struct pci_bus *b, **r;
......@@ -779,11 +773,19 @@ struct pci_bus * __init pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata
*r = b;
b->number = b->secondary = bus;
b->sysdata = sysdata;
b->ops = ops;
b->resource[0] = &ioport_resource;
b->resource[1] = &iomem_resource;
b->subordinate = pci_do_scan_bus(b);
return b;
}
struct pci_bus * __init pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
{
struct pci_bus *b = pci_alloc_primary_bus(bus);
if (b) {
b->sysdata = sysdata;
b->ops = ops;
b->subordinate = pci_do_scan_bus(b);
}
return b;
}
......@@ -804,9 +806,8 @@ static int __init pci_setup(char *str)
if (k)
*k++ = 0;
if (*str && (str = pcibios_setup(str)) && *str) {
if (!strcmp(str, "reverse"))
pci_reverse = 1;
else printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
/* PCI layer options should be handled here */
printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
}
str = k;
}
......
......@@ -25,6 +25,8 @@ EXPORT_SYMBOL(pci_find_device);
EXPORT_SYMBOL(pci_find_slot);
EXPORT_SYMBOL(pci_set_master);
EXPORT_SYMBOL(pci_simple_probe);
EXPORT_SYMBOL(pci_set_power_state);
EXPORT_SYMBOL(pci_assign_resource);
#ifdef CONFIG_PROC_FS
EXPORT_SYMBOL(pci_proc_attach_device);
EXPORT_SYMBOL(pci_proc_detach_device);
......
......@@ -283,20 +283,21 @@ int cb_alloc(socket_info_t *s)
u_char i, hdr, fn, bus = s->cap.cardbus;
cb_config_t *c;
memset(&tmp, 0, sizeof(tmp));
tmp.bus = s->cap.cb_bus; tmp.devfn = 0;
tmp.next = pci_devices; pci_devices = &tmp;
pci_readw(bus, 0, PCI_VENDOR_ID, &vend);
pci_readw(bus, 0, PCI_DEVICE_ID, &dev);
pci_read_config_word(&tmp, PCI_VENDOR_ID, &vend);
pci_read_config_word(&tmp, PCI_DEVICE_ID, &dev);
printk(KERN_INFO "cs: cb_alloc(bus %d): vendor 0x%04x, "
"device 0x%04x\n", bus, vend, dev);
pci_readb(bus, 0, PCI_HEADER_TYPE, &hdr);
pci_read_config_byte(&tmp, PCI_HEADER_TYPE, &hdr);
if (hdr & 0x80) {
/* Count functions */
for (fn = 0; fn < 8; fn++) {
tmp.devfn = fn;
pci_readw(bus, fn, PCI_VENDOR_ID, &v);
pci_read_config_word(&tmp, PCI_VENDOR_ID, &v);
if (v != vend) break;
}
} else fn = 1;
......@@ -307,7 +308,6 @@ int cb_alloc(socket_info_t *s)
memset(c, 0, fn * sizeof(struct cb_config_t));
s->cb_config = c;
pci_devices = tmp.next;
for (i = 0; i < fn; i++) {
c[i].dev.bus = s->cap.cb_bus;
c[i].dev.devfn = i;
......@@ -317,7 +317,7 @@ int cb_alloc(socket_info_t *s)
}
s->cap.cb_bus->devices = &c[0].dev;
/* Link into PCI device chain */
c[s->functions-1].dev.next = pci_devices;
c[fn-1].dev.next = pci_devices;
pci_devices = &c[0].dev;
for (i = 0; i < fn; i++) {
c[i].dev.vendor = vend;
......@@ -338,17 +338,17 @@ void cb_free(socket_info_t *s)
cb_config_t *c = s->cb_config;
if (c) {
struct pci_dev **p, *q;
struct pci_dev **p;
/* Unlink from PCI device chain */
for (p = &pci_devices; *p; p = &((*p)->next))
if (*p == &c[0].dev) break;
for (q = *p; q; q = q->next) {
if (q->bus != (*p)->bus) break;
for (p = &pci_devices; *p; p = &((*p)->next)) {
struct pci_dev * dev = *p;
if (dev->bus != s->cap.cb_bus)
continue;
*p = dev->next;
#ifdef CONFIG_PROC_FS
pci_proc_detach_device(q);
pci_proc_detach_device(dev);
#endif
}
if (*p) *p = q;
s->cap.cb_bus->devices = NULL;
kfree(s->cb_config);
s->cb_config = NULL;
......
This diff is collapsed.
......@@ -437,6 +437,8 @@ struct Scsi_Device_Template
struct module * module; /* Used for loadable modules */
unsigned char scsi_type;
unsigned char major;
unsigned char min_major; /* Minimum major in range. */
unsigned char max_major; /* Maximum major in range. */
unsigned char nr_dev; /* Number currently attached */
unsigned char dev_noticed; /* Number of devices detected. */
unsigned char dev_max; /* Current size of arrays */
......@@ -447,7 +449,8 @@ struct Scsi_Device_Template
void (*finish)(void); /* Perform initialization after attachment */
int (*attach)(Scsi_Device *); /* Attach devices to arrays */
void (*detach)(Scsi_Device *);
int (*init_command)(Scsi_Cmnd *); /* Used by new queueing code. */
int (*init_command)(Scsi_Cmnd *); /* Used by new queueing code.
Selects command for blkdevs */
};
extern struct Scsi_Device_Template sd_template;
......
......@@ -1470,9 +1470,6 @@ void scsi_do_cmd(Scsi_Cmnd * SCpnt, const void *cmnd,
*/
host->host_busy++;
device->device_busy++;
/*
* Our own function scsi_done (which marks the host as not busy, disables
* the timeout counter, etc) will be called by us or by the
......@@ -1575,6 +1572,9 @@ void scsi_done(Scsi_Cmnd * SCpnt)
* Since serial_number is now 0, the error handler cound detect this
* situation and avoid to call the the low level driver abort routine.
* (DB)
*
* FIXME(eric) - I believe that this test is now redundant, due to
* the test of the return status of del_timer().
*/
if (SCpnt->state == SCSI_STATE_TIMEOUT) {
SCSI_LOG_MLCOMPLETE(1, printk("Ignoring completion of %p due to timeout status", SCpnt));
......
......@@ -1778,6 +1778,17 @@ STATIC int scsi_unjam_host(struct Scsi_Host *host)
for (SCpnt = SCdone; SCpnt != NULL; SCpnt = SCdone) {
SCdone = SCpnt->bh_next;
SCpnt->bh_next = NULL;
/*
* Oh, this is a vile hack. scsi_done() expects a timer
* to be running on the command. If there isn't, it assumes
* that the command has actually timed out, and a timer
* handler is running. That may well be how we got into
* this fix, but right now things are stable. We add
* a timer back again so that we can report completion.
* scsi_done() will immediately remove said timer from
* the command, and then process it.
*/
scsi_add_timer(SCpnt, 100, scsi_eh_times_out);
scsi_done(SCpnt);
}
......@@ -1809,7 +1820,14 @@ void scsi_error_handler(void *data)
int rtn;
DECLARE_MUTEX_LOCKED(sem);
/*
* We only listen to signals if the HA was loaded as a module.
* If the HA was compiled into the kernel, then we don't listen
* to any signals.
*/
if( host->loaded_as_module ) {
siginitsetinv(&current->blocked, SHUTDOWN_SIGS);
}
lock_kernel();
......@@ -1844,10 +1862,14 @@ void scsi_error_handler(void *data)
* trying to unload a module.
*/
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler sleeping\n"));
if( host->loaded_as_module ) {
down_interruptible(&sem);
if (signal_pending(current))
break;
} else {
down(&sem);
}
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler waking up\n"));
......
......@@ -607,6 +607,22 @@ struct Scsi_Device_Template *scsi_get_request_dev(struct request *req)
if (spnt->blk && spnt->major == major) {
return spnt;
}
/*
* I am still not entirely satisfied with this solution,
* but it is good enough for now. Disks have a number of
* major numbers associated with them, the primary
* 8, which we test above, and a secondary range of 7
* different consecutive major numbers. If this ever
* becomes insufficient, then we could add another function
* to the structure, and generalize this completely.
*/
if( spnt->min_major != 0
&& spnt->max_major != 0
&& major >= spnt->min_major
&& major <= spnt->max_major )
{
return spnt;
}
}
return NULL;
}
......@@ -742,10 +758,15 @@ void scsi_request_fn(request_queue_t * q)
if (!SCpnt) {
break;
}
SHpnt->host_busy++;
SDpnt->device_busy++;
}
/*
* Now bump the usage count for both the host and the
* device.
*/
SHpnt->host_busy++;
SDpnt->device_busy++;
/*
* FIXME(eric)
* I am not sure where the best place to do this is. We need
......
......@@ -290,6 +290,30 @@ __inline static int __scsi_merge_fn(request_queue_t * q,
count = bh->b_size >> 9;
sector = bh->b_rsector;
#if CONFIG_HIGHMEM
/*
* This is a temporary hack for the time being.
* In some cases, the ll_rw_blk layer is creating
* bounce buffers for us - this implies that we don't
* need to down here, but queue management becomes quite
* difficult otherwise. When the ll_rw_blk layer gets
* cleaned up to handle bounce buffers better, then
* this hack can be cleaned up.
*/
if( sector == -1 )
{
struct buffer_head * bh_new;
bh_new = (struct buffer_head *) bh->b_dev_id;
if( bh_new != NULL )
{
sector = bh_new->b_rsector;
}
if( sector == -1 )
{
panic("Unable to merge ambiguous block request");
}
}
#endif
/*
* We come in here in one of two cases. The first is that we
......@@ -765,7 +789,8 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
if( scsi_dma_free_sectors > 30 ) {
for (this_count = 0, bh = SCpnt->request.bh;
bh; bh = bh->b_reqnext) {
if( scsi_dma_free_sectors < 30 || this_count == sectors )
if( scsi_dma_free_sectors - this_count < 30
|| this_count == sectors )
{
break;
}
......@@ -831,24 +856,11 @@ static int _FUNCTION(Scsi_Cmnd * SCpnt) \
* We always force "_VALID" to 1. Eventually clean this up
* and get rid of the extra argument.
*/
#if 0
/* Old definitions */
INITIO(scsi_init_io_, 0, 0, 0)
INITIO(scsi_init_io_d, 0, 0, 1)
INITIO(scsi_init_io_c, 0, 1, 0)
INITIO(scsi_init_io_dc, 0, 1, 1)
/* Newer redundant definitions. */
INITIO(scsi_init_io_, 1, 0, 0)
INITIO(scsi_init_io_d, 1, 0, 1)
INITIO(scsi_init_io_c, 1, 1, 0)
INITIO(scsi_init_io_dc, 1, 1, 1)
#endif
INITIO(scsi_init_io_v, 1, 0, 0)
INITIO(scsi_init_io_vd, 1, 0, 1)
INITIO(scsi_init_io_vc, 1, 1, 0)
INITIO(scsi_init_io_vdc, 1, 1, 1)
/*
* Function: initialize_merge_fn()
*
......@@ -881,21 +893,12 @@ void initialize_merge_fn(Scsi_Device * SDpnt)
* If this host has an unlimited tablesize, then don't bother with a
* merge manager. The whole point of the operation is to make sure
* that requests don't grow too large, and this host isn't picky.
*/
if (SHpnt->sg_tablesize == SG_ALL) {
if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) {
SDpnt->scsi_init_io_fn = scsi_init_io_v;
} else if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma != 0) {
SDpnt->scsi_init_io_fn = scsi_init_io_vd;
} else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) {
SDpnt->scsi_init_io_fn = scsi_init_io_vc;
} else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma != 0) {
SDpnt->scsi_init_io_fn = scsi_init_io_vdc;
}
return;
}
/*
* Now pick out the correct function.
*
* Note that ll_rw_blk.c is effectively maintaining a segment
* count which is only valid if clustering is used, and it obviously
* doesn't handle the DMA case. In the end, it
* is simply easier to do it ourselves with our own functions
* rather than rely upon the default behavior of ll_rw_blk.
*/
if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) {
q->merge_fn = scsi_merge_fn_;
......
......@@ -202,6 +202,11 @@ struct Scsi_Device_Template sd_template = {
tag:"sd",
scsi_type:TYPE_DISK,
major:SCSI_DISK0_MAJOR,
/*
* Secondary range of majors that this driver handles.
*/
min_major:SCSI_DISK1_MAJOR,
max_major:SCSI_DISK7_MAJOR,
blk:1,
detect:sd_detect,
init:sd_init,
......@@ -229,7 +234,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
Scsi_Disk *dpnt;
char nbuff[6];
devm = MINOR(SCpnt->request.rq_dev);
devm = SD_PARTITION(SCpnt->request.rq_dev);
dev = DEVICE_NR(SCpnt->request.rq_dev);
block = SCpnt->request.sector;
......@@ -561,7 +566,7 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
default:
break;
}
error_sector -= sd[MINOR(SCpnt->request.rq_dev)].start_sect;
error_sector -= sd[SD_PARTITION(SCpnt->request.rq_dev)].start_sect;
error_sector &= ~(block_sectors - 1);
good_sectors = error_sector - SCpnt->request.sector;
if (good_sectors < 0 || good_sectors >= this_count)
......
......@@ -101,10 +101,17 @@ static int sg_detect(Scsi_Device *);
static void sg_detach(Scsi_Device *);
struct Scsi_Device_Template sg_template = {NULL, NULL, "sg", NULL, 0xff,
SCSI_GENERIC_MAJOR, 0, 0, 0, 0,
sg_detect, sg_init,
sg_finish, sg_attach, sg_detach};
struct Scsi_Device_Template sg_template =
{
tag:"sg",
scsi_type:0xff,
major:SCSI_GENERIC_MAJOR,
detect:sg_detect,
init:sg_init,
finish:sg_finish,
attach:sg_attach,
detach:sg_detach
};
typedef struct sg_scatter_hold /* holding area for scsi scatter gather info */
......
......@@ -147,10 +147,16 @@ static int st_detect(Scsi_Device *);
static void st_detach(Scsi_Device *);
struct Scsi_Device_Template st_template =
{NULL, "tape", "st", NULL, TYPE_TAPE,
SCSI_TAPE_MAJOR, 0, 0, 0, 0,
st_detect, st_init,
NULL, st_attach, st_detach};
{
name:"tape",
tag:"st",
scsi_type:TYPE_TAPE,
major:SCSI_TAPE_MAJOR,
detect:st_detect,
init:st_init,
attach:st_attach,
detach:st_detach
};
static int st_compression(Scsi_Tape *, int);
......
......@@ -360,6 +360,7 @@ struct pci_bus {
struct pci_dev *self; /* bridge device as seen by parent */
struct pci_dev *devices; /* devices behind this bridge */
struct pci_dev **last_dev_p; /* where should next device be linked to */
struct resource *resource[4]; /* address space routed to this bus */
void *sysdata; /* hook for sys-specific extension */
......@@ -449,6 +450,8 @@ int pcibios_find_device (unsigned short vendor, unsigned short dev_id,
void pci_init(void);
struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
struct pci_bus *pci_alloc_primary_bus(int bus);
struct pci_dev *pci_scan_slot(struct pci_dev *temp);
int pci_proc_attach_device(struct pci_dev *dev);
int pci_proc_detach_device(struct pci_dev *dev);
void pci_name_device(struct pci_dev *dev);
......
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