Commit 93ef77fa authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.15pre2

parent f91c3404
...@@ -141,6 +141,21 @@ pci_set_master(struct pci_dev *dev) ...@@ -141,6 +141,21 @@ pci_set_master(struct pci_dev *dev)
} }
} }
/*
* Translate the low bits of the PCI base
* to the resource type
*/
static inline unsigned int pci_resource_flags(unsigned int flags)
{
if (flags & PCI_BASE_ADDRESS_SPACE_IO)
return IORESOURCE_IO | flags;
if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH)
return IORESOURCE_MEM | IORESOURCE_PREFETCH;
return IORESOURCE_MEM;
}
void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany) void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany)
{ {
unsigned int reg; unsigned int reg;
...@@ -168,16 +183,16 @@ void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany) ...@@ -168,16 +183,16 @@ void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany)
continue; continue;
res->start = l & mask; res->start = l & mask;
res->flags = l & ~mask; l &= ~mask;
res->flags = l | pci_resource_flags(l);
size = 1; size = 1;
do { do {
size <<= 1; size <<= 1;
} while (!(size & newval)); } while (!(size & newval));
/* 64-bit memory? */ /* 64-bit decode? */
if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) if ((l & (PCI_BASE_ADDRESS_MEM_TYPE_MASK | PCI_BASE_ADDRESS_SPACE)) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
== (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
unsigned int high; unsigned int high;
reg++; reg++;
pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + (reg << 2), &high); pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + (reg << 2), &high);
......
...@@ -1199,6 +1199,30 @@ struct pci_dev *isapnp_find_dev(struct pci_bus *card, ...@@ -1199,6 +1199,30 @@ struct pci_dev *isapnp_find_dev(struct pci_bus *card,
return NULL; return NULL;
} }
/*
* FIXME! We should probably save away more than just the type
* in the DMA resource fields..
*/
static unsigned int isapnp_dma_resource_flags(struct isapnp_dma *dma)
{
return dma->type | IORESOURCE_DMA | IORESOURCE_AUTO;
}
static unsigned int isapnp_mem_resource_flags(struct isapnp_mem *mem)
{
return mem->type | IORESOURCE_MEM | IORESOURCE_AUTO;
}
static unsigned int isapnp_irq_resource_flags(struct isapnp_irq *irq)
{
return irq->flags | IORESOURCE_IRQ | IORESOURCE_AUTO;
}
static unsigned int isapnp_port_resource_flags(struct isapnp_port *port)
{
return port->flags | IORESOURCE_IO | IORESOURCE_AUTO;
}
static int isapnp_config_prepare(struct pci_dev *dev) static int isapnp_config_prepare(struct pci_dev *dev)
{ {
struct isapnp_resources *res, *resa; struct isapnp_resources *res, *resa;
...@@ -1216,47 +1240,41 @@ static int isapnp_config_prepare(struct pci_dev *dev) ...@@ -1216,47 +1240,41 @@ static int isapnp_config_prepare(struct pci_dev *dev)
return -EINVAL; return -EINVAL;
if (dev->active || dev->ro) if (dev->active || dev->ro)
return -EBUSY; return -EBUSY;
dev->irq = dev->irq2 = DEVICE_IRQ_NOTSET; for (idx = 0; idx < DEVICE_COUNT_IRQ; idx++) {
dev->irq_flags = dev->irq2_flags = 0; dev->irq_resource[idx].name = NULL;
dev->irq_resource[idx].start = 0;
dev->irq_resource[idx].end = 0;
dev->irq_resource[idx].flags = 0;
}
for (idx = 0; idx < DEVICE_COUNT_DMA; idx++) { for (idx = 0; idx < DEVICE_COUNT_DMA; idx++) {
dev->dma[idx] = DEVICE_DMA_NOTSET; dev->dma_resource[idx].name = NULL;
dev->dma_type[idx] = DEVICE_DMA_TYPE_8AND16BIT; dev->dma_resource[idx].start = 0;
dev->dma_flags[idx] = 0; dev->dma_resource[idx].end = 0;
dev->dma_speed[idx] = DEVICE_DMA_SPEED_COMPATIBLE; dev->dma_resource[idx].flags = 0;
} }
for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) { for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) {
dev->resource[idx].name = NULL; dev->resource[idx].name = NULL;
dev->resource[idx].start = DEVICE_IO_NOTSET; dev->resource[idx].start = 0;
dev->resource[idx].end = 0; dev->resource[idx].end = 0;
dev->resource[idx].fixed = 0; dev->resource[idx].flags = 0;
dev->resource[idx].bits = 12;
dev->resource[idx].hw_flags = 0;
dev->resource[idx].type = DEVICE_IO_TYPE_8AND16BIT;
} }
port_count = irq_count = dma_count = mem_count = 0; port_count = irq_count = dma_count = mem_count = 0;
for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) { for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
port_count1 = irq_count1 = dma_count1 = mem_count1 = 0; port_count1 = irq_count1 = dma_count1 = mem_count1 = 0;
for (resa = res; resa; resa = resa->alt) { for (resa = res; resa; resa = resa->alt) {
for (port = resa->port, idx = 0; port; port = port->next, idx++) { for (port = resa->port, idx = 0; port; port = port->next, idx++) {
if (dev->resource[port_count + idx].start == DEVICE_IO_NOTSET) { if (dev->resource[port_count + idx].flags == 0) {
dev->resource[port_count + idx].start = DEVICE_IO_AUTO; dev->resource[port_count + idx].flags = isapnp_port_resource_flags(port);
dev->resource[port_count + idx].end = port->size; dev->resource[port_count + idx].end = port->size;
dev->resource[port_count + idx].bits = port->flags & ISAPNP_PORT_FLAG_16BITADDR ? 16 : 12;
dev->resource[port_count + idx].fixed = port->flags & ISAPNP_PORT_FLAG_FIXED ? 1 : 0;
} }
} }
if (port_count1 < idx) if (port_count1 < idx)
port_count1 = idx; port_count1 = idx;
for (irq = resa->irq, idx = 0; irq; irq = irq->next, idx++) { for (irq = resa->irq, idx = 0; irq; irq = irq->next, idx++) {
if (irq_count + idx == 0) { int count = irq_count + idx;
if (dev->irq == DEVICE_IRQ_NOTSET) { if (count < DEVICE_COUNT_IRQ) {
dev->irq = DEVICE_IRQ_AUTO; if (dev->irq_resource[count].flags == 0) {
dev->irq_flags = irq->flags; dev->irq_resource[count].flags = isapnp_irq_resource_flags(irq);
}
} else if (irq_count + idx == 1) {
if (dev->irq2 == DEVICE_IRQ_NOTSET) {
dev->irq2 = DEVICE_IRQ_AUTO;
dev->irq2_flags = irq->flags;
} }
} }
...@@ -1264,22 +1282,14 @@ static int isapnp_config_prepare(struct pci_dev *dev) ...@@ -1264,22 +1282,14 @@ static int isapnp_config_prepare(struct pci_dev *dev)
if (irq_count1 < idx) if (irq_count1 < idx)
irq_count1 = idx; irq_count1 = idx;
for (dma = resa->dma, idx = 0; dma; dma = dma->next, idx++) for (dma = resa->dma, idx = 0; dma; dma = dma->next, idx++)
if (dev->dma[idx] == DEVICE_DMA_NOTSET) { if (dev->dma_resource[idx].flags == 0) {
dev->dma[idx] = DEVICE_DMA_AUTO; dev->dma_resource[idx].flags = isapnp_dma_resource_flags(dma);
dev->dma_type[idx] = dma->type;
dev->dma_flags[idx] = dma->flags;
dev->dma_speed[idx] = dma->speed;
} }
if (dma_count1 < idx) if (dma_count1 < idx)
dma_count1 = idx; dma_count1 = idx;
for (mem = resa->mem, idx = 0; mem; mem = mem->next, idx++) for (mem = resa->mem, idx = 0; mem; mem = mem->next, idx++)
if (dev->resource[mem_count + idx + 8].start == DEVICE_IO_AUTO) { if (dev->resource[mem_count + idx + 8].flags == 0) {
dev->resource[mem_count + idx].start = DEVICE_IO_AUTO; dev->resource[mem_count + idx].flags = isapnp_mem_resource_flags(mem);
dev->resource[mem_count + idx].end = mem->size;
dev->resource[mem_count + idx].bits = 24;
dev->resource[mem_count + idx].fixed = 0;
dev->resource[mem_count + idx].hw_flags = mem->flags;
dev->resource[mem_count + idx].type = mem->type;
} }
if (mem_count1 < idx) if (mem_count1 < idx)
mem_count1 = idx; mem_count1 = idx;
...@@ -1315,7 +1325,7 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg, ...@@ -1315,7 +1325,7 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg,
return -EINVAL; return -EINVAL;
/* process port settings */ /* process port settings */
for (tmp = 0; tmp < 8; tmp++) { for (tmp = 0; tmp < 8; tmp++) {
if (cfg->request->resource[tmp].start != DEVICE_IO_AUTO) if (!(cfg->request->resource[tmp].flags & IORESOURCE_AUTO))
continue; /* don't touch */ continue; /* don't touch */
port = cfg->port[tmp]; port = cfg->port[tmp];
if (!port) { if (!port) {
...@@ -1331,21 +1341,17 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg, ...@@ -1331,21 +1341,17 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg,
for (tmp1 = tmp; tmp1 > 0 && port; tmp1--) for (tmp1 = tmp; tmp1 > 0 && port; tmp1--)
port = port->next; port = port->next;
cfg->port[tmp] = port; cfg->port[tmp] = port;
cfg->result.resource[tmp].start = DEVICE_IO_AUTO;
if (!port) if (!port)
return -ENOENT; return -ENOENT;
cfg->result.resource[tmp].flags = isapnp_port_resource_flags(port);
} }
} }
} }
/* process irq settings */ /* process irq settings */
for (tmp = 0; tmp < 2; tmp++) { for (tmp = 0; tmp < 2; tmp++) {
if (tmp == 0) { if (!(cfg->request->irq_resource[tmp].flags & IORESOURCE_AUTO))
if (cfg->request->irq != DEVICE_IRQ_AUTO) continue; /* don't touch */
continue; /* don't touch */
} else {
if (cfg->request->irq2 != DEVICE_IRQ_AUTO)
continue; /* don't touch */
}
irq = cfg->irq[tmp]; irq = cfg->irq[tmp];
if (!irq) { if (!irq) {
cfg->irq[tmp] = irq = isapnp_find_irq(cfg->request, tmp); cfg->irq[tmp] = irq = isapnp_find_irq(cfg->request, tmp);
...@@ -1360,20 +1366,17 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg, ...@@ -1360,20 +1366,17 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg,
for (tmp1 = tmp; tmp1 > 0 && irq; tmp1--) for (tmp1 = tmp; tmp1 > 0 && irq; tmp1--)
irq = irq->next; irq = irq->next;
cfg->irq[tmp] = irq; cfg->irq[tmp] = irq;
if (tmp == 0) {
cfg->result.irq = DEVICE_IRQ_AUTO;
} else {
cfg->result.irq2 = DEVICE_IRQ_AUTO;
}
if (!irq) if (!irq)
return -ENOENT; return -ENOENT;
cfg->result.irq_resource[tmp].flags = isapnp_irq_resource_flags(irq);
} }
} }
} }
/* process dma settings */ /* process dma settings */
for (tmp = 0; tmp < 2; tmp++) { for (tmp = 0; tmp < 2; tmp++) {
if (cfg->request->dma[tmp] != DEVICE_DMA_AUTO) if (!(cfg->request->dma_resource[tmp].flags & IORESOURCE_AUTO))
continue; /* don't touch */ continue; /* don't touch */
dma = cfg->dma[tmp]; dma = cfg->dma[tmp];
if (!dma) { if (!dma) {
cfg->dma[tmp] = dma = isapnp_find_dma(cfg->request, tmp); cfg->dma[tmp] = dma = isapnp_find_dma(cfg->request, tmp);
...@@ -1388,15 +1391,15 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg, ...@@ -1388,15 +1391,15 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg,
for (tmp1 = tmp; tmp1 > 0 && dma; tmp1--) for (tmp1 = tmp; tmp1 > 0 && dma; tmp1--)
dma = dma->next; dma = dma->next;
cfg->dma[tmp] = dma; cfg->dma[tmp] = dma;
cfg->result.dma[tmp] = DEVICE_DMA_AUTO;
if (!dma) if (!dma)
return -ENOENT; return -ENOENT;
cfg->result.dma_resource[tmp].flags = isapnp_dma_resource_flags(dma);
} }
} }
} }
/* process memory settings */ /* process memory settings */
for (tmp = 0; tmp < 4; tmp++) { for (tmp = 0; tmp < 4; tmp++) {
if (cfg->request->resource[tmp + 8].start != DEVICE_IO_AUTO) if (!(cfg->request->resource[tmp + 8].flags & IORESOURCE_AUTO))
continue; /* don't touch */ continue; /* don't touch */
mem = cfg->mem[tmp]; mem = cfg->mem[tmp];
if (!mem) { if (!mem) {
...@@ -1412,9 +1415,9 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg, ...@@ -1412,9 +1415,9 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg,
for (tmp1 = tmp; tmp1 > 0 && mem; tmp1--) for (tmp1 = tmp; tmp1 > 0 && mem; tmp1--)
mem = mem->next; mem = mem->next;
cfg->mem[tmp] = mem; cfg->mem[tmp] = mem;
cfg->result.resource[tmp + 8].start = DEVICE_IO_AUTO;
if (!mem) if (!mem)
return -ENOENT; return -ENOENT;
cfg->result.resource[tmp + 8].flags = isapnp_mem_resource_flags(mem);
} }
} }
} }
...@@ -1440,7 +1443,7 @@ static int isapnp_check_port(struct isapnp_cfgtmp *cfg, int port, int size, int ...@@ -1440,7 +1443,7 @@ static int isapnp_check_port(struct isapnp_cfgtmp *cfg, int port, int size, int
for (dev = isapnp_devices; dev; dev = dev->next) { for (dev = isapnp_devices; dev; dev = dev->next) {
if (dev->active) { if (dev->active) {
for (tmp = 0; tmp < 8; tmp++) { for (tmp = 0; tmp < 8; tmp++) {
if (dev->resource[tmp].start != DEVICE_IO_NOTSET) { if (dev->resource[tmp].flags) {
rport = dev->resource[tmp].start; rport = dev->resource[tmp].start;
rsize = (dev->resource[tmp].end - rport) + 1; rsize = (dev->resource[tmp].end - rport) + 1;
if (port >= rport && port < rport + rsize) if (port >= rport && port < rport + rsize)
...@@ -1452,18 +1455,20 @@ static int isapnp_check_port(struct isapnp_cfgtmp *cfg, int port, int size, int ...@@ -1452,18 +1455,20 @@ static int isapnp_check_port(struct isapnp_cfgtmp *cfg, int port, int size, int
} }
} }
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
unsigned int flags;
if (i == idx) if (i == idx)
continue; continue;
tmp = cfg->request->resource[i].start; flags = cfg->request->resource[i].flags;
if (tmp == DEVICE_IO_NOTSET) if (!flags)
continue; continue;
if (tmp == DEVICE_IO_AUTO) { /* auto */ tmp = cfg->request->resource[i].start;
if (flags & IORESOURCE_AUTO) { /* auto */
xport = cfg->port[i]; xport = cfg->port[i];
if (!xport) if (!xport)
return 1; return 1;
tmp = cfg->result.resource[i].start; if (cfg->result.resource[i].flags & IORESOURCE_AUTO)
if (tmp == DEVICE_IO_AUTO)
continue; continue;
tmp = cfg->result.resource[i].start;
if (tmp + xport->size >= port && tmp <= port + xport->size) if (tmp + xport->size >= port && tmp <= port + xport->size)
return 1; return 1;
continue; continue;
...@@ -1487,14 +1492,14 @@ static int isapnp_valid_port(struct isapnp_cfgtmp *cfg, int idx) ...@@ -1487,14 +1492,14 @@ static int isapnp_valid_port(struct isapnp_cfgtmp *cfg, int idx)
if (!cfg || idx < 0 || idx > 7) if (!cfg || idx < 0 || idx > 7)
return -EINVAL; return -EINVAL;
if (cfg->result.resource[idx].start != DEVICE_IO_AUTO) /* don't touch */ if (!(cfg->result.resource[idx].flags & IORESOURCE_AUTO)) /* don't touch */
return 0; return 0;
__again: __again:
port = cfg->port[idx]; port = cfg->port[idx];
if (!port) if (!port)
return -EINVAL; return -EINVAL;
value = &cfg->result.resource[idx].start; value = &cfg->result.resource[idx].start;
if (*value == DEVICE_IO_AUTO) { if (cfg->result.resource[idx].flags & IORESOURCE_AUTO) {
if (!isapnp_check_port(cfg, *value = port->min, port->size, idx)) if (!isapnp_check_port(cfg, *value = port->min, port->size, idx))
return 0; return 0;
} }
...@@ -1529,24 +1534,23 @@ static int isapnp_check_interrupt(struct isapnp_cfgtmp *cfg, int irq, int idx) ...@@ -1529,24 +1534,23 @@ static int isapnp_check_interrupt(struct isapnp_cfgtmp *cfg, int irq, int idx)
} }
for (dev = isapnp_devices; dev; dev = dev->next) { for (dev = isapnp_devices; dev; dev = dev->next) {
if (dev->active) { if (dev->active) {
if (dev->irq == irq || dev->irq2 == irq) if (dev->irq_resource[0].start == irq ||
dev->irq_resource[1].start == irq)
return 1; return 1;
} }
} }
if (request_irq(irq, isapnp_test_handler, SA_INTERRUPT, "isapnp", NULL)) if (request_irq(irq, isapnp_test_handler, SA_INTERRUPT, "isapnp", NULL))
return 1; return 1;
free_irq(irq, NULL); free_irq(irq, NULL);
if (idx != 0) { for (i = 0; i < DEVICE_COUNT_IRQ; i++) {
if (cfg->result.irq != DEVICE_IRQ_AUTO && if (i == idx)
cfg->result.irq != DEVICE_IRQ_NOTSET) continue;
if (cfg->result.irq == irq) if (!cfg->result.irq_resource[i].flags)
return 1; continue;
} if (cfg->result.irq_resource[i].flags & IORESOURCE_AUTO)
if (idx != 1) { continue;
if (cfg->result.irq2 != DEVICE_IRQ_AUTO && if (cfg->result.irq_resource[i].start == irq)
cfg->result.irq2 != DEVICE_IRQ_NOTSET) return 1;
if (cfg->result.irq2 == irq)
return 1;
} }
return 0; return 0;
} }
...@@ -1558,28 +1562,19 @@ static int isapnp_valid_irq(struct isapnp_cfgtmp *cfg, int idx) ...@@ -1558,28 +1562,19 @@ static int isapnp_valid_irq(struct isapnp_cfgtmp *cfg, int idx)
5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
}; };
int err, i; int err, i;
unsigned int *value; unsigned long *value;
struct isapnp_irq *irq; struct isapnp_irq *irq;
if (!cfg || idx < 0 || idx > 1) if (!cfg || idx < 0 || idx > 1)
return -EINVAL; return -EINVAL;
if (idx == 0) { if (!(cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO))
if (cfg->result.irq != DEVICE_IRQ_AUTO) /* don't touch */ return 0;
return 0;
} else {
if (cfg->result.irq2 != DEVICE_IRQ_AUTO) /* don't touch */
return 0;
}
__again: __again:
irq = cfg->irq[idx]; irq = cfg->irq[idx];
if (!irq) if (!irq)
return -EINVAL; return -EINVAL;
if (idx == 0) { value = &cfg->result.irq_resource[idx].start;
value = &cfg->result.irq; if (cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO) {
} else {
value = &cfg->result.irq2;
}
if (*value == DEVICE_IRQ_AUTO) {
for (i = 0; i < 16 && !(irq->map & (1<<xtab[i])); i++); for (i = 0; i < 16 && !(irq->map & (1<<xtab[i])); i++);
if (i >= 16) if (i >= 16)
return -ENOENT; return -ENOENT;
...@@ -1616,7 +1611,7 @@ static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx) ...@@ -1616,7 +1611,7 @@ static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx)
} }
for (dev = isapnp_devices; dev; dev = dev->next) { for (dev = isapnp_devices; dev; dev = dev->next) {
if (dev->active) { if (dev->active) {
if (dev->dma[0] == dma || dev->dma[1] == dma) if (dev->dma_resource[0].start == dma || dev->dma_resource[1].start == dma)
return 1; return 1;
} }
} }
...@@ -1626,10 +1621,10 @@ static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx) ...@@ -1626,10 +1621,10 @@ static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx)
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (i == idx) if (i == idx)
continue; continue;
if (cfg->result.dma[i] == DEVICE_DMA_NOTSET || if (!cfg->result.dma_resource[i].flags ||
cfg->result.dma[i] == DEVICE_DMA_AUTO) (cfg->result.dma_resource[i].flags & IORESOURCE_AUTO))
continue; continue;
if (cfg->result.dma[i] == dma) if (cfg->result.dma_resource[i].start == dma)
return 1; return 1;
} }
return 0; return 0;
...@@ -1638,19 +1633,19 @@ static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx) ...@@ -1638,19 +1633,19 @@ static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx)
static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx) static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx)
{ {
int err, i; int err, i;
unsigned char *value; unsigned long *value;
struct isapnp_dma *dma; struct isapnp_dma *dma;
if (!cfg || idx < 0 || idx > 1) if (!cfg || idx < 0 || idx > 1)
return -EINVAL; return -EINVAL;
if (cfg->result.dma[idx] != DEVICE_DMA_AUTO) /* don't touch */ if (!(cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO)) /* don't touch */
return 0; return 0;
__again: __again:
dma = cfg->dma[idx]; dma = cfg->dma[idx];
if (!dma) if (!dma)
return -EINVAL; return -EINVAL;
value = &cfg->result.dma[idx]; value = &cfg->result.dma_resource[idx].start;
if (*value == DEVICE_DMA_AUTO) { if (cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO) {
for (i = 0; i < 8 && !(dma->map & (1<<i)); i++); for (i = 0; i < 8 && !(dma->map & (1<<i)); i++);
if (i >= 8) if (i >= 8)
return -ENOENT; return -ENOENT;
...@@ -1693,7 +1688,7 @@ static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsign ...@@ -1693,7 +1688,7 @@ static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsign
for (dev = isapnp_devices; dev; dev = dev->next) { for (dev = isapnp_devices; dev; dev = dev->next) {
if (dev->active) { if (dev->active) {
for (tmp = 0; tmp < 4; tmp++) { for (tmp = 0; tmp < 4; tmp++) {
if (dev->resource[tmp].start != DEVICE_IO_NOTSET) { if (dev->resource[tmp].flags) {
raddr = dev->resource[tmp + 8].start; raddr = dev->resource[tmp + 8].start;
rsize = (dev->resource[tmp + 8].end - raddr) + 1; rsize = (dev->resource[tmp + 8].end - raddr) + 1;
if (addr >= raddr && addr < raddr + rsize) if (addr >= raddr && addr < raddr + rsize)
...@@ -1705,17 +1700,17 @@ static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsign ...@@ -1705,17 +1700,17 @@ static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsign
} }
} }
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
unsigned int flags = cfg->request->resource[i + 8].flags;
if (i == idx) if (i == idx)
continue; continue;
tmp = cfg->request->resource[i + 8].start; if (!flags)
if (tmp == DEVICE_IO_NOTSET)
continue; continue;
if (tmp == DEVICE_IO_AUTO) { /* auto */ tmp = cfg->result.resource[i + 8].start;
if (flags & IORESOURCE_AUTO) { /* auto */
xmem = cfg->mem[i]; xmem = cfg->mem[i];
if (!xmem) if (!xmem)
return 1; return 1;
tmp = cfg->result.resource[i + 8].start; if (cfg->result.resource[i + 8].flags & IORESOURCE_AUTO)
if (tmp == DEVICE_IO_AUTO)
continue; continue;
if (tmp + xmem->size >= addr && tmp <= addr + xmem->size) if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)
return 1; return 1;
...@@ -1735,19 +1730,21 @@ static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsign ...@@ -1735,19 +1730,21 @@ static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsign
static int isapnp_valid_mem(struct isapnp_cfgtmp *cfg, int idx) static int isapnp_valid_mem(struct isapnp_cfgtmp *cfg, int idx)
{ {
int err; int err;
unsigned int flags;
unsigned long *value; unsigned long *value;
struct isapnp_mem *mem; struct isapnp_mem *mem;
if (!cfg || idx < 0 || idx > 3) if (!cfg || idx < 0 || idx > 3)
return -EINVAL; return -EINVAL;
if (cfg->result.resource[idx + 8].start != DEVICE_IO_AUTO) /* don't touch */ flags = cfg->result.resource[idx + 8].flags;
if (flags && (flags & IORESOURCE_AUTO)) /* don't touch */
return 0; return 0;
__again: __again:
mem = cfg->mem[idx]; mem = cfg->mem[idx];
if (!mem) if (!mem)
return -EINVAL; return -EINVAL;
value = &cfg->result.resource[idx].start; value = &cfg->result.resource[idx].start;
if (*value == DEVICE_IO_AUTO) { if (flags & IORESOURCE_AUTO) {
*value = mem->min; *value = mem->min;
if (!isapnp_check_mem(cfg, *value, mem->size, idx)) if (!isapnp_check_mem(cfg, *value, mem->size, idx))
return 0; return 0;
...@@ -1771,17 +1768,16 @@ static int isapnp_check_valid(struct isapnp_cfgtmp *cfg) ...@@ -1771,17 +1768,16 @@ static int isapnp_check_valid(struct isapnp_cfgtmp *cfg)
int tmp; int tmp;
for (tmp = 0; tmp < 8; tmp++) for (tmp = 0; tmp < 8; tmp++)
if (cfg->result.resource[tmp].start == DEVICE_IO_AUTO) if (cfg->result.resource[tmp].flags & IORESOURCE_AUTO)
return -EAGAIN; return -EAGAIN;
if (cfg->result.irq == DEVICE_IRQ_AUTO)
return -EAGAIN;
if (cfg->result.irq2 == DEVICE_IRQ_AUTO)
return -EAGAIN;
for (tmp = 0; tmp < 2; tmp++) for (tmp = 0; tmp < 2; tmp++)
if (cfg->result.dma[tmp] == DEVICE_DMA_AUTO) if (cfg->result.irq_resource[tmp].flags & IORESOURCE_AUTO)
return -EAGAIN;
for (tmp = 0; tmp < 2; tmp++)
if (cfg->result.dma_resource[tmp].flags & IORESOURCE_AUTO)
return -EAGAIN; return -EAGAIN;
for (tmp = 0; tmp < 4; tmp++) for (tmp = 0; tmp < 4; tmp++)
if (cfg->result.resource[tmp + 1].start == DEVICE_IO_AUTO) if (cfg->result.resource[tmp + 8].flags & IORESOURCE_AUTO)
return -EAGAIN; return -EAGAIN;
return 0; return 0;
} }
...@@ -1800,19 +1796,19 @@ static int isapnp_config_activate(struct pci_dev *dev) ...@@ -1800,19 +1796,19 @@ static int isapnp_config_activate(struct pci_dev *dev)
memcpy(&cfg.result, dev, sizeof(struct pci_dev)); memcpy(&cfg.result, dev, sizeof(struct pci_dev));
/* check if all values are set, otherwise try auto-configuration */ /* check if all values are set, otherwise try auto-configuration */
for (tmp = fauto = 0; !fauto && tmp < 8; tmp++) { for (tmp = fauto = 0; !fauto && tmp < 8; tmp++) {
if (dev->resource[tmp].start == DEVICE_IO_AUTO) if (dev->resource[tmp].flags & IORESOURCE_AUTO)
fauto++;
}
for (tmp = 0; !fauto && tmp < 2; tmp++) {
if (dev->irq_resource[tmp].flags & IORESOURCE_AUTO)
fauto++; fauto++;
} }
if (dev->irq == DEVICE_IRQ_AUTO)
fauto++;
if (dev->irq2 == DEVICE_IRQ_AUTO)
fauto++;
for (tmp = 0; !fauto && tmp < 2; tmp++) { for (tmp = 0; !fauto && tmp < 2; tmp++) {
if (dev->dma[tmp] == DEVICE_DMA_AUTO) if (dev->dma_resource[tmp].flags & IORESOURCE_AUTO)
fauto++; fauto++;
} }
for (tmp = 0; !fauto && tmp < 4; tmp++) { for (tmp = 0; !fauto && tmp < 4; tmp++) {
if (dev->resource[tmp + 8].start == DEVICE_IO_AUTO) if (dev->resource[tmp + 8].flags & IORESOURCE_AUTO)
fauto++; fauto++;
} }
if (!fauto) if (!fauto)
...@@ -1823,19 +1819,16 @@ static int isapnp_config_activate(struct pci_dev *dev) ...@@ -1823,19 +1819,16 @@ static int isapnp_config_activate(struct pci_dev *dev)
/* find first valid configuration */ /* find first valid configuration */
fauto = 0; fauto = 0;
do { do {
for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].start != DEVICE_IO_NOTSET; tmp++) for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].flags ; tmp++)
if ((err = isapnp_valid_port(&cfg, tmp))<0) if ((err = isapnp_valid_port(&cfg, tmp))<0)
return err; return err;
if (cfg.result.irq != DEVICE_IRQ_NOTSET) for (tmp = 0; tmp < 2 && cfg.result.irq_resource[tmp].flags ; tmp++)
if ((err = isapnp_valid_irq(&cfg, 0))<0) if ((err = isapnp_valid_irq(&cfg, 0))<0)
return err; return err;
if (cfg.result.irq2 != DEVICE_IRQ_NOTSET) for (tmp = 0; tmp < 2 && cfg.result.dma_resource[tmp].flags; tmp++)
if ((err = isapnp_valid_irq(&cfg, 1))<0)
return err;
for (tmp = 0; tmp < 2 && tmp < cfg.result.dma[tmp] != DEVICE_DMA_NOTSET; tmp++)
if ((err = isapnp_valid_dma(&cfg, tmp))<0) if ((err = isapnp_valid_dma(&cfg, tmp))<0)
return err; return err;
for (tmp = 0; tmp < 4 && tmp < cfg.result.resource[tmp + 8].start != DEVICE_IO_NOTSET; tmp++) for (tmp = 0; tmp < 4 && cfg.result.resource[tmp + 8].flags; tmp++)
if ((err = isapnp_valid_mem(&cfg, tmp))<0) if ((err = isapnp_valid_mem(&cfg, tmp))<0)
return err; return err;
} while (isapnp_check_valid(&cfg)<0 && fauto++ < 20); } while (isapnp_check_valid(&cfg)<0 && fauto++ < 20);
...@@ -1845,31 +1838,24 @@ static int isapnp_config_activate(struct pci_dev *dev) ...@@ -1845,31 +1838,24 @@ static int isapnp_config_activate(struct pci_dev *dev)
/* we have valid configuration, try configure hardware */ /* we have valid configuration, try configure hardware */
isapnp_cfg_begin(dev->bus->number, dev->devfn); isapnp_cfg_begin(dev->bus->number, dev->devfn);
dev->active = 1; dev->active = 1;
dev->irq = cfg.result.irq; dev->irq_resource[0] = cfg.result.irq_resource[0];
dev->irq2 = cfg.result.irq2; dev->irq_resource[1] = cfg.result.irq_resource[1];
dev->dma[0] = cfg.result.dma[0]; dev->dma_resource[0] = cfg.result.dma_resource[0];
dev->dma[1] = cfg.result.dma[1]; dev->dma_resource[1] = cfg.result.dma_resource[1];
for (tmp = 0; tmp < 12; tmp++) { for (tmp = 0; tmp < 12; tmp++) {
dev->resource[tmp].start = cfg.result.resource[tmp].start; dev->resource[tmp] = cfg.result.resource[tmp];
if (cfg.result.resource[tmp].start != DEVICE_IO_NOTSET &&
cfg.result.resource[tmp].end != DEVICE_IO_AUTO)
dev->resource[tmp].end += cfg.result.resource[tmp].start;
} }
for (tmp = 0; tmp < 8 && dev->resource[tmp].start != DEVICE_IO_NOTSET; tmp++) for (tmp = 0; tmp < 8 && dev->resource[tmp].flags; tmp++)
isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), dev->resource[tmp].start); isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), dev->resource[tmp].start);
if (dev->irq != DEVICE_IRQ_NOTSET) { for (tmp = 0; tmp < 2 && dev->irq_resource[tmp].flags; tmp++) {
if (dev->irq == 2) int irq = dev->irq_resource[tmp].start;
dev->irq = 9; if (irq == 2)
isapnp_write_byte(ISAPNP_CFG_IRQ+(0<<1), dev->irq); irq = 9;
} isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq);
if (dev->irq2 != DEVICE_IRQ_NOTSET) { }
if (dev->irq2 == 2) for (tmp = 0; tmp < 2 && dev->dma_resource[tmp].flags; tmp++)
dev->irq2 = 9; isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma_resource[tmp].start);
isapnp_write_byte(ISAPNP_CFG_IRQ+(1<<1), dev->irq2); for (tmp = 0; tmp < 4 && dev->resource[tmp+8].flags; tmp++)
}
for (tmp = 0; tmp < 2 && dev->dma[tmp] != DEVICE_DMA_NOTSET; tmp++)
isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma[tmp]);
for (tmp = 0; tmp < 4 && dev->resource[tmp].start != DEVICE_IO_NOTSET; tmp++)
isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (dev->resource[tmp + 8].start >> 8) & 0xffff); isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (dev->resource[tmp + 8].start >> 8) & 0xffff);
isapnp_activate(dev->devfn); isapnp_activate(dev->devfn);
isapnp_cfg_end(); isapnp_cfg_end();
...@@ -1882,7 +1868,7 @@ static int isapnp_config_deactivate(struct pci_dev *dev) ...@@ -1882,7 +1868,7 @@ static int isapnp_config_deactivate(struct pci_dev *dev)
return -EINVAL; return -EINVAL;
isapnp_cfg_begin(dev->bus->number, dev->devfn); isapnp_cfg_begin(dev->bus->number, dev->devfn);
isapnp_deactivate(dev->devfn); isapnp_deactivate(dev->devfn);
dev->activate = 0; dev->active = 0;
isapnp_cfg_end(); isapnp_cfg_end();
return 0; return 0;
} }
...@@ -1971,7 +1957,7 @@ static void isapnp_free_device(struct pci_dev *dev) ...@@ -1971,7 +1957,7 @@ static void isapnp_free_device(struct pci_dev *dev)
struct pci_dev *next; struct pci_dev *next;
while (dev) { while (dev) {
next = dev->next; next = dev->sibling;
isapnp_free_resources((struct isapnp_resources *)dev->sysdata, 0); isapnp_free_resources((struct isapnp_resources *)dev->sysdata, 0);
kfree(dev); kfree(dev);
dev = next; dev = next;
......
...@@ -380,21 +380,21 @@ static void isapnp_print_mem(isapnp_info_buffer_t *buffer, char *space, struct i ...@@ -380,21 +380,21 @@ static void isapnp_print_mem(isapnp_info_buffer_t *buffer, char *space, struct i
isapnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x", isapnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x",
space, mem->min, mem->max, mem->align, mem->size); space, mem->min, mem->max, mem->align, mem->size);
if (mem->flags & DEVICE_IO_FLAG_WRITEABLE) if (mem->flags & ISAPNP_FLAG_WRITEABLE)
isapnp_printf(buffer, ", writeable"); isapnp_printf(buffer, ", writeable");
if (mem->flags & DEVICE_IO_FLAG_CACHEABLE) if (mem->flags & ISAPNP_FLAG_CACHEABLE)
isapnp_printf(buffer, ", cacheable"); isapnp_printf(buffer, ", cacheable");
if (mem->flags & DEVICE_IO_FLAG_RANGELENGTH) if (mem->flags & ISAPNP_FLAG_RANGELENGTH)
isapnp_printf(buffer, ", range-length"); isapnp_printf(buffer, ", range-length");
if (mem->flags & DEVICE_IO_FLAG_SHADOWABLE) if (mem->flags & ISAPNP_FLAG_SHADOWABLE)
isapnp_printf(buffer, ", shadowable"); isapnp_printf(buffer, ", shadowable");
if (mem->flags & DEVICE_IO_FLAG_EXPANSIONROM) if (mem->flags & ISAPNP_FLAG_EXPANSIONROM)
isapnp_printf(buffer, ", expansion ROM"); isapnp_printf(buffer, ", expansion ROM");
switch (mem->type) { switch (mem->type) {
case DEVICE_IO_TYPE_8BIT: case ISAPNP_TYPE_8BIT:
s = "8-bit"; s = "8-bit";
break; break;
case DEVICE_IO_TYPE_8AND16BIT: case ISAPNP_TYPE_8AND16BIT:
s = "8-bit&16-bit"; s = "8-bit&16-bit";
break; break;
default: default:
...@@ -734,9 +734,9 @@ static int isapnp_set_port(char *line) ...@@ -734,9 +734,9 @@ static int isapnp_set_port(char *line)
return 1; return 1;
} }
isapnp_write_word(ISAPNP_CFG_PORT + (idx << 1), port); isapnp_write_word(ISAPNP_CFG_PORT + (idx << 1), port);
if (isapnp_info_device->resource[idx].start == DEVICE_IO_NOTSET) if (isapnp_info_device->resource[idx].start == ISAPNP_NOTSET)
return 0; return 0;
if (isapnp_info_device->resource[idx].start == DEVICE_IO_AUTO) { if (isapnp_info_device->resource[idx].start == ISAPNP_AUTO) {
isapnp_info_device->resource[idx].start = port; isapnp_info_device->resource[idx].start = port;
isapnp_info_device->resource[idx].end += port - 1; isapnp_info_device->resource[idx].end += port - 1;
} else { } else {
...@@ -746,6 +746,12 @@ static int isapnp_set_port(char *line) ...@@ -746,6 +746,12 @@ static int isapnp_set_port(char *line)
} }
return 0; return 0;
} }
static void isapnp_set_irqresource(struct resource *res, int irq)
{
res->start = res->end = irq;
res->flags = IORESOURCE_IRQ;
}
static int isapnp_set_irq(char *line) static int isapnp_set_irq(char *line)
{ {
...@@ -767,18 +773,16 @@ static int isapnp_set_irq(char *line) ...@@ -767,18 +773,16 @@ static int isapnp_set_irq(char *line)
return 1; return 1;
} }
isapnp_write_byte(ISAPNP_CFG_IRQ + (idx << 1), irq); isapnp_write_byte(ISAPNP_CFG_IRQ + (idx << 1), irq);
if (idx == 0) { isapnp_set_irqresource(isapnp_info_device->irq_resource + idx, irq);
if (isapnp_info_device->irq == DEVICE_IRQ_NOTSET)
return 0;
isapnp_info_device->irq = irq;
} else {
if (isapnp_info_device->irq2 == DEVICE_IRQ_NOTSET)
return 0;
isapnp_info_device->irq2 = irq;
}
return 0; return 0;
} }
static void isapnp_set_dmaresource(struct resource *res, int dma)
{
res->start = res->end = dma;
res->flags = IORESOURCE_DMA;
}
static int isapnp_set_dma(char *line) static int isapnp_set_dma(char *line)
{ {
int idx, dma; int idx, dma;
...@@ -797,9 +801,7 @@ static int isapnp_set_dma(char *line) ...@@ -797,9 +801,7 @@ static int isapnp_set_dma(char *line)
return 1; return 1;
} }
isapnp_write_byte(ISAPNP_CFG_DMA + idx, dma); isapnp_write_byte(ISAPNP_CFG_DMA + idx, dma);
if (isapnp_info_device->dma[idx] == DEVICE_DMA_NOTSET) isapnp_set_dmaresource(isapnp_info_device->dma_resource + idx, dma);
return 0;
isapnp_info_device->dma[idx] = dma;
return 0; return 0;
} }
...@@ -819,9 +821,9 @@ static int isapnp_set_mem(char *line) ...@@ -819,9 +821,9 @@ static int isapnp_set_mem(char *line)
} }
mem >>= 8; mem >>= 8;
isapnp_write_word(ISAPNP_CFG_MEM + (idx<<2), mem & 0xffff); isapnp_write_word(ISAPNP_CFG_MEM + (idx<<2), mem & 0xffff);
if (isapnp_info_device->resource[idx + 8].start == DEVICE_IO_NOTSET) if (isapnp_info_device->resource[idx + 8].start == ISAPNP_NOTSET)
return 0; return 0;
if (isapnp_info_device->resource[idx + 8].start == DEVICE_IO_AUTO) { if (isapnp_info_device->resource[idx + 8].start == ISAPNP_AUTO) {
isapnp_info_device->resource[idx + 8].start = mem & ~0x00ffff00; isapnp_info_device->resource[idx + 8].start = mem & ~0x00ffff00;
isapnp_info_device->resource[idx + 8].end += (mem & ~0x00ffff00) - 1; isapnp_info_device->resource[idx + 8].end += (mem & ~0x00ffff00) - 1;
} else { } else {
......
...@@ -1951,11 +1951,11 @@ static int encode_fix(struct fb_fix_screeninfo *fix, ...@@ -1951,11 +1951,11 @@ static int encode_fix(struct fb_fix_screeninfo *fix,
fix->mmio_len = 0x400; fix->mmio_len = 0x400;
fix->accel = FB_ACCEL_ATI_MACH64CT; fix->accel = FB_ACCEL_ATI_MACH64CT;
} else if (Gx == VT_CHIP_ID || Gx == VU_CHIP_ID || Gx == VV_CHIP_ID) { } else if (Gx == VT_CHIP_ID || Gx == VU_CHIP_ID || Gx == VV_CHIP_ID) {
fix->mmio_start = info->ati_regbase_phys-0x400); fix->mmio_start = info->ati_regbase_phys-0x400;
fix->mmio_len = 0x800; fix->mmio_len = 0x800;
fix->accel = FB_ACCEL_ATI_MACH64VT; fix->accel = FB_ACCEL_ATI_MACH64VT;
} else { } else {
fix->mmio_start = info->ati_regbase_phys-0x400); fix->mmio_start = info->ati_regbase_phys-0x400;
fix->mmio_len = 0x800; fix->mmio_len = 0x800;
fix->accel = FB_ACCEL_ATI_MACH64GT; fix->accel = FB_ACCEL_ATI_MACH64GT;
} }
......
/*
* linux/drivers/video/modedb.c -- Standard video mode database management
*
* Copyright (C) 1999 Geert Uytterhoeven
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/tty.h>
#include <linux/fb.h>
#include <linux/console_struct.h>
#include <linux/sched.h>
#define DEBUG
#define name_matches(v, s, l) \
((v).name && !strncmp((s), (v).name, (l)) && strlen((v).name) == (l))
#define res_matches(v, x, y) \
((v).xres == (x) && (v).yres == (y))
#ifdef DEBUG
#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
#else
#define DPRINTK(fmt, args...)
#endif
const char *global_mode_option = NULL;
/*
* Standard video mode definitions (taken from XFree86)
*/
#define DEFAULT_MODEDB_INDEX 0
static const struct fb_videomode modedb[] __initdata = {
{
/* 640x400 @ 70 Hz, 31.5 kHz hsync */
NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
0, FB_VMODE_NONINTERLACED
}, {
/* 640x480 @ 60 Hz, 31.5 kHz hsync */
NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
0, FB_VMODE_NONINTERLACED
}, {
/* 800x600 @ 56 Hz, 35.15 kHz hsync */
NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
0, FB_VMODE_NONINTERLACED
}, {
/* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
0, FB_VMODE_INTERLACED
}, {
/* 640x400 @ 85 Hz, 37.86 kHz hsync */
NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}, {
/* 640x480 @ 72 Hz, 36.5 kHz hsync */
NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
0, FB_VMODE_NONINTERLACED
}, {
/* 640x480 @ 75 Hz, 37.50 kHz hsync */
NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
0, FB_VMODE_NONINTERLACED
}, {
/* 800x600 @ 60 Hz, 37.8 kHz hsync */
NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}, {
/* 640x480 @ 85 Hz, 43.27 kHz hsync */
NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
0, FB_VMODE_NONINTERLACED
}, {
/* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
0, FB_VMODE_INTERLACED
}, {
/* 800x600 @ 72 Hz, 48.0 kHz hsync */
NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}, {
/* 1024x768 @ 60 Hz, 48.4 kHz hsync */
NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
0, FB_VMODE_NONINTERLACED
}, {
/* 640x480 @ 100 Hz, 53.01 kHz hsync */
NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
0, FB_VMODE_NONINTERLACED
}, {
/* 1152x864 @ 60 Hz, 53.5 kHz hsync */
NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
0, FB_VMODE_NONINTERLACED
}, {
/* 800x600 @ 85 Hz, 55.84 kHz hsync */
NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
0, FB_VMODE_NONINTERLACED
}, {
/* 1024x768 @ 70 Hz, 56.5 kHz hsync */
NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
0, FB_VMODE_NONINTERLACED
}, {
/* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
0, FB_VMODE_INTERLACED
}, {
/* 800x600 @ 100 Hz, 64.02 kHz hsync */
NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
0, FB_VMODE_NONINTERLACED
}, {
/* 1024x768 @ 76 Hz, 62.5 kHz hsync */
NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
0, FB_VMODE_NONINTERLACED
}, {
/* 1152x864 @ 70 Hz, 62.4 kHz hsync */
NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
0, FB_VMODE_NONINTERLACED
}, {
/* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
0, FB_VMODE_NONINTERLACED
}, {
/* 1024x768 @ 85 Hz, 70.24 kHz hsync */
NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
0, FB_VMODE_NONINTERLACED
}, {
/* 1152x864 @ 78 Hz, 70.8 kHz hsync */
NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
0, FB_VMODE_NONINTERLACED
}, {
/* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
0, FB_VMODE_NONINTERLACED
}, {
/* 1600x1200 @ 60Hz, 75.00 kHz hsync */
NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}, {
/* 1152x864 @ 84 Hz, 76.0 kHz hsync */
NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
0, FB_VMODE_NONINTERLACED
}, {
/* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
0, FB_VMODE_NONINTERLACED
}, {
/* 1024x768 @ 100Hz, 80.21 kHz hsync */
NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
0, FB_VMODE_NONINTERLACED
}, {
/* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
0, FB_VMODE_NONINTERLACED
}, {
/* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
0, FB_VMODE_NONINTERLACED
}, {
/* 1152x864 @ 100 Hz, 89.62 kHz hsync */
NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
0, FB_VMODE_NONINTERLACED
}, {
/* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}, {
/* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}, {
/* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}, {
/* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
0, FB_VMODE_NONINTERLACED
}, {
/* 1800x1440 @ 64Hz, 96.15 kHz hsync */
NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}, {
/* 1800x1440 @ 70Hz, 104.52 kHz hsync */
NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}, {
/* 512x384 @ 78 Hz, 31.50 kHz hsync */
NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
0, FB_VMODE_NONINTERLACED
}, {
/* 512x384 @ 85 Hz, 34.38 kHz hsync */
NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
0, FB_VMODE_NONINTERLACED
}, {
/* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
0, FB_VMODE_DOUBLE
}, {
/* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
0, FB_VMODE_DOUBLE
}, {
/* 320x240 @ 72 Hz, 36.5 kHz hsync */
NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
0, FB_VMODE_DOUBLE
}, {
/* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
0, FB_VMODE_DOUBLE
}, {
/* 400x300 @ 60 Hz, 37.8 kHz hsync */
NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
0, FB_VMODE_DOUBLE
}, {
/* 400x300 @ 72 Hz, 48.0 kHz hsync */
NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
0, FB_VMODE_DOUBLE
}, {
/* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
0, FB_VMODE_DOUBLE
}, {
/* 480x300 @ 60 Hz, 37.8 kHz hsync */
NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
0, FB_VMODE_DOUBLE
}, {
/* 480x300 @ 63 Hz, 39.6 kHz hsync */
NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
0, FB_VMODE_DOUBLE
}, {
/* 480x300 @ 72 Hz, 48.0 kHz hsync */
NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
0, FB_VMODE_DOUBLE
},
};
static int __init my_atoi(const char *name)
{
int val = 0;
for (;; name++) {
switch (*name) {
case '0'...'9':
val = 10*val+(*name-'0');
break;
default:
return val;
}
}
}
static int __init PROC_CONSOLE(const struct fb_info *info)
{
int fgc;
if (info->display_fg != NULL)
fgc = info->display_fg->vc_num;
else
return -1;
if (!current->tty)
return fgc;
if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
/* XXX Should report error here? */
return fgc;
if (MINOR(current->tty->device) < 1)
return fgc;
return MINOR(current->tty->device) - 1;
}
static int __init try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
const struct fb_videomode *mode, unsigned int bpp)
{
int err;
DPRINTK("Trying mode %s %dx%d-%d@%d\n", mode->name ? mode->name : "noname",
mode->xres, mode->yres, bpp, mode->refresh);
var->xres = mode->xres;
var->yres = mode->yres;
var->xres_virtual = mode->xres;
var->yres_virtual = mode->yres;
var->xoffset = 0;
var->yoffset = 0;
var->bits_per_pixel = bpp;
var->activate |= FB_ACTIVATE_TEST;
var->pixclock = mode->pixclock;
var->left_margin = mode->left_margin;
var->right_margin = mode->right_margin;
var->upper_margin = mode->upper_margin;
var->lower_margin = mode->lower_margin;
var->hsync_len = mode->hsync_len;
var->vsync_len = mode->vsync_len;
var->sync = mode->sync;
var->vmode = mode->vmode;
err = info->fbops->fb_set_var(var, PROC_CONSOLE(info), info);
var->activate &= ~FB_ACTIVATE_TEST;
return !err;
}
/*
*
* Find a suitable video mode
*
* Valid mode specifiers (mode_option):
*
* <xres>x<yres>[-<bpp>][@<refresh>]
* <name>[-<bpp>][@<refresh>]
*
* with <xres>, <yres>, <bpp> and <refresh> decimal numbers and <name> a
* string
*
* The passed struct fb_var_screeninfo is _not_ cleared! This allows you
* to supply values for e.g. the grayscale and accel_flags fields.
*/
int __init fb_find_mode(struct fb_var_screeninfo *var,
struct fb_info *info, const char *mode_option,
const struct fb_videomode *db, unsigned int dbsize,
const struct fb_videomode *default_mode,
unsigned int default_bpp)
{
int i, j;
/* Set up defaults */
if (!db) {
db = modedb;
dbsize = sizeof(modedb)/sizeof(*modedb);
}
if (!default_mode)
default_mode = &modedb[DEFAULT_MODEDB_INDEX];
if (!default_bpp)
default_bpp = 8;
/* Did the user specify a video mode? */
if (mode_option || (mode_option = global_mode_option)) {
const char *name = mode_option;
unsigned int namelen = strlen(name);
int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
int yres_specified = 0;
for (i = namelen-1; i >= 0; i--) {
switch (name[i]) {
case '@':
namelen = i;
if (!refresh_specified && !bpp_specified &&
!yres_specified) {
refresh = my_atoi(&name[i+1]);
refresh_specified = 1;
} else
goto done;
break;
case '-':
namelen = i;
if (!bpp_specified && !yres_specified) {
bpp = my_atoi(&name[i+1]);
bpp_specified = 1;
} else
goto done;
break;
case 'x':
if (!yres_specified) {
yres = my_atoi(&name[i+1]);
yres_specified = 1;
} else
goto done;
break;
case '0'...'9':
break;
default:
goto done;
}
}
if (i < 0 && yres_specified) {
xres = my_atoi(name);
res_specified = 1;
}
done:
for (i = refresh_specified; i >= 0; i--) {
DPRINTK("Trying specified video mode%s\n",
i ? "" : " (ignoring refresh rate)");
for (j = 0; j < dbsize; j++)
if ((name_matches(db[j], name, namelen) ||
(res_specified && res_matches(db[j], xres, yres))) &&
(!i || db[j].refresh == refresh) &&
try_mode(var, info, &db[j], bpp))
return 2-i;
}
}
DPRINTK("Trying default video mode\n");
if (try_mode(var, info, default_mode, default_bpp))
return 3;
DPRINTK("Trying all modes\n");
for (i = 0; i < dbsize; i++)
if (try_mode(var, info, &db[i], default_bpp))
return 4;
DPRINTK("No valid mode found\n");
return 0;
}
...@@ -8,19 +8,6 @@ ...@@ -8,19 +8,6 @@
#ifndef _LINUX_IOPORT_H #ifndef _LINUX_IOPORT_H
#define _LINUX_IOPORT_H #define _LINUX_IOPORT_H
#define DEVICE_IO_NOTSET (~0)
#define DEVICE_IO_AUTO ((~0)-1)
#define DEVICE_IO_FLAG_WRITEABLE (1<<0)
#define DEVICE_IO_FLAG_CACHEABLE (1<<1)
#define DEVICE_IO_FLAG_RANGELENGTH (1<<2)
#define DEVICE_IO_FLAG_SHADOWABLE (1<<4)
#define DEVICE_IO_FLAG_EXPANSIONROM (1<<5)
#define DEVICE_IO_TYPE_8BIT 0
#define DEVICE_IO_TYPE_16BIT 1
#define DEVICE_IO_TYPE_8AND16BIT 2
/* /*
* Resources are tree-like, allowing * Resources are tree-like, allowing
* nesting etc.. * nesting etc..
...@@ -29,22 +16,29 @@ struct resource { ...@@ -29,22 +16,29 @@ struct resource {
const char *name; const char *name;
unsigned long start, end; unsigned long start, end;
unsigned long flags; unsigned long flags;
unsigned char bits; /* decoded bits */
unsigned char fixed; /* fixed range */
unsigned short hw_flags; /* hardware flags */
unsigned short type; /* region type */
struct resource *parent, *sibling, *child; struct resource *parent, *sibling, *child;
}; };
/* /*
* PCI-like IO resources have these defined flags. * IO resources have these defined flags.
* The low four bits come directly from the PCI specs,
* the rest are extended sw flags..
*/ */
#define IORESOURCE_IOPORT 0x01 /* 0 - memory mapped, 1 - IO ports */ #define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
#define IORESOURCE_MEMTYPE_MASK 0x06 /* PCI-specific mapping info */
#define IORESOURCE_PREFETCH 0x08 /* No side effects */ #define IORESOURCE_IO 0x00000100 /* Resource type */
#define IORESOURCE_BUSY 0x10 /* Driver uses this resource */ #define IORESOURCE_MEM 0x00000200
#define IORESOURCE_IRQ 0x00000400
#define IORESOURCE_DMA 0x00000800
#define IORESOURCE_PREFETCH 0x00001000 /* No side effects */
#define IORESOURCE_READONLY 0x00002000
#define IORESOURCE_CACHEABLE 0x00004000
#define IORESOURCE_RANGELENGTH 0x00008000
#define IORESOURCE_SHADOWABLE 0x00010000
#define IORESOURCE_UNSET 0x00020000
#define IORESOURCE_AUTO 0x00040000
#define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */
/* PC/ISA/whatever - the normal PC address spaces: IO and memory */ /* PC/ISA/whatever - the normal PC address spaces: IO and memory */
extern struct resource ioport_resource; extern struct resource ioport_resource;
......
...@@ -24,6 +24,19 @@ ...@@ -24,6 +24,19 @@
#include <linux/config.h> #include <linux/config.h>
#define ISAPNP_NOTSET (~0)
#define ISAPNP_AUTO ((~0)-1)
#define ISAPNP_FLAG_WRITEABLE (1<<0)
#define ISAPNP_FLAG_CACHEABLE (1<<1)
#define ISAPNP_FLAG_RANGELENGTH (1<<2)
#define ISAPNP_FLAG_SHADOWABLE (1<<4)
#define ISAPNP_FLAG_EXPANSIONROM (1<<5)
#define ISAPNP_TYPE_8BIT 0
#define ISAPNP_TYPE_16BIT 1
#define ISAPNP_TYPE_8AND16BIT 2
/* /*
* Configuration registers (TODO: change by specification) * Configuration registers (TODO: change by specification)
*/ */
......
...@@ -1209,6 +1209,7 @@ ...@@ -1209,6 +1209,7 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#define DEVICE_COUNT_COMPATIBLE 4 #define DEVICE_COUNT_COMPATIBLE 4
#define DEVICE_COUNT_IRQ 2
#define DEVICE_COUNT_DMA 2 #define DEVICE_COUNT_DMA 2
#define DEVICE_COUNT_RESOURCE 12 #define DEVICE_COUNT_RESOURCE 12
...@@ -1276,19 +1277,15 @@ struct pci_dev { ...@@ -1276,19 +1277,15 @@ struct pci_dev {
* necessary. The field must not be 0 unless the device * necessary. The field must not be 0 unless the device
* cannot generate interrupts at all. * cannot generate interrupts at all.
*/ */
unsigned int irq; /* irq generated by this device */ unsigned int irq;
unsigned short irq_flags; /* irq type */
unsigned int irq2; /*
unsigned short irq2_flags; * Base registers for this device, can be adjusted by
unsigned char dma[DEVICE_COUNT_DMA];
unsigned char dma_type[DEVICE_COUNT_DMA];
unsigned char dma_flags[DEVICE_COUNT_DMA];
unsigned char dma_speed[DEVICE_COUNT_DMA];
/* Base registers for this device, can be adjusted by
* pcibios_fixup() as necessary. * pcibios_fixup() as necessary.
*/ */
struct resource resource[DEVICE_COUNT_RESOURCE]; struct resource resource[DEVICE_COUNT_RESOURCE];
struct resource dma_resource[DEVICE_COUNT_DMA];
struct resource irq_resource[DEVICE_COUNT_IRQ];
unsigned long rom_address; unsigned long rom_address;
int (*prepare)(struct pci_dev *dev); int (*prepare)(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