Commit 02e58fc8 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://ppc.bkbits.net/for-linus-ppc64

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 2e6e0d09 424706ad
...@@ -21,7 +21,7 @@ locking rules: ...@@ -21,7 +21,7 @@ locking rules:
dcache_lock may block dcache_lock may block
d_revalidate: no yes d_revalidate: no yes
d_hash no yes d_hash no yes
d_compare: yes no d_compare: no no
d_delete: yes no d_delete: yes no
d_release: no yes d_release: no yes
d_iput: no yes d_iput: no yes
......
...@@ -223,7 +223,7 @@ io7_redirect_one_lsi(struct io7 *io7, unsigned int which, unsigned int where) ...@@ -223,7 +223,7 @@ io7_redirect_one_lsi(struct io7 *io7, unsigned int which, unsigned int where)
*/ */
val = io7->csrs->PO7_LSI_CTL[which].csr; val = io7->csrs->PO7_LSI_CTL[which].csr;
val &= ~(0x1ffUL << 14); /* clear the target pid */ val &= ~(0x1ffUL << 14); /* clear the target pid */
val |= ((unsigned long)where << 14); /* set teh new target pid */ val |= ((unsigned long)where << 14); /* set the new target pid */
io7->csrs->PO7_LSI_CTL[which].csr = val; io7->csrs->PO7_LSI_CTL[which].csr = val;
mb(); mb();
...@@ -240,7 +240,7 @@ io7_redirect_one_msi(struct io7 *io7, unsigned int which, unsigned int where) ...@@ -240,7 +240,7 @@ io7_redirect_one_msi(struct io7 *io7, unsigned int which, unsigned int where)
*/ */
val = io7->csrs->PO7_MSI_CTL[which].csr; val = io7->csrs->PO7_MSI_CTL[which].csr;
val &= ~(0x1ffUL << 14); /* clear the target pid */ val &= ~(0x1ffUL << 14); /* clear the target pid */
val |= ((unsigned long)where << 14); /* set teh new target pid */ val |= ((unsigned long)where << 14); /* set the new target pid */
io7->csrs->PO7_MSI_CTL[which].csr = val; io7->csrs->PO7_MSI_CTL[which].csr = val;
mb(); mb();
......
...@@ -83,15 +83,13 @@ void __init mtrr_state_warn(void) ...@@ -83,15 +83,13 @@ void __init mtrr_state_warn(void)
if (!mask) if (!mask)
return; return;
if (mask & MTRR_CHANGE_MASK_FIXED) if (mask & MTRR_CHANGE_MASK_FIXED)
printk printk(KERN_WARNING "mtrr: your CPUs had inconsistent fixed MTRR settings\n");
("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
if (mask & MTRR_CHANGE_MASK_VARIABLE) if (mask & MTRR_CHANGE_MASK_VARIABLE)
printk printk(KERN_WARNING "mtrr: your CPUs had inconsistent variable MTRR settings\n");
("mtrr: your CPUs had inconsistent variable MTRR settings\n");
if (mask & MTRR_CHANGE_MASK_DEFTYPE) if (mask & MTRR_CHANGE_MASK_DEFTYPE)
printk printk(KERN_WARNING "mtrr: your CPUs had inconsistent MTRRdefType settings\n");
("mtrr: your CPUs had inconsistent MTRRdefType settings\n"); printk(KERN_INFO "mtrr: probably your BIOS does not setup all CPUs.\n");
printk("mtrr: probably your BIOS does not setup all CPUs\n"); printk(KERN_INFO "mtrr: corrected configuration.\n");
} }
...@@ -338,23 +336,19 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i ...@@ -338,23 +336,19 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i
boot_cpu_data.x86_model == 1 && boot_cpu_data.x86_model == 1 &&
boot_cpu_data.x86_mask <= 7) { boot_cpu_data.x86_mask <= 7) {
if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) { if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) {
printk(KERN_WARNING printk(KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
"mtrr: base(0x%lx000) is not 4 MiB aligned\n",
base);
return -EINVAL; return -EINVAL;
} }
if (!(base + size < 0x70000000 || base > 0x7003FFFF) && if (!(base + size < 0x70000000 || base > 0x7003FFFF) &&
(type == MTRR_TYPE_WRCOMB (type == MTRR_TYPE_WRCOMB
|| type == MTRR_TYPE_WRBACK)) { || type == MTRR_TYPE_WRBACK)) {
printk(KERN_WARNING printk(KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
"mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
return -EINVAL; return -EINVAL;
} }
} }
if (base + size < 0x100) { if (base + size < 0x100) {
printk(KERN_WARNING printk(KERN_WARNING "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n",
"mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n",
base, size); base, size);
return -EINVAL; return -EINVAL;
} }
...@@ -364,8 +358,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i ...@@ -364,8 +358,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i
for (lbase = base; !(lbase & 1) && (last & 1); for (lbase = base; !(lbase & 1) && (last & 1);
lbase = lbase >> 1, last = last >> 1) ; lbase = lbase >> 1, last = last >> 1) ;
if (lbase != last) { if (lbase != last) {
printk(KERN_WARNING printk(KERN_WARNING "mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n",
"mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n",
base, size); base, size);
return -EINVAL; return -EINVAL;
} }
......
...@@ -668,7 +668,9 @@ static int __init find_isa_irq_pin(int irq, int type) ...@@ -668,7 +668,9 @@ static int __init find_isa_irq_pin(int irq, int type)
if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
mp_bus_id_to_type[lbus] == MP_BUS_EISA || mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
mp_bus_id_to_type[lbus] == MP_BUS_MCA) && mp_bus_id_to_type[lbus] == MP_BUS_MCA ||
mp_bus_id_to_type[lbus] == MP_BUS_NEC98
) &&
(mp_irqs[i].mpc_irqtype == type) && (mp_irqs[i].mpc_irqtype == type) &&
(mp_irqs[i].mpc_srcbusirq == irq)) (mp_irqs[i].mpc_srcbusirq == irq))
...@@ -762,6 +764,12 @@ static int __init EISA_ELCR(unsigned int irq) ...@@ -762,6 +764,12 @@ static int __init EISA_ELCR(unsigned int irq)
#define default_MCA_trigger(idx) (1) #define default_MCA_trigger(idx) (1)
#define default_MCA_polarity(idx) (0) #define default_MCA_polarity(idx) (0)
/* NEC98 interrupts are always polarity zero edge triggered,
* when listed as conforming in the MP table. */
#define default_NEC98_trigger(idx) (0)
#define default_NEC98_polarity(idx) (0)
static int __init MPBIOS_polarity(int idx) static int __init MPBIOS_polarity(int idx)
{ {
int bus = mp_irqs[idx].mpc_srcbus; int bus = mp_irqs[idx].mpc_srcbus;
...@@ -796,6 +804,11 @@ static int __init MPBIOS_polarity(int idx) ...@@ -796,6 +804,11 @@ static int __init MPBIOS_polarity(int idx)
polarity = default_MCA_polarity(idx); polarity = default_MCA_polarity(idx);
break; break;
} }
case MP_BUS_NEC98: /* NEC 98 pin */
{
polarity = default_NEC98_polarity(idx);
break;
}
default: default:
{ {
printk(KERN_WARNING "broken BIOS!!\n"); printk(KERN_WARNING "broken BIOS!!\n");
...@@ -865,6 +878,11 @@ static int __init MPBIOS_trigger(int idx) ...@@ -865,6 +878,11 @@ static int __init MPBIOS_trigger(int idx)
trigger = default_MCA_trigger(idx); trigger = default_MCA_trigger(idx);
break; break;
} }
case MP_BUS_NEC98: /* NEC 98 pin */
{
trigger = default_NEC98_trigger(idx);
break;
}
default: default:
{ {
printk(KERN_WARNING "broken BIOS!!\n"); printk(KERN_WARNING "broken BIOS!!\n");
...@@ -926,6 +944,7 @@ static int pin_2_irq(int idx, int apic, int pin) ...@@ -926,6 +944,7 @@ static int pin_2_irq(int idx, int apic, int pin)
case MP_BUS_ISA: /* ISA pin */ case MP_BUS_ISA: /* ISA pin */
case MP_BUS_EISA: case MP_BUS_EISA:
case MP_BUS_MCA: case MP_BUS_MCA:
case MP_BUS_NEC98:
{ {
irq = mp_irqs[idx].mpc_srcbusirq; irq = mp_irqs[idx].mpc_srcbusirq;
break; break;
...@@ -1133,8 +1152,9 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector) ...@@ -1133,8 +1152,9 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
void __init UNEXPECTED_IO_APIC(void) void __init UNEXPECTED_IO_APIC(void)
{ {
printk(KERN_WARNING " WARNING: unexpected IO-APIC, please mail\n"); printk(KERN_WARNING "INFO: unexpected IO-APIC, please file a report at\n");
printk(KERN_WARNING " to linux-smp@vger.kernel.org\n"); printk(KERN_WARNING " http://bugzilla.kernel.org\n");
printk(KERN_WARNING " if your kernel is less than 3 months old.\n");
} }
void __init print_IO_APIC(void) void __init print_IO_APIC(void)
......
...@@ -169,7 +169,7 @@ void __init MP_processor_info (struct mpc_config_processor *m) ...@@ -169,7 +169,7 @@ void __init MP_processor_info (struct mpc_config_processor *m)
num_processors++; num_processors++;
if (m->mpc_apicid > MAX_APICS) { if (m->mpc_apicid > MAX_APICS) {
printk("Processor #%d INVALID. (Max ID: %d).\n", printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n",
m->mpc_apicid, MAX_APICS); m->mpc_apicid, MAX_APICS);
--num_processors; --num_processors;
return; return;
...@@ -182,7 +182,7 @@ void __init MP_processor_info (struct mpc_config_processor *m) ...@@ -182,7 +182,7 @@ void __init MP_processor_info (struct mpc_config_processor *m)
* Validate version * Validate version
*/ */
if (ver == 0x0) { if (ver == 0x0) {
printk("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid); printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
ver = 0x10; ver = 0x10;
} }
apic_version[m->mpc_apicid] = ver; apic_version[m->mpc_apicid] = ver;
...@@ -209,8 +209,10 @@ static void __init MP_bus_info (struct mpc_config_bus *m) ...@@ -209,8 +209,10 @@ static void __init MP_bus_info (struct mpc_config_bus *m)
mp_current_pci_id++; mp_current_pci_id++;
} else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) { } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) {
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA; mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
} else if (strncmp(str, BUSTYPE_NEC98, sizeof(BUSTYPE_NEC98)-1) == 0) {
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_NEC98;
} else { } else {
printk("Unknown bustype %s - ignoring\n", str); printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
} }
} }
...@@ -219,10 +221,10 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m) ...@@ -219,10 +221,10 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
if (!(m->mpc_flags & MPC_APIC_USABLE)) if (!(m->mpc_flags & MPC_APIC_USABLE))
return; return;
printk("I/O APIC #%d Version %d at 0x%lX.\n", printk(KERN_INFO "I/O APIC #%d Version %d at 0x%lX.\n",
m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr); m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
if (nr_ioapics >= MAX_IO_APICS) { if (nr_ioapics >= MAX_IO_APICS) {
printk("Max # of I/O APICs (%d) exceeded (found %d).\n", printk(KERN_CRIT "Max # of I/O APICs (%d) exceeded (found %d).\n",
MAX_IO_APICS, nr_ioapics); MAX_IO_APICS, nr_ioapics);
panic("Recompile kernel with bigger MAX_IO_APICS!.\n"); panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
} }
...@@ -272,10 +274,10 @@ static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m) ...@@ -272,10 +274,10 @@ static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
#ifdef CONFIG_X86_NUMAQ #ifdef CONFIG_X86_NUMAQ
static void __init MP_translation_info (struct mpc_config_translation *m) static void __init MP_translation_info (struct mpc_config_translation *m)
{ {
printk("Translation: record %d, type %d, quad %d, global %d, local %d\n", mpc_record, m->trans_type, m->trans_quad, m->trans_global, m->trans_local); printk(KERN_INFO "Translation: record %d, type %d, quad %d, global %d, local %d\n", mpc_record, m->trans_type, m->trans_quad, m->trans_global, m->trans_local);
if (mpc_record >= MAX_MPC_ENTRY) if (mpc_record >= MAX_MPC_ENTRY)
printk("MAX_MPC_ENTRY exceeded!\n"); printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
else else
translation_table[mpc_record] = m; /* stash this for later */ translation_table[mpc_record] = m; /* stash this for later */
if (m->trans_quad+1 > numnodes) if (m->trans_quad+1 > numnodes)
...@@ -293,10 +295,10 @@ static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \ ...@@ -293,10 +295,10 @@ static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \
unsigned char *oemptr = ((unsigned char *)oemtable)+count; unsigned char *oemptr = ((unsigned char *)oemtable)+count;
mpc_record = 0; mpc_record = 0;
printk("Found an OEM MPC table at %8p - parsing it ... \n", oemtable); printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n", oemtable);
if (memcmp(oemtable->oem_signature,MPC_OEM_SIGNATURE,4)) if (memcmp(oemtable->oem_signature,MPC_OEM_SIGNATURE,4))
{ {
printk("SMP mpc oemtable: bad signature [%c%c%c%c]!\n", printk(KERN_WARNING "SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
oemtable->oem_signature[0], oemtable->oem_signature[0],
oemtable->oem_signature[1], oemtable->oem_signature[1],
oemtable->oem_signature[2], oemtable->oem_signature[2],
...@@ -305,7 +307,7 @@ static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \ ...@@ -305,7 +307,7 @@ static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \
} }
if (mpf_checksum((unsigned char *)oemtable,oemtable->oem_length)) if (mpf_checksum((unsigned char *)oemtable,oemtable->oem_length))
{ {
printk("SMP oem mptable: checksum error!\n"); printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
return; return;
} }
while (count < oemtable->oem_length) { while (count < oemtable->oem_length) {
...@@ -322,7 +324,7 @@ static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \ ...@@ -322,7 +324,7 @@ static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \
} }
default: default:
{ {
printk("Unrecognised OEM table entry type! - %d\n", (int) *oemptr); printk(KERN_WARNING "Unrecognised OEM table entry type! - %d\n", (int) *oemptr);
return; return;
} }
} }
...@@ -364,7 +366,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) ...@@ -364,7 +366,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
} }
memcpy(oem,mpc->mpc_oem,8); memcpy(oem,mpc->mpc_oem,8);
oem[8]=0; oem[8]=0;
printk("OEM ID: %s ",oem); printk(KERN_INFO "OEM ID: %s ",oem);
memcpy(str,mpc->mpc_productid,12); memcpy(str,mpc->mpc_productid,12);
str[12]=0; str[12]=0;
...@@ -479,12 +481,12 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type) ...@@ -479,12 +481,12 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type)
* If it does, we assume it's valid. * If it does, we assume it's valid.
*/ */
if (mpc_default_type == 5) { if (mpc_default_type == 5) {
printk("ISA/PCI bus type with no IRQ information... falling back to ELCR\n"); printk(KERN_INFO "ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13)) if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13))
printk("ELCR contains invalid data... not using ELCR\n"); printk(KERN_WARNING "ELCR contains invalid data... not using ELCR\n");
else { else {
printk("Using ELCR to identify PCI interrupts\n"); printk(KERN_INFO "Using ELCR to identify PCI interrupts\n");
ELCR_fallback = 1; ELCR_fallback = 1;
} }
} }
...@@ -559,7 +561,8 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) ...@@ -559,7 +561,8 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
bus.mpc_busid = 0; bus.mpc_busid = 0;
switch (mpc_default_type) { switch (mpc_default_type) {
default: default:
printk("???\nUnknown standard configuration %d\n", printk("???\n");
printk(KERN_ERR "Unknown standard configuration %d\n",
mpc_default_type); mpc_default_type);
/* fall through */ /* fall through */
case 1: case 1:
...@@ -628,12 +631,12 @@ void __init get_smp_config (void) ...@@ -628,12 +631,12 @@ void __init get_smp_config (void)
else if (acpi_lapic) else if (acpi_lapic)
printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n"); printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n");
printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); printk("KERN_INFO Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
if (mpf->mpf_feature2 & (1<<7)) { if (mpf->mpf_feature2 & (1<<7)) {
printk(" IMCR and PIC compatibility mode.\n"); printk(KERN_INFO " IMCR and PIC compatibility mode.\n");
pic_mode = 1; pic_mode = 1;
} else { } else {
printk(" Virtual Wire compatibility mode.\n"); printk(KERN_INFO " Virtual Wire compatibility mode.\n");
pic_mode = 0; pic_mode = 0;
} }
...@@ -642,7 +645,7 @@ void __init get_smp_config (void) ...@@ -642,7 +645,7 @@ void __init get_smp_config (void)
*/ */
if (mpf->mpf_feature1 != 0) { if (mpf->mpf_feature1 != 0) {
printk("Default MP configuration #%d\n", mpf->mpf_feature1); printk(KERN_INFO "Default MP configuration #%d\n", mpf->mpf_feature1);
construct_default_ISA_mptable(mpf->mpf_feature1); construct_default_ISA_mptable(mpf->mpf_feature1);
} else if (mpf->mpf_physptr) { } else if (mpf->mpf_physptr) {
...@@ -665,7 +668,7 @@ void __init get_smp_config (void) ...@@ -665,7 +668,7 @@ void __init get_smp_config (void)
if (!mp_irq_entries) { if (!mp_irq_entries) {
struct mpc_config_bus bus; struct mpc_config_bus bus;
printk("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n"); printk(KERN_ERR "BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
bus.mpc_type = MP_BUS; bus.mpc_type = MP_BUS;
bus.mpc_busid = 0; bus.mpc_busid = 0;
...@@ -678,7 +681,7 @@ void __init get_smp_config (void) ...@@ -678,7 +681,7 @@ void __init get_smp_config (void)
} else } else
BUG(); BUG();
printk("Processors: %d\n", num_processors); printk(KERN_INFO "Processors: %d\n", num_processors);
/* /*
* Only use the first configuration found. * Only use the first configuration found.
*/ */
...@@ -702,7 +705,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length) ...@@ -702,7 +705,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
|| (mpf->mpf_specification == 4)) ) { || (mpf->mpf_specification == 4)) ) {
smp_found_config = 1; smp_found_config = 1;
printk("found SMP MP-table at %08lx\n", printk(KERN_INFO "found SMP MP-table at %08lx\n",
virt_to_phys(mpf)); virt_to_phys(mpf));
reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE); reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
if (mpf->mpf_physptr) if (mpf->mpf_physptr)
...@@ -752,8 +755,6 @@ void __init find_smp_config (void) ...@@ -752,8 +755,6 @@ void __init find_smp_config (void)
address = *(unsigned short *)phys_to_virt(0x40E); address = *(unsigned short *)phys_to_virt(0x40E);
address <<= 4; address <<= 4;
smp_scan_config(address, 0x400); smp_scan_config(address, 0x400);
if (smp_found_config)
printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.kernel.org if you experience SMP problems!\n");
} }
......
...@@ -452,9 +452,11 @@ static void flush_tlb_all_ipi(void* info) ...@@ -452,9 +452,11 @@ static void flush_tlb_all_ipi(void* info)
void flush_tlb_all(void) void flush_tlb_all(void)
{ {
preempt_disable();
smp_call_function (flush_tlb_all_ipi,0,1,1); smp_call_function (flush_tlb_all_ipi,0,1,1);
do_flush_tlb_all_local(); do_flush_tlb_all_local();
preempt_enable();
} }
/* /*
......
...@@ -631,7 +631,7 @@ hub_provider_shutdown(devfs_handle_t hub) ...@@ -631,7 +631,7 @@ hub_provider_shutdown(devfs_handle_t hub)
} }
/* /*
* Check that an address is in teh real small window widget 0 space * Check that an address is in the real small window widget 0 space
* or else in the big window we're using to emulate small window 0 * or else in the big window we're using to emulate small window 0
* in the kernel. * in the kernel.
*/ */
...@@ -708,7 +708,7 @@ hub_check_pci_equiv(void *addra, void *addrb) ...@@ -708,7 +708,7 @@ hub_check_pci_equiv(void *addra, void *addrb)
/* /*
* hub_setup_prb(nasid, prbnum, credits, conveyor) * hub_setup_prb(nasid, prbnum, credits, conveyor)
* *
* Put a PRB into fire-and-forget mode if conveyor isn't set. Otehrwise, * Put a PRB into fire-and-forget mode if conveyor isn't set. Otherwise,
* put it into conveyor belt mode with the specified number of credits. * put it into conveyor belt mode with the specified number of credits.
*/ */
void void
......
...@@ -320,7 +320,8 @@ tracesys_sigexit: ...@@ -320,7 +320,8 @@ tracesys_sigexit:
#ifdef __LP64__ #ifdef __LP64__
/* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and /* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and
* narrow palinux. Use ENTRY_DIFF for those where a 32-bit specific * narrow palinux. Use ENTRY_DIFF for those where a 32-bit specific
* implementation is required on wide palinux. * implementation is required on wide palinux. Use ENTRY_COMP where
* the compatability layer has a useful 32-bit implementation.
*/ */
#define ENTRY_SAME(_name_) .dword sys_##_name_ #define ENTRY_SAME(_name_) .dword sys_##_name_
#define ENTRY_DIFF(_name_) .dword sys32_##_name_ #define ENTRY_DIFF(_name_) .dword sys32_##_name_
...@@ -597,7 +598,7 @@ sys_call_table: ...@@ -597,7 +598,7 @@ sys_call_table:
ENTRY_SAME(ni_syscall) /* tkill */ ENTRY_SAME(ni_syscall) /* tkill */
ENTRY_SAME(sendfile64) ENTRY_SAME(sendfile64)
ENTRY_SAME(futex) /* 210 */ ENTRY_COMP(futex) /* 210 */
ENTRY_SAME(sched_setaffinity) ENTRY_SAME(sched_setaffinity)
ENTRY_SAME(sched_getaffinity) ENTRY_SAME(sched_getaffinity)
ENTRY_SAME(set_thread_area) ENTRY_SAME(set_thread_area)
......
...@@ -41,9 +41,9 @@ ...@@ -41,9 +41,9 @@
#define dbsr 0x3f0 /* debug status register */ #define dbsr 0x3f0 /* debug status register */
#define dccr 0x3fa /* data cache control reg. */ #define dccr 0x3fa /* data cache control reg. */
#define dcwr 0x3ba /* data cache write-thru reg */ #define dcwr 0x3ba /* data cache write-thru reg */
#define dear 0x3d5 /* data exeption address reg */ #define dear 0x3d5 /* data exception address reg */
#define esr 0x3d4 /* execption syndrome registe */ #define esr 0x3d4 /* exception syndrome registe */
#define evpr 0x3d6 /* exeption vector prefix reg */ #define evpr 0x3d6 /* exception vector prefix reg */
#define iccr 0x3fb /* instruction cache cntrl re */ #define iccr 0x3fb /* instruction cache cntrl re */
#define icdbdr 0x3d3 /* instr cache dbug data reg */ #define icdbdr 0x3d3 /* instr cache dbug data reg */
#define lrreg 0x008 /* link register */ #define lrreg 0x008 /* link register */
......
...@@ -1337,7 +1337,7 @@ setup_604_hid0: ...@@ -1337,7 +1337,7 @@ setup_604_hid0:
blr blr
/* 7400 <= rev 2.7 and 7410 rev = 1.0 suffer from some /* 7400 <= rev 2.7 and 7410 rev = 1.0 suffer from some
* erratas we work around here. * errata we work around here.
* Moto MPC710CE.pdf describes them, those are errata * Moto MPC710CE.pdf describes them, those are errata
* #3, #4 and #5 * #3, #4 and #5
* Note that we assume the firmware didn't choose to * Note that we assume the firmware didn't choose to
......
...@@ -723,7 +723,7 @@ _GLOBAL(sys_call_table32) ...@@ -723,7 +723,7 @@ _GLOBAL(sys_call_table32)
.llong .sys_removexattr .llong .sys_removexattr
.llong .sys_lremovexattr .llong .sys_lremovexattr
.llong .sys_fremovexattr /* 220 */ .llong .sys_fremovexattr /* 220 */
.llong .sys_futex .llong .compat_sys_futex
.llong .sys32_sched_setaffinity .llong .sys32_sched_setaffinity
.llong .sys32_sched_getaffinity .llong .sys32_sched_getaffinity
.llong .sys_ni_syscall .llong .sys_ni_syscall
......
...@@ -629,7 +629,7 @@ sys_call_table: ...@@ -629,7 +629,7 @@ sys_call_table:
.long SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper) /* 235 */ .long SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper) /* 235 */
.long SYSCALL(sys_gettid,sys_gettid) .long SYSCALL(sys_gettid,sys_gettid)
.long SYSCALL(sys_tkill,sys_tkill) .long SYSCALL(sys_tkill,sys_tkill)
.long SYSCALL(sys_futex,sys32_futex_wrapper) .long SYSCALL(sys_futex,compat_sys_futex_wrapper)
.long SYSCALL(sys_sched_setaffinity,sys32_sched_setaffinity_wrapper) .long SYSCALL(sys_sched_setaffinity,sys32_sched_setaffinity_wrapper)
.long SYSCALL(sys_sched_getaffinity,sys32_sched_getaffinity_wrapper) /* 240 */ .long SYSCALL(sys_sched_getaffinity,sys32_sched_getaffinity_wrapper) /* 240 */
.long SYSCALL(sys_ni_syscall,sys_ni_syscall) .long SYSCALL(sys_ni_syscall,sys_ni_syscall)
......
...@@ -4049,28 +4049,6 @@ asmlinkage int sys32_sched_getaffinity(compat_pid_t pid, unsigned int len, ...@@ -4049,28 +4049,6 @@ asmlinkage int sys32_sched_getaffinity(compat_pid_t pid, unsigned int len,
return ret; return ret;
} }
asmlinkage int
sys_futex(void *uaddr, int op, int val, struct timespec *utime);
asmlinkage int
sys32_futex(void *uaddr, int op, int val,
struct compat_timespec *timeout32)
{
struct timespec tmp;
mm_segment_t old_fs;
int ret;
if (timeout32 && get_compat_timespec(&tmp, timeout32))
return -EINVAL;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_futex(uaddr, op, val, timeout32 ? &tmp : NULL);
set_fs(old_fs);
return ret;
}
asmlinkage ssize_t sys_read(unsigned int fd, char * buf, size_t count); asmlinkage ssize_t sys_read(unsigned int fd, char * buf, size_t count);
asmlinkage compat_ssize_t sys32_read(unsigned int fd, char * buf, size_t count) asmlinkage compat_ssize_t sys32_read(unsigned int fd, char * buf, size_t count)
......
...@@ -1088,13 +1088,13 @@ sys32_fstat64_wrapper: ...@@ -1088,13 +1088,13 @@ sys32_fstat64_wrapper:
llgfr %r4,%r4 # long llgfr %r4,%r4 # long
jg sys32_fstat64 # branch to system call jg sys32_fstat64 # branch to system call
.globl sys32_futex_wrapper .globl compat_sys_futex_wrapper
sys32_futex_wrapper: compat_sys_futex_wrapper:
llgtr %r2,%r2 # void * llgtr %r2,%r2 # u32 *
lgfr %r3,%r3 # int lgfr %r3,%r3 # int
lgfr %r4,%r4 # int lgfr %r4,%r4 # int
llgtr %r5,%r5 # struct timespec * llgtr %r5,%r5 # struct compat_timespec *
jg sys32_futex # branch to system call jg compat_sys_futex # branch to system call
.globl sys32_setxattr_wrapper .globl sys32_setxattr_wrapper
sys32_setxattr_wrapper: sys32_setxattr_wrapper:
......
...@@ -440,7 +440,7 @@ ia32_sys_call_table: ...@@ -440,7 +440,7 @@ ia32_sys_call_table:
.quad sys_fremovexattr .quad sys_fremovexattr
.quad sys_tkill /* 238 */ .quad sys_tkill /* 238 */
.quad sys_sendfile64 .quad sys_sendfile64
.quad sys32_futex /* 240 */ .quad compat_sys_futex /* 240 */
.quad sys32_sched_setaffinity .quad sys32_sched_setaffinity
.quad sys32_sched_getaffinity .quad sys32_sched_getaffinity
.quad sys_set_thread_area .quad sys_set_thread_area
......
...@@ -2199,26 +2199,6 @@ long sys32_sched_getaffinity(pid_t pid, unsigned int len, ...@@ -2199,26 +2199,6 @@ long sys32_sched_getaffinity(pid_t pid, unsigned int len,
return err; return err;
} }
extern int sys_futex(unsigned long uaddr, int op, int val, struct timespec *t);
asmlinkage long
sys32_futex(unsigned long uaddr, int op, int val, struct compat_timespec *utime32)
{
struct timespec t;
mm_segment_t oldfs = get_fs();
int err;
if (utime32 && get_compat_timespec(&t, utime32))
return -EFAULT;
/* the set_fs is safe because futex doesn't use the seg limit
for valid page checking of uaddr. */
set_fs(KERNEL_DS);
err = sys_futex(uaddr, op, val, utime32 ? &t : NULL);
set_fs(oldfs);
return err;
}
extern long sys_io_setup(unsigned nr_reqs, aio_context_t *ctx); extern long sys_io_setup(unsigned nr_reqs, aio_context_t *ctx);
long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p) long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p)
......
This diff is collapsed.
...@@ -89,8 +89,10 @@ static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR] = { ...@@ -89,8 +89,10 @@ static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR] = {
working even with the SCSI system. It's so working even with the SCSI system. It's so
scsi_unregister_host will differentiate the controllers. scsi_unregister_host will differentiate the controllers.
When register_scsi_module is called, each host template is When register_scsi_module is called, each host template is
customized (name change) in cciss_register_scsi() customized (name change) in cciss_register_scsi() (that's
(that's called from cciss.c:cciss_init_one()) */ called from cciss_engage_scsi, called from
cciss.c:cciss_proc_write(), on "engage scsi" being received
from user space.) */
static static
Scsi_Host_Template driver_template[MAX_CTLR] = Scsi_Host_Template driver_template[MAX_CTLR] =
...@@ -199,14 +201,12 @@ scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd) ...@@ -199,14 +201,12 @@ scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd)
} }
static int static int
scsi_cmd_stack_setup(int ctlr) scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa)
{ {
int i; int i;
struct cciss_scsi_adapter_data_t *sa;
struct cciss_scsi_cmd_stack_t *stk; struct cciss_scsi_cmd_stack_t *stk;
size_t size; size_t size;
sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
stk = &sa->cmd_stack; stk = &sa->cmd_stack;
size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE; size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
...@@ -535,126 +535,24 @@ lookup_scsi3addr(int ctlr, int bus, int target, int lun, char *scsi3addr) ...@@ -535,126 +535,24 @@ lookup_scsi3addr(int ctlr, int bus, int target, int lun, char *scsi3addr)
return -1; return -1;
} }
static void static void
cciss_find_non_disk_devices(int cntl_num) cciss_scsi_setup(int cntl_num)
{ {
ReportLunData_struct *ld_buff; struct cciss_scsi_adapter_data_t * shba;
InquiryData_struct *inq_buff;
int return_code;
int i;
int listlength = 0;
int num_luns;
unsigned char scsi3addr[8];
unsigned long flags;
int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8;
hba[cntl_num]->scsi_ctlr = (void *)
kmalloc(sizeof(struct cciss_scsi_adapter_data_t),
GFP_KERNEL);
if (hba[cntl_num]->scsi_ctlr == NULL)
return;
((struct cciss_scsi_adapter_data_t *)
hba[cntl_num]->scsi_ctlr)->scsi_host = NULL;
((struct cciss_scsi_adapter_data_t *)
hba[cntl_num]->scsi_ctlr)->lock = SPIN_LOCK_UNLOCKED;
((struct cciss_scsi_adapter_data_t *)
hba[cntl_num]->scsi_ctlr)->registered = 0;
if (scsi_cmd_stack_setup(cntl_num) != 0) {
printk("Trouble, returned non-zero!\n");
return;
}
ld_buff = kmalloc(reportlunsize, GFP_KERNEL);
if (ld_buff == NULL) {
printk(KERN_ERR "cciss: out of memory\n");
return;
}
memset(ld_buff, 0, sizeof(ReportLunData_struct));
inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
if (inq_buff == NULL) {
printk(KERN_ERR "cciss: out of memory\n");
kfree(ld_buff);
return;
}
/* Get the physical luns */
return_code = sendcmd(CISS_REPORT_PHYS, cntl_num, ld_buff,
reportlunsize, 0, 0, 0, NULL );
if( return_code == IO_OK) {
unsigned char *c = &ld_buff->LUNListLength[0];
listlength = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
}
else { /* getting report of physical luns failed */
printk(KERN_WARNING "cciss: report physical luns"
" command failed\n");
listlength = 0;
}
CPQ_TAPE_LOCK(cntl_num, flags);
ccissscsi[cntl_num].ndevices = 0; ccissscsi[cntl_num].ndevices = 0;
num_luns = listlength / 8; // 8 bytes pre entry shba = (struct cciss_scsi_adapter_data_t *)
/* printk("Found %d LUNs\n", num_luns); */ kmalloc(sizeof(*shba), GFP_KERNEL);
if (shba == NULL)
if (num_luns > CISS_MAX_PHYS_LUN) return;
{ shba->scsi_host = NULL;
printk(KERN_WARNING shba->lock = SPIN_LOCK_UNLOCKED;
"cciss: Maximum physical LUNs (%d) exceeded. " shba->registered = 0;
"%d LUNs ignored.\n", CISS_MAX_PHYS_LUN, if (scsi_cmd_stack_setup(cntl_num, shba) != 0) {
num_luns - CISS_MAX_PHYS_LUN); kfree(shba);
num_luns = CISS_MAX_PHYS_LUN; shba = NULL;
}
for(i=0; i<num_luns; i++) {
/* Execute an inquiry to figure the device type */
memset(inq_buff, 0, sizeof(InquiryData_struct));
memcpy(scsi3addr, ld_buff->LUN[i], 8); /* ugly... */
return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,
sizeof(InquiryData_struct), 2, 0 ,0, scsi3addr );
if (return_code == IO_OK) {
if(inq_buff->data_byte[8] == 0xFF)
{
printk(KERN_WARNING "cciss: inquiry failed\n");
} else {
int devtype;
/* printk("Inquiry...\n");
print_bytes((unsigned char *) inq_buff, 36, 1, 1); */
devtype = (inq_buff->data_byte[0] & 0x1f);
switch (devtype)
{
case 0x01: /* sequential access, (tape) */
case 0x08: /* medium changer */
/* this is the only kind of dev */
/* we want to expose here. */
if (cciss_scsi_add_entry(cntl_num, -1,
(unsigned char *) ld_buff->LUN[i],
devtype) != 0)
i=num_luns; // leave loop
break;
default:
break;
}
}
}
else printk("cciss: inquiry failed.\n");
} }
#if 0 hba[cntl_num]->scsi_ctlr = (void *) shba;
for (i=0;i<ccissscsi[cntl_num].ndevices;i++)
printk("Tape device presented at c%db%dt%dl%d\n",
cntl_num, // <-- this is wrong
ccissscsi[cntl_num].dev[i].bus,
ccissscsi[cntl_num].dev[i].target,
ccissscsi[cntl_num].dev[i].lun);
#endif
CPQ_TAPE_UNLOCK(cntl_num, flags);
kfree(ld_buff);
kfree(inq_buff);
return; return;
} }
...@@ -913,7 +811,7 @@ cciss_scsi_do_simple_cmd(ctlr_info_t *c, ...@@ -913,7 +811,7 @@ cciss_scsi_do_simple_cmd(ctlr_info_t *c,
memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB)); memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
memcpy(cp->Request.CDB, cdb, cdblen); memcpy(cp->Request.CDB, cdb, cdblen);
cp->Request.Timeout = 1000; // guarantee completion. cp->Request.Timeout = 0;
cp->Request.CDBLen = cdblen; cp->Request.CDBLen = cdblen;
cp->Request.Type.Type = TYPE_CMD; cp->Request.Type.Type = TYPE_CMD;
cp->Request.Type.Attribute = ATTR_SIMPLE; cp->Request.Type.Attribute = ATTR_SIMPLE;
...@@ -1208,6 +1106,12 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) ...@@ -1208,6 +1106,12 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
{ {
case 0x01: /* sequential access, (tape) */ case 0x01: /* sequential access, (tape) */
case 0x08: /* medium changer */ case 0x08: /* medium changer */
if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
printk(KERN_INFO "cciss%d: %s ignored, "
"too many devices.\n", cntl_num,
DEVICETYPE(devtype));
break;
}
memcpy(&currentsd[ncurrent].scsi3addr[0], memcpy(&currentsd[ncurrent].scsi3addr[0],
&scsi3addr[0], 8); &scsi3addr[0], 8);
currentsd[ncurrent].devtype = devtype; currentsd[ncurrent].devtype = devtype;
...@@ -1262,7 +1166,6 @@ cciss_scsi_proc_info(char *buffer, /* data buffer */ ...@@ -1262,7 +1166,6 @@ cciss_scsi_proc_info(char *buffer, /* data buffer */
int buflen, datalen; int buflen, datalen;
struct Scsi_Host *sh; struct Scsi_Host *sh;
int found;
ctlr_info_t *ci; ctlr_info_t *ci;
int cntl_num; int cntl_num;
...@@ -1382,8 +1285,8 @@ cciss_scsi_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) ...@@ -1382,8 +1285,8 @@ cciss_scsi_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
c = (ctlr_info_t **) &cmd->device->host->hostdata[0]; c = (ctlr_info_t **) &cmd->device->host->hostdata[0];
ctlr = (*c)->ctlr; ctlr = (*c)->ctlr;
rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id, cmd->device->lun, rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id,
scsi3addr); cmd->device->lun, scsi3addr);
if (rc != 0) { if (rc != 0) {
/* the scsi nexus does not match any that we presented... */ /* the scsi nexus does not match any that we presented... */
/* pretend to mid layer that we got selection timeout */ /* pretend to mid layer that we got selection timeout */
...@@ -1428,7 +1331,7 @@ cciss_scsi_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) ...@@ -1428,7 +1331,7 @@ cciss_scsi_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
// Fill in the request block... // Fill in the request block...
cp->Request.Timeout = 1000; // guarantee completion cp->Request.Timeout = 0;
memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB)); memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
if (cmd->cmd_len > sizeof(cp->Request.CDB)) BUG(); if (cmd->cmd_len > sizeof(cp->Request.CDB)) BUG();
cp->Request.CDBLen = cmd->cmd_len; cp->Request.CDBLen = cmd->cmd_len;
...@@ -1531,7 +1434,7 @@ cciss_unregister_scsi(int ctlr) ...@@ -1531,7 +1434,7 @@ cciss_unregister_scsi(int ctlr)
} }
static int static int
cciss_register_scsi(int ctlr, int this_is_init_time) cciss_register_scsi(int ctlr)
{ {
unsigned long flags; unsigned long flags;
...@@ -1541,15 +1444,10 @@ cciss_register_scsi(int ctlr, int this_is_init_time) ...@@ -1541,15 +1444,10 @@ cciss_register_scsi(int ctlr, int this_is_init_time)
driver_template[ctlr].module = THIS_MODULE;; driver_template[ctlr].module = THIS_MODULE;;
/* Since this is really a block driver, the SCSI core may not be /* Since this is really a block driver, the SCSI core may not be
initialized yet, in which case, calling scsi_register_host initialized at init time, in which case, calling scsi_register_host
would hang. instead, we will do it later, via /proc filesystem would hang. Instead, we do it later, via /proc filesystem
and rc scripts, when we know SCSI core is good to go. */ and rc scripts, when we know SCSI core is good to go. */
if (this_is_init_time) {
CPQ_TAPE_UNLOCK(ctlr, flags);
return 0;
}
/* Only register if SCSI devices are detected. */ /* Only register if SCSI devices are detected. */
if (ccissscsi[ctlr].ndevices != 0) { if (ccissscsi[ctlr].ndevices != 0) {
((struct cciss_scsi_adapter_data_t *) ((struct cciss_scsi_adapter_data_t *)
...@@ -1583,7 +1481,7 @@ cciss_engage_scsi(int ctlr) ...@@ -1583,7 +1481,7 @@ cciss_engage_scsi(int ctlr)
} }
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
cciss_update_non_disk_devices(ctlr, -1); cciss_update_non_disk_devices(ctlr, -1);
cciss_register_scsi(ctlr, 0); cciss_register_scsi(ctlr);
return 0; return 0;
} }
...@@ -1607,9 +1505,9 @@ cciss_proc_tape_report(int ctlr, unsigned char *buffer, off_t *pos, off_t *len) ...@@ -1607,9 +1505,9 @@ cciss_proc_tape_report(int ctlr, unsigned char *buffer, off_t *pos, off_t *len)
/* If no tape support, then these become defined out of existence */ /* If no tape support, then these become defined out of existence */
#define cciss_find_non_disk_devices(cntl_num) #define cciss_scsi_setup(cntl_num)
#define cciss_unregister_scsi(ctlr) #define cciss_unregister_scsi(ctlr)
#define cciss_register_scsi(ctlr, this_is_init_time) #define cciss_register_scsi(ctlr)
#define cciss_proc_tape_report(ctlr, buffer, pos, len) #define cciss_proc_tape_report(ctlr, buffer, pos, len)
#endif /* CONFIG_CISS_SCSI_TAPE */ #endif /* CONFIG_CISS_SCSI_TAPE */
...@@ -98,6 +98,8 @@ struct deadline_rq { ...@@ -98,6 +98,8 @@ struct deadline_rq {
unsigned long expires; unsigned long expires;
}; };
static inline void deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq);
static kmem_cache_t *drq_pool; static kmem_cache_t *drq_pool;
#define RQ_DATA(rq) ((struct deadline_rq *) (rq)->elevator_private) #define RQ_DATA(rq) ((struct deadline_rq *) (rq)->elevator_private)
...@@ -189,26 +191,22 @@ __deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) ...@@ -189,26 +191,22 @@ __deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
return 0; return 0;
} }
static int static void
deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
{ {
struct deadline_rq *__alias; struct deadline_rq *__alias;
drq->rb_key = rq_rb_key(drq->request); drq->rb_key = rq_rb_key(drq->request);
retry:
__alias = __deadline_add_drq_rb(dd, drq); __alias = __deadline_add_drq_rb(dd, drq);
if (!__alias) { if (!__alias) {
rb_insert_color(&drq->rb_node, DRQ_RB_ROOT(dd, drq)); rb_insert_color(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
return 0; return;
} }
/* deadline_move_to_dispatch(dd, __alias);
* this should not typically happen, but if it does simply chain goto retry;
* the two requests. then they will be moved to the dispatch list
* at the same time
*/
list_add(&drq->request->queuelist, &__alias->request->queuelist);
return 1;
} }
static inline void static inline void
...@@ -276,13 +274,12 @@ deadline_add_request(struct deadline_data *dd, struct deadline_rq *drq) ...@@ -276,13 +274,12 @@ deadline_add_request(struct deadline_data *dd, struct deadline_rq *drq)
{ {
const int data_dir = rq_data_dir(drq->request); const int data_dir = rq_data_dir(drq->request);
if (!deadline_add_drq_rb(dd, drq)) { deadline_add_drq_rb(dd, drq);
/* /*
* set expire time (only used for reads) and add to fifo list * set expire time (only used for reads) and add to fifo list
*/ */
drq->expires = jiffies + dd->fifo_expire[data_dir]; drq->expires = jiffies + dd->fifo_expire[data_dir];
list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]); list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]);
}
} }
/* /*
...@@ -425,6 +422,12 @@ deadline_merged_requests(request_queue_t *q, struct request *req, ...@@ -425,6 +422,12 @@ deadline_merged_requests(request_queue_t *q, struct request *req,
static inline void static inline void
deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq) deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq)
{ {
request_queue_t *q = drq->request->q;
if (q->last_merge == &drq->request->queuelist)
q->last_merge = NULL;
deadline_del_drq_hash(drq);
deadline_del_drq_rb(dd, drq); deadline_del_drq_rb(dd, drq);
list_del_init(&drq->fifo); list_del_init(&drq->fifo);
list_add_tail(&drq->request->queuelist, dd->dispatch); list_add_tail(&drq->request->queuelist, dd->dispatch);
......
...@@ -399,7 +399,7 @@ struct request *elv_former_request(request_queue_t *q, struct request *rq) ...@@ -399,7 +399,7 @@ struct request *elv_former_request(request_queue_t *q, struct request *rq)
elevator_t *e = &q->elevator; elevator_t *e = &q->elevator;
if (e->elevator_former_req_fn) if (e->elevator_former_req_fn)
return e->elevator_latter_req_fn(q, rq); return e->elevator_former_req_fn(q, rq);
prev = rq->queuelist.prev; prev = rq->queuelist.prev;
if (prev != &q->queue_head && prev != &rq->queuelist) if (prev != &q->queue_head && prev != &rq->queuelist)
......
...@@ -1358,11 +1358,19 @@ static struct request *get_request_wait(request_queue_t *q, int rw) ...@@ -1358,11 +1358,19 @@ static struct request *get_request_wait(request_queue_t *q, int rw)
generic_unplug_device(q); generic_unplug_device(q);
do { do {
int block = 0;
prepare_to_wait_exclusive(&rl->wait, &wait, prepare_to_wait_exclusive(&rl->wait, &wait,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
spin_lock_irq(q->queue_lock);
if (!rl->count) if (!rl->count)
block = 1;
spin_unlock_irq(q->queue_lock);
if (block)
io_schedule(); io_schedule();
finish_wait(&rl->wait, &wait); finish_wait(&rl->wait, &wait);
spin_lock_irq(q->queue_lock); spin_lock_irq(q->queue_lock);
rq = get_request(q, rw); rq = get_request(q, rw);
spin_unlock_irq(q->queue_lock); spin_unlock_irq(q->queue_lock);
...@@ -1596,12 +1604,8 @@ void blk_congestion_wait(int rw, long timeout) ...@@ -1596,12 +1604,8 @@ void blk_congestion_wait(int rw, long timeout)
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
struct congestion_state *cs = &congestion_states[rw]; struct congestion_state *cs = &congestion_states[rw];
if (!atomic_read(&cs->nr_active_queues))
return;
blk_run_queues(); blk_run_queues();
prepare_to_wait(&cs->wqh, &wait, TASK_UNINTERRUPTIBLE); prepare_to_wait(&cs->wqh, &wait, TASK_UNINTERRUPTIBLE);
if (atomic_read(&cs->nr_active_queues))
io_schedule_timeout(timeout); io_schedule_timeout(timeout);
finish_wait(&cs->wqh, &wait); finish_wait(&cs->wqh, &wait);
} }
......
...@@ -2233,6 +2233,23 @@ static int probe_si (struct sx_board *board) ...@@ -2233,6 +2233,23 @@ static int probe_si (struct sx_board *board)
return 0; return 0;
} }
/* Now we're pretty much convinced that there is an SI board here,
but to prevent trouble, we'd better double check that we don't
have an SI1 board when we're probing for an SI2 board.... */
write_sx_byte (board, SI2_ISA_ID_BASE,0x10);
if ( IS_SI1_BOARD(board)) {
/* This should be an SI1 board, which has this
location writable... */
if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10)
return 0;
} else {
/* This should be an SI2 board, which has the bottom
3 bits non-writable... */
if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10)
return 0;
}
printheader (); printheader ();
printk (KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base); printk (KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base);
......
...@@ -18,6 +18,8 @@ obj-$(CONFIG_IEEE1394_CMP) += cmp.o ...@@ -18,6 +18,8 @@ obj-$(CONFIG_IEEE1394_CMP) += cmp.o
clean-files := oui.c clean-files := oui.c
ieee1394.o: $(ieee1394-objs)
$(LD) $(LDFLAGS) -r -o $@ $(ieee1394-objs)
ifeq ($(obj),) ifeq ($(obj),)
obj = . obj = .
......
...@@ -598,6 +598,8 @@ static struct buffer *buffer_alloc(int size) ...@@ -598,6 +598,8 @@ static struct buffer *buffer_alloc(int size)
struct buffer *b; struct buffer *b;
b = kmalloc(sizeof *b + size, SLAB_KERNEL); b = kmalloc(sizeof *b + size, SLAB_KERNEL);
if (b == NULL)
return NULL;
b->head = 0; b->head = 0;
b->tail = 0; b->tail = 0;
b->length = 0; b->length = 0;
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
#ifndef __AMDTP_H #ifndef __AMDTP_H
#define __AMDTP_H #define __AMDTP_H
#include <asm/ioctl.h>
#include <asm/types.h> #include <asm/types.h>
#include "ieee1394-ioctl.h"
/* The userspace interface for the Audio & Music Data Transmission /* The userspace interface for the Audio & Music Data Transmission
* Protocol driver is really simple. First, open /dev/amdtp, use the * Protocol driver is really simple. First, open /dev/amdtp, use the
...@@ -57,13 +57,6 @@ ...@@ -57,13 +57,6 @@
* *
*/ */
/* We use '#' for our ioctl magic number because it's cool. */
#define AMDTP_IOC_CHANNEL _IOW('#', 0, sizeof (struct amdtp_ioctl))
#define AMDTP_IOC_PLUG _IOW('#', 1, sizeof (struct amdtp_ioctl))
#define AMDTP_IOC_PING _IOW('#', 2, sizeof (struct amdtp_ioctl))
#define AMDTP_IOC_ZAP _IO('#', 3)
enum { enum {
AMDTP_FORMAT_RAW, AMDTP_FORMAT_RAW,
AMDTP_FORMAT_IEC958_PCM, AMDTP_FORMAT_IEC958_PCM,
......
...@@ -25,8 +25,7 @@ void dma_prog_region_init(struct dma_prog_region *prog) ...@@ -25,8 +25,7 @@ void dma_prog_region_init(struct dma_prog_region *prog)
int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev) int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev)
{ {
/* round up to page size */ /* round up to page size */
if(n_bytes % PAGE_SIZE) n_bytes = round_up_to_page(n_bytes);
n_bytes += PAGE_SIZE - (n_bytes & PAGE_SIZE);
prog->n_pages = n_bytes / PAGE_SIZE; prog->n_pages = n_bytes / PAGE_SIZE;
...@@ -70,8 +69,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_d ...@@ -70,8 +69,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_d
unsigned int i, n_pages; unsigned int i, n_pages;
/* round up to page size */ /* round up to page size */
if(n_bytes % PAGE_SIZE) n_bytes = round_up_to_page(n_bytes);
n_bytes += PAGE_SIZE - (n_bytes & PAGE_SIZE);
n_pages = n_bytes / PAGE_SIZE; n_pages = n_bytes / PAGE_SIZE;
...@@ -210,7 +208,7 @@ dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int wri ...@@ -210,7 +208,7 @@ dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int wri
} }
static struct vm_operations_struct dma_region_vm_ops = { static struct vm_operations_struct dma_region_vm_ops = {
nopage: dma_region_pagefault, .nopage = dma_region_pagefault,
}; };
int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma) int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma)
......
...@@ -73,4 +73,12 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_s ...@@ -73,4 +73,12 @@ int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_s
relative to the beginning of the dma_region */ relative to the beginning of the dma_region */
dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset); dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset);
/* round up a number of bytes to be a multiple of the PAGE_SIZE */
static inline unsigned long round_up_to_page(unsigned long len)
{
if(len % PAGE_SIZE)
len += PAGE_SIZE - (len % PAGE_SIZE);
return len;
}
#endif /* IEEE1394_DMA_H */ #endif /* IEEE1394_DMA_H */
...@@ -918,6 +918,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init) ...@@ -918,6 +918,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
u64 chan_mask; u64 chan_mask;
int retval = -EINVAL; int retval = -EINVAL;
debug_printk( "dv1394: initialising %d\n", video->id );
if(init->api_version != DV1394_API_VERSION) if(init->api_version != DV1394_API_VERSION)
goto err; goto err;
...@@ -1186,6 +1187,7 @@ static void stop_dma(struct video_card *video) ...@@ -1186,6 +1187,7 @@ static void stop_dma(struct video_card *video)
if( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) || if( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) ||
(reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) { (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) {
/* still active */ /* still active */
debug_printk("dv1394: stop_dma: DMA not stopped yet\n" );
mb(); mb();
} else { } else {
debug_printk("dv1394: stop_dma: DMA stopped safely after %d ms\n", i/10); debug_printk("dv1394: stop_dma: DMA stopped safely after %d ms\n", i/10);
...@@ -1199,6 +1201,8 @@ static void stop_dma(struct video_card *video) ...@@ -1199,6 +1201,8 @@ static void stop_dma(struct video_card *video)
printk(KERN_ERR "dv1394: stop_dma: DMA still going after %d ms!\n", i/10); printk(KERN_ERR "dv1394: stop_dma: DMA still going after %d ms!\n", i/10);
} }
} }
else
debug_printk("dv1394: stop_dma: already stopped.\n");
spin_unlock_irqrestore(&video->spinlock, flags); spin_unlock_irqrestore(&video->spinlock, flags);
} }
...@@ -1226,7 +1230,8 @@ static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf) ...@@ -1226,7 +1230,8 @@ static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf)
/* disable interrupts for IT context */ /* disable interrupts for IT context */
reg_write(video->ohci, OHCI1394_IsoXmitIntMaskClear, (1 << video->ohci_it_ctx)); reg_write(video->ohci, OHCI1394_IsoXmitIntMaskClear, (1 << video->ohci_it_ctx));
clear_bit(video->ohci_it_ctx, &video->ohci->it_ctx_usage); /* remove tasklet */
ohci1394_unregister_iso_tasklet(video->ohci, &video->it_tasklet);
debug_printk("dv1394: IT context %d released\n", video->ohci_it_ctx); debug_printk("dv1394: IT context %d released\n", video->ohci_it_ctx);
video->ohci_it_ctx = -1; video->ohci_it_ctx = -1;
} }
...@@ -1240,23 +1245,14 @@ static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf) ...@@ -1240,23 +1245,14 @@ static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf)
/* disable interrupts for IR context */ /* disable interrupts for IR context */
reg_write(video->ohci, OHCI1394_IsoRecvIntMaskClear, (1 << video->ohci_ir_ctx)); reg_write(video->ohci, OHCI1394_IsoRecvIntMaskClear, (1 << video->ohci_ir_ctx));
clear_bit(video->ohci_ir_ctx, &video->ohci->ir_ctx_usage); /* remove tasklet */
ohci1394_unregister_iso_tasklet(video->ohci, &video->ir_tasklet);
debug_printk("dv1394: IR context %d released\n", video->ohci_ir_ctx); debug_printk("dv1394: IR context %d released\n", video->ohci_ir_ctx);
video->ohci_ir_ctx = -1; video->ohci_ir_ctx = -1;
} }
spin_unlock_irqrestore(&video->spinlock, flags); spin_unlock_irqrestore(&video->spinlock, flags);
/* remove tasklets */
if(video->ohci_it_ctx != -1) {
ohci1394_unregister_iso_tasklet(video->ohci, &video->it_tasklet);
video->ohci_it_ctx = -1;
}
if(video->ohci_ir_ctx != -1) {
ohci1394_unregister_iso_tasklet(video->ohci, &video->ir_tasklet);
video->ohci_ir_ctx = -1;
}
/* release the ISO channel */ /* release the ISO channel */
if(video->channel != -1) { if(video->channel != -1) {
u64 chan_mask; u64 chan_mask;
...@@ -1612,7 +1608,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1612,7 +1608,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
switch(cmd) switch(cmd)
{ {
case DV1394_SUBMIT_FRAMES: { case DV1394_IOC_SUBMIT_FRAMES: {
unsigned int n_submit; unsigned int n_submit;
if( !video_card_initialized(video) ) { if( !video_card_initialized(video) ) {
...@@ -1666,7 +1662,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1666,7 +1662,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
break; break;
} }
case DV1394_WAIT_FRAMES: { case DV1394_IOC_WAIT_FRAMES: {
unsigned int n_wait; unsigned int n_wait;
if( !video_card_initialized(video) ) { if( !video_card_initialized(video) ) {
...@@ -1715,7 +1711,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1715,7 +1711,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
break; break;
} }
case DV1394_RECEIVE_FRAMES: { case DV1394_IOC_RECEIVE_FRAMES: {
unsigned int n_recv; unsigned int n_recv;
if( !video_card_initialized(video) ) { if( !video_card_initialized(video) ) {
...@@ -1748,7 +1744,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1748,7 +1744,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
break; break;
} }
case DV1394_START_RECEIVE: { case DV1394_IOC_START_RECEIVE: {
if( !video_card_initialized(video) ) { if( !video_card_initialized(video) ) {
ret = do_dv1394_init_default(video); ret = do_dv1394_init_default(video);
if(ret) if(ret)
...@@ -1765,7 +1761,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1765,7 +1761,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
break; break;
} }
case DV1394_INIT: { case DV1394_IOC_INIT: {
struct dv1394_init init; struct dv1394_init init;
if(arg == (unsigned long) NULL) { if(arg == (unsigned long) NULL) {
ret = do_dv1394_init_default(video); ret = do_dv1394_init_default(video);
...@@ -1779,12 +1775,12 @@ static int dv1394_ioctl(struct inode *inode, struct file *file, ...@@ -1779,12 +1775,12 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
break; break;
} }
case DV1394_SHUTDOWN: case DV1394_IOC_SHUTDOWN:
ret = do_dv1394_shutdown(video, 0); ret = do_dv1394_shutdown(video, 0);
break; break;
case DV1394_GET_STATUS: { case DV1394_IOC_GET_STATUS: {
struct dv1394_status status; struct dv1394_status status;
if( !video_card_initialized(video) ) { if( !video_card_initialized(video) ) {
...@@ -2346,6 +2342,7 @@ static void ir_tasklet_func(unsigned long data) ...@@ -2346,6 +2342,7 @@ static void ir_tasklet_func(unsigned long data)
dbc = (int) (p->cip_h1 >> 24); dbc = (int) (p->cip_h1 >> 24);
if ( video->continuity_counter != -1 && dbc > ((video->continuity_counter + 1) % 256) ) if ( video->continuity_counter != -1 && dbc > ((video->continuity_counter + 1) % 256) )
{ {
printk(KERN_WARNING "dv1394: discontinuity detected, dropping all frames\n" );
video->dropped_frames += video->n_clear_frames + 1; video->dropped_frames += video->n_clear_frames + 1;
video->first_frame = 0; video->first_frame = 0;
video->n_clear_frames = 0; video->n_clear_frames = 0;
...@@ -2364,9 +2361,8 @@ static void ir_tasklet_func(unsigned long data) ...@@ -2364,9 +2361,8 @@ static void ir_tasklet_func(unsigned long data)
video->n_clear_frames++; video->n_clear_frames++;
if (video->n_clear_frames > video->n_frames) { if (video->n_clear_frames > video->n_frames) {
video->dropped_frames++; video->dropped_frames++;
video->n_clear_frames--; printk(KERN_WARNING "dv1394: dropped a frame during reception\n" );
if (video->n_clear_frames < 0) video->n_clear_frames = video->n_frames-1;
video->n_clear_frames = 0;
video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames; video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames;
} }
if (video->first_clear_frame == -1) if (video->first_clear_frame == -1)
...@@ -2375,7 +2371,6 @@ static void ir_tasklet_func(unsigned long data) ...@@ -2375,7 +2371,6 @@ static void ir_tasklet_func(unsigned long data)
/* get the next frame */ /* get the next frame */
video->active_frame = (video->active_frame + 1) % video->n_frames; video->active_frame = (video->active_frame + 1) % video->n_frames;
f = video->frames[video->active_frame]; f = video->frames[video->active_frame];
irq_printk(" frame received, active_frame = %d, n_clear_frames = %d, first_clear_frame = %d\n", irq_printk(" frame received, active_frame = %d, n_clear_frames = %d, first_clear_frame = %d\n",
video->active_frame, video->n_clear_frames, video->first_clear_frame); video->active_frame, video->n_clear_frames, video->first_clear_frame);
} }
......
...@@ -200,48 +200,7 @@ ...@@ -200,48 +200,7 @@
/* ioctl() commands */ /* ioctl() commands */
#include "ieee1394-ioctl.h"
enum {
/* I don't like using 0 as a valid ioctl() */
DV1394_INVALID = 0,
/* get the driver ready to transmit video.
pass a struct dv1394_init* as the parameter (see below),
or NULL to get default parameters */
DV1394_INIT,
/* stop transmitting video and free the ringbuffer */
DV1394_SHUTDOWN,
/* submit N new frames to be transmitted, where
the index of the first new frame is first_clear_buffer,
and the index of the last new frame is
(first_clear_buffer + N) % n_frames */
DV1394_SUBMIT_FRAMES,
/* block until N buffers are clear (pass N as the parameter)
Because we re-transmit the last frame on underrun, there
will at most be n_frames - 1 clear frames at any time */
DV1394_WAIT_FRAMES,
/* capture new frames that have been received, where
the index of the first new frame is first_clear_buffer,
and the index of the last new frame is
(first_clear_buffer + N) % n_frames */
DV1394_RECEIVE_FRAMES,
DV1394_START_RECEIVE,
/* pass a struct dv1394_status* as the parameter (see below) */
DV1394_GET_STATUS,
};
enum pal_or_ntsc { enum pal_or_ntsc {
......
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
printk(KERN_ERR fmt, ## args) printk(KERN_ERR fmt, ## args)
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 641 $ Ben Collins <bcollins@debian.org>"; "$Rev: 770 $ Ben Collins <bcollins@debian.org>";
/* Our ieee1394 highlevel driver */ /* Our ieee1394 highlevel driver */
#define ETHER1394_DRIVER_NAME "ether1394" #define ETHER1394_DRIVER_NAME "ether1394"
...@@ -368,6 +368,7 @@ static void ether1394_add_host (struct hpsb_host *host) ...@@ -368,6 +368,7 @@ static void ether1394_add_host (struct hpsb_host *host)
if (register_netdev (dev)) { if (register_netdev (dev)) {
ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n"); ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n");
kfree (dev); kfree (dev);
kfree (hi);
return; return;
} }
......
...@@ -164,17 +164,19 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start) ...@@ -164,17 +164,19 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start)
return retval; return retval;
} }
void hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
unsigned int channel) unsigned int channel)
{ {
if (channel > 63) { if (channel > 63) {
HPSB_ERR("%s called with invalid channel", __FUNCTION__); HPSB_ERR("%s called with invalid channel", __FUNCTION__);
return; return -EINVAL;
} }
if (host->iso_listen_count[channel]++ == 0) { if (host->iso_listen_count[channel]++ == 0) {
host->driver->devctl(host, ISO_LISTEN_CHANNEL, channel); return host->driver->devctl(host, ISO_LISTEN_CHANNEL, channel);
} }
return 0;
} }
void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
......
...@@ -150,7 +150,7 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start); ...@@ -150,7 +150,7 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start);
* Enable or disable receving a certain isochronous channel through the * Enable or disable receving a certain isochronous channel through the
* iso_receive op. * iso_receive op.
*/ */
void hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
unsigned int channel); unsigned int channel);
void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
unsigned int channel); unsigned int channel);
......
...@@ -38,9 +38,15 @@ static int dummy_devctl(struct hpsb_host *h, enum devctl_cmd c, int arg) ...@@ -38,9 +38,15 @@ static int dummy_devctl(struct hpsb_host *h, enum devctl_cmd c, int arg)
return -1; return -1;
} }
static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg)
{
return -1;
}
static struct hpsb_host_driver dummy_driver = { static struct hpsb_host_driver dummy_driver = {
.transmit_packet = dummy_transmit_packet, .transmit_packet = dummy_transmit_packet,
.devctl = dummy_devctl .devctl = dummy_devctl,
.isoctl = dummy_isoctl
}; };
/** /**
...@@ -63,9 +69,11 @@ int hpsb_ref_host(struct hpsb_host *host) ...@@ -63,9 +69,11 @@ int hpsb_ref_host(struct hpsb_host *host)
spin_lock_irqsave(&hosts_lock, flags); spin_lock_irqsave(&hosts_lock, flags);
list_for_each(lh, &hosts) { list_for_each(lh, &hosts) {
if (host == list_entry(lh, struct hpsb_host, host_list)) { if (host == list_entry(lh, struct hpsb_host, host_list)) {
if (host->driver->devctl(host, MODIFY_USAGE, 1)) {
host->driver->devctl(host, MODIFY_USAGE, 1); host->driver->devctl(host, MODIFY_USAGE, 1);
host->refcount++; host->refcount++;
retval = 1; retval = 1;
}
break; break;
} }
} }
......
...@@ -108,9 +108,9 @@ enum devctl_cmd { ...@@ -108,9 +108,9 @@ enum devctl_cmd {
enum isoctl_cmd { enum isoctl_cmd {
/* rawiso API - see iso.h for the meanings of these commands /* rawiso API - see iso.h for the meanings of these commands
* INIT = allocate resources * INIT = allocate resources
* START = begin transmission/reception (arg: cycle to start on) * START = begin transmission/reception
* STOP = halt transmission/reception * STOP = halt transmission/reception
* QUEUE/RELEASE = produce/consume packets (arg: # of packets) * QUEUE/RELEASE = produce/consume packets
* SHUTDOWN = deallocate resources * SHUTDOWN = deallocate resources
*/ */
...@@ -121,6 +121,9 @@ enum isoctl_cmd { ...@@ -121,6 +121,9 @@ enum isoctl_cmd {
XMIT_SHUTDOWN, XMIT_SHUTDOWN,
RECV_INIT, RECV_INIT,
RECV_LISTEN_CHANNEL, /* multi-channel only */
RECV_UNLISTEN_CHANNEL, /* multi-channel only */
RECV_SET_CHANNEL_MASK, /* multi-channel only; arg is a *u64 */
RECV_START, RECV_START,
RECV_STOP, RECV_STOP,
RECV_RELEASE, RECV_RELEASE,
...@@ -170,10 +173,11 @@ struct hpsb_host_driver { ...@@ -170,10 +173,11 @@ struct hpsb_host_driver {
*/ */
int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg); int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg);
/* ISO transmission/reception functions. Return 0 on success, -1 on failure. /* ISO transmission/reception functions. Return 0 on success, -1
* If the low-level driver does not support the new ISO API, set isoctl to NULL. * (or -EXXX errno code) on failure. If the low-level driver does not
* support the new ISO API, set isoctl to NULL.
*/ */
int (*isoctl) (struct hpsb_iso *iso, enum isoctl_cmd command, int arg); int (*isoctl) (struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg);
/* This function is mainly to redirect local CSR reads/locks to the iso /* This function is mainly to redirect local CSR reads/locks to the iso
* management registers (bus manager id, bandwidth available, channels * management registers (bus manager id, bandwidth available, channels
......
/* Base file for all ieee1394 ioctl's. Linux-1394 has allocated base '#'
* with a range of 0x00-0x3f. */
#ifndef __IEEE1394_IOCTL_H
#define __IEEE1394_IOCTL_H
#include <asm/ioctl.h>
#include <asm/types.h>
/* AMDTP Gets 6 */
#define AMDTP_IOC_CHANNEL _IOW('#', 0x00, struct amdtp_ioctl)
#define AMDTP_IOC_PLUG _IOW('#', 0x01, struct amdtp_ioctl)
#define AMDTP_IOC_PING _IOW('#', 0x02, struct amdtp_ioctl)
#define AMDTP_IOC_ZAP _IO ('#', 0x03)
/* DV1394 Gets 10 */
/* Get the driver ready to transmit video. pass a struct dv1394_init* as
* the parameter (see below), or NULL to get default parameters */
#define DV1394_IOC_INIT _IOW('#', 0x06, struct dv1394_init)
/* Stop transmitting video and free the ringbuffer */
#define DV1394_IOC_SHUTDOWN _IO ('#', 0x07)
/* Submit N new frames to be transmitted, where the index of the first new
* frame is first_clear_buffer, and the index of the last new frame is
* (first_clear_buffer + N) % n_frames */
#define DV1394_IOC_SUBMIT_FRAMES _IO ('#', 0x08)
/* Block until N buffers are clear (pass N as the parameter) Because we
* re-transmit the last frame on underrun, there will at most be n_frames
* - 1 clear frames at any time */
#define DV1394_IOC_WAIT_FRAMES _IO ('#', 0x09)
/* Capture new frames that have been received, where the index of the
* first new frame is first_clear_buffer, and the index of the last new
* frame is (first_clear_buffer + N) % n_frames */
#define DV1394_IOC_RECEIVE_FRAMES _IO ('#', 0x0a)
/* Tell card to start receiving DMA */
#define DV1394_IOC_START_RECEIVE _IO ('#', 0x0b)
/* Pass a struct dv1394_status* as the parameter */
#define DV1394_IOC_GET_STATUS _IOR('#', 0x0c, struct dv1394_status)
/* Video1394 Gets 10 */
#define VIDEO1394_IOC_LISTEN_CHANNEL \
_IOWR('#', 0x10, struct video1394_mmap)
#define VIDEO1394_IOC_UNLISTEN_CHANNEL \
_IOW ('#', 0x11, int)
#define VIDEO1394_IOC_LISTEN_QUEUE_BUFFER \
_IOW ('#', 0x12, struct video1394_wait)
#define VIDEO1394_IOC_LISTEN_WAIT_BUFFER \
_IOWR('#', 0x13, struct video1394_wait)
#define VIDEO1394_IOC_TALK_CHANNEL \
_IOWR('#', 0x14, struct video1394_mmap)
#define VIDEO1394_IOC_UNTALK_CHANNEL \
_IOW ('#', 0x15, int)
#define VIDEO1394_IOC_TALK_QUEUE_BUFFER \
_IOW ('#', 0x16, sizeof (struct video1394_wait) + \
sizeof (struct video1394_queue_variable))
#define VIDEO1394_IOC_TALK_WAIT_BUFFER \
_IOW ('#', 0x17, struct video1394_wait)
#define VIDEO1394_IOC_LISTEN_POLL_BUFFER \
_IOWR('#', 0x18, struct video1394_wait)
/* Raw1394's ISO interface */
#define RAW1394_IOC_ISO_XMIT_INIT \
_IOW ('#', 0x1a, struct raw1394_iso_status)
#define RAW1394_IOC_ISO_RECV_INIT \
_IOWR('#', 0x1b, struct raw1394_iso_status)
#define RAW1394_IOC_ISO_RECV_START \
_IOC (_IOC_WRITE, '#', 0x1c, sizeof(int) * 3)
#define RAW1394_IOC_ISO_XMIT_START \
_IOC (_IOC_WRITE, '#', 0x1d, sizeof(int) * 2)
#define RAW1394_IOC_ISO_XMIT_RECV_STOP \
_IO ('#', 0x1e)
#define RAW1394_IOC_ISO_GET_STATUS \
_IOR ('#', 0x1f, struct raw1394_iso_status)
#define RAW1394_IOC_ISO_SHUTDOWN \
_IO ('#', 0x20)
#define RAW1394_IOC_ISO_QUEUE_ACTIVITY \
_IO ('#', 0x21)
#define RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL \
_IOW ('#', 0x22, unsigned char)
#define RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL \
_IOW ('#', 0x23, unsigned char)
#define RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK \
_IOW ('#', 0x24, u64)
#define RAW1394_IOC_ISO_RECV_PACKETS \
_IOW ('#', 0x25, struct raw1394_iso_packets)
#define RAW1394_IOC_ISO_RECV_RELEASE_PACKETS \
_IOW ('#', 0x26, unsigned int)
#define RAW1394_IOC_ISO_XMIT_PACKETS \
_IOW ('#', 0x27, struct raw1394_iso_packets)
#define RAW1394_IOC_ISO_XMIT_SYNC \
_IO ('#', 0x28)
#endif /* __IEEE1394_IOCTL_H */
...@@ -1055,7 +1055,7 @@ static int ieee1394_get_chardev(int blocknum, ...@@ -1055,7 +1055,7 @@ static int ieee1394_get_chardev(int blocknum,
{ {
int ret = 0; int ret = 0;
if( (blocknum < 0) || (blocknum > 15) ) if ((blocknum < 0) || (blocknum > 15))
return ret; return ret;
read_lock(&ieee1394_chardevs_lock); read_lock(&ieee1394_chardevs_lock);
...@@ -1063,10 +1063,10 @@ static int ieee1394_get_chardev(int blocknum, ...@@ -1063,10 +1063,10 @@ static int ieee1394_get_chardev(int blocknum,
*module = ieee1394_chardevs[blocknum].module; *module = ieee1394_chardevs[blocknum].module;
*file_ops = ieee1394_chardevs[blocknum].file_ops; *file_ops = ieee1394_chardevs[blocknum].file_ops;
if(*file_ops == NULL) if (*file_ops == NULL)
goto out; goto out;
if(!try_module_get(*module)) if (!try_module_get(*module))
goto out; goto out;
/* success! */ /* success! */
...@@ -1126,14 +1126,14 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file) ...@@ -1126,14 +1126,14 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
if(retval == 0) { if(retval == 0) {
/* If the open() succeeded, then ieee1394 will be left /* If the open() succeeded, then ieee1394 will be left
with an extra module reference, so we discard it here. * with an extra module reference, so we discard it here.
*
* The task-specific driver still has the extra reference
* given to it by ieee1394_get_chardev(). This extra
* reference prevents the module from unloading while the
* file is open, and will be dropped by the VFS when the
* file is released. */
The task-specific driver still has the extra
reference given to it by ieee1394_get_chardev().
This extra reference prevents the module from
unloading while the file is open, and will be
dropped by the VFS when the file is released.
*/
module_put(THIS_MODULE); module_put(THIS_MODULE);
} else { } else {
/* point the file's f_ops back to ieee1394. The VFS will then /* point the file's f_ops back to ieee1394. The VFS will then
...@@ -1142,11 +1142,10 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file) ...@@ -1142,11 +1142,10 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
file->f_op = &ieee1394_chardev_ops; file->f_op = &ieee1394_chardev_ops;
/* if the open() failed, then we need to drop the /* If the open() failed, then we need to drop the extra
extra reference we gave to the task-specific * reference we gave to the task-specific driver. */
driver */
module_put(module);
module_put(module);
} }
return retval; return retval;
...@@ -1298,10 +1297,16 @@ EXPORT_SYMBOL(hpsb_iso_xmit_init); ...@@ -1298,10 +1297,16 @@ EXPORT_SYMBOL(hpsb_iso_xmit_init);
EXPORT_SYMBOL(hpsb_iso_recv_init); EXPORT_SYMBOL(hpsb_iso_recv_init);
EXPORT_SYMBOL(hpsb_iso_xmit_start); EXPORT_SYMBOL(hpsb_iso_xmit_start);
EXPORT_SYMBOL(hpsb_iso_recv_start); EXPORT_SYMBOL(hpsb_iso_recv_start);
EXPORT_SYMBOL(hpsb_iso_recv_listen_channel);
EXPORT_SYMBOL(hpsb_iso_recv_unlisten_channel);
EXPORT_SYMBOL(hpsb_iso_recv_set_channel_mask);
EXPORT_SYMBOL(hpsb_iso_stop); EXPORT_SYMBOL(hpsb_iso_stop);
EXPORT_SYMBOL(hpsb_iso_shutdown); EXPORT_SYMBOL(hpsb_iso_shutdown);
EXPORT_SYMBOL(hpsb_iso_xmit_queue_packets); EXPORT_SYMBOL(hpsb_iso_xmit_queue_packet);
EXPORT_SYMBOL(hpsb_iso_xmit_sync);
EXPORT_SYMBOL(hpsb_iso_recv_release_packets); EXPORT_SYMBOL(hpsb_iso_recv_release_packets);
EXPORT_SYMBOL(hpsb_iso_n_ready); EXPORT_SYMBOL(hpsb_iso_n_ready);
EXPORT_SYMBOL(hpsb_iso_packet_data); EXPORT_SYMBOL(hpsb_iso_packet_sent);
EXPORT_SYMBOL(hpsb_iso_packet_info); EXPORT_SYMBOL(hpsb_iso_packet_received);
EXPORT_SYMBOL(hpsb_iso_wake);
This diff is collapsed.
...@@ -17,25 +17,37 @@ ...@@ -17,25 +17,37 @@
/* high-level ISO interface */ /* high-level ISO interface */
/* per-packet data embedded in the ringbuffer */ /* This API sends and receives isochronous packets on a large,
virtually-contiguous kernel memory buffer. The buffer may be mapped
into a user-space process for zero-copy transmission and reception.
There are no explicit boundaries between packets in the buffer. A
packet may be transmitted or received at any location. However,
low-level drivers may impose certain restrictions on alignment or
size of packets. (e.g. in OHCI no packet may cross a page boundary,
and packets should be quadlet-aligned)
*/
/* Packet descriptor - the API maintains a ring buffer of these packet
descriptors in kernel memory (hpsb_iso.infos[]). */
struct hpsb_iso_packet_info { struct hpsb_iso_packet_info {
unsigned short len; /* offset of data payload relative to the first byte of the buffer */
unsigned short cycle; __u32 offset;
unsigned char channel; /* recv only */
unsigned char tag;
unsigned char sy;
};
/* /* length of the data payload, in bytes (not including the isochronous header) */
* each packet in the ringbuffer consists of three things: __u16 len;
* 1. the packet's data payload (no isochronous header)
* 2. a struct hpsb_iso_packet_info /* (recv only) the cycle number (mod 8000) on which the packet was received */
* 3. some empty space before the next packet __u16 cycle;
*
* packets are separated by hpsb_iso.buf_stride bytes /* (recv only) channel on which the packet was received */
* an even number of packets fit on one page __u8 channel;
* no packet can be larger than one page
*/ /* 2-bit 'tag' and 4-bit 'sy' fields of the isochronous header */
__u8 tag;
__u8 sy;
};
enum hpsb_iso_type { HPSB_ISO_RECV = 0, HPSB_ISO_XMIT = 1 }; enum hpsb_iso_type { HPSB_ISO_RECV = 0, HPSB_ISO_XMIT = 1 };
...@@ -46,47 +58,48 @@ struct hpsb_iso { ...@@ -46,47 +58,48 @@ struct hpsb_iso {
struct hpsb_host *host; struct hpsb_host *host;
void *hostdata; void *hostdata;
/* function to be called (from interrupt context) when the iso status changes */ /* a function to be called (from interrupt context) after
outgoing packets have been sent, or incoming packets have
arrived */
void (*callback)(struct hpsb_iso*); void (*callback)(struct hpsb_iso*);
/* wait for buffer space */
wait_queue_head_t waitq;
int speed; /* SPEED_100, 200, or 400 */ int speed; /* SPEED_100, 200, or 400 */
int channel; int channel; /* -1 if multichannel */
/* greatest # of packets between interrupts - controls /* greatest # of packets between interrupts - controls
the maximum latency of the buffer */ the maximum latency of the buffer */
int irq_interval; int irq_interval;
/* the packet ringbuffer */ /* the buffer for packet data payloads */
struct dma_region buf; struct dma_region data_buf;
/* # of packets in the ringbuffer */ /* size of data_buf, in bytes (always a multiple of PAGE_SIZE) */
unsigned int buf_packets; unsigned int buf_size;
/* offset between successive packets, in bytes -
you can assume that this is a power of 2,
and less than or equal to the page size */
int buf_stride;
/* largest possible packet size, in bytes */ /* ringbuffer of packet descriptors in regular kernel memory */
unsigned int max_packet_size; struct hpsb_iso_packet_info *infos;
/* offset relative to (buf.kvirt + N*buf_stride) at which /* # of packets in the ringbuffer */
the data payload begins for packet N */ unsigned int buf_packets;
int packet_data_offset;
/* offset relative to (buf.kvirt + N*buf_stride) at which the /* protects packet cursors */
struct hpsb_iso_packet_info is stored for packet N */ spinlock_t lock;
int packet_info_offset;
/* the index of the next packet that will be produced /* the index of the next packet that will be produced
or consumed by the user */ or consumed by the user */
int first_packet; int first_packet;
/* number of packets owned by the low-level driver and /* the index of the next packet that will be transmitted
queued for transmission or reception. or received by the 1394 hardware */
this is related to the number of packets available int pkt_dma;
to the user process: n_ready = buf_packets - n_dma_packets */
atomic_t n_dma_packets; /* how many packets, starting at first_packet:
(transmit) are ready to be filled with data
(receive) contain received data */
int n_ready_packets;
/* how many times the buffer has overflowed or underflowed */ /* how many times the buffer has overflowed or underflowed */
atomic_t overflows; atomic_t overflows;
...@@ -99,8 +112,12 @@ struct hpsb_iso { ...@@ -99,8 +112,12 @@ struct hpsb_iso {
/* # of packets left to prebuffer (xmit only) */ /* # of packets left to prebuffer (xmit only) */
int prebuffer; int prebuffer;
/* starting cycle (xmit only) */ /* starting cycle for DMA (xmit only) */
int start_cycle; int start_cycle;
/* cycle at which next packet will be transmitted,
-1 if not known */
int xmit_cycle;
}; };
/* functions available to high-level drivers (e.g. raw1394) */ /* functions available to high-level drivers (e.g. raw1394) */
...@@ -108,30 +125,40 @@ struct hpsb_iso { ...@@ -108,30 +125,40 @@ struct hpsb_iso {
/* allocate the buffer and DMA context */ /* allocate the buffer and DMA context */
struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host, struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host,
unsigned int data_buf_size,
unsigned int buf_packets, unsigned int buf_packets,
unsigned int max_packet_size,
int channel, int channel,
int speed, int speed,
int irq_interval, int irq_interval,
void (*callback)(struct hpsb_iso*)); void (*callback)(struct hpsb_iso*));
/* note: if channel = -1, multi-channel receive is enabled */
struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host, struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
unsigned int data_buf_size,
unsigned int buf_packets, unsigned int buf_packets,
unsigned int max_packet_size,
int channel, int channel,
int irq_interval, int irq_interval,
void (*callback)(struct hpsb_iso*)); void (*callback)(struct hpsb_iso*));
/* multi-channel only */
int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel);
int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel);
int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask);
/* start/stop DMA */ /* start/stop DMA */
int hpsb_iso_xmit_start(struct hpsb_iso *iso, int start_on_cycle, int prebuffer); int hpsb_iso_xmit_start(struct hpsb_iso *iso, int start_on_cycle, int prebuffer);
int hpsb_iso_recv_start(struct hpsb_iso *iso, int start_on_cycle); int hpsb_iso_recv_start(struct hpsb_iso *iso, int start_on_cycle, int tag_mask, int sync);
void hpsb_iso_stop(struct hpsb_iso *iso); void hpsb_iso_stop(struct hpsb_iso *iso);
/* deallocate buffer and DMA context */ /* deallocate buffer and DMA context */
void hpsb_iso_shutdown(struct hpsb_iso *iso); void hpsb_iso_shutdown(struct hpsb_iso *iso);
/* N packets have been written to the buffer; queue them for transmission */ /* queue a packet for transmission. 'offset' is relative to the beginning of the
int hpsb_iso_xmit_queue_packets(struct hpsb_iso *xmit, unsigned int n_packets); DMA buffer, where the packet's data payload should already have been placed */
int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag, u8 sy);
/* wait until all queued packets have been transmitted to the bus */
int hpsb_iso_xmit_sync(struct hpsb_iso *iso);
/* N packets have been read out of the buffer, re-use the buffer space */ /* N packets have been read out of the buffer, re-use the buffer space */
int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets); int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets);
...@@ -139,10 +166,19 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets ...@@ -139,10 +166,19 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets
/* returns # of packets ready to send or receive */ /* returns # of packets ready to send or receive */
int hpsb_iso_n_ready(struct hpsb_iso *iso); int hpsb_iso_n_ready(struct hpsb_iso *iso);
/* returns a pointer to the payload of packet 'pkt' */ /* the following are callbacks available to low-level drivers */
unsigned char* hpsb_iso_packet_data(struct hpsb_iso *iso, unsigned int pkt);
/* call after a packet has been transmitted to the bus (interrupt context is OK)
'cycle' is the _exact_ cycle the packet was sent on
'error' should be non-zero if some sort of error occurred when sending the packet
*/
void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error);
/* call after a packet has been received (interrupt context OK) */
void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
u16 cycle, u8 channel, u8 tag, u8 sy);
/* returns a pointer to the info struct of packet 'pkt' */ /* call to wake waiting processes after buffer space has opened up. */
struct hpsb_iso_packet_info* hpsb_iso_packet_info(struct hpsb_iso *iso, unsigned int pkt); void hpsb_iso_wake(struct hpsb_iso *iso);
#endif /* IEEE1394_ISO_H */ #endif /* IEEE1394_ISO_H */
...@@ -1089,8 +1089,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned ...@@ -1089,8 +1089,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned
static void nodemgr_remove_node(struct node_entry *ne) static void nodemgr_remove_node(struct node_entry *ne)
{ {
HPSB_DEBUG("%s removed: Node[" NODE_BUS_FMT "] GUID[%016Lx] [%s]", HPSB_DEBUG("Device removed: Node[" NODE_BUS_FMT "] GUID[%016Lx] [%s]",
(ne->host->node_id == ne->nodeid) ? "Host" : "Device",
NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid, NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid,
ne->vendor_name ?: "Unknown"); ne->vendor_name ?: "Unknown");
......
This diff is collapsed.
...@@ -109,6 +109,7 @@ struct dma_rcv_ctx { ...@@ -109,6 +109,7 @@ struct dma_rcv_ctx {
int ctrlClear; int ctrlClear;
int ctrlSet; int ctrlSet;
int cmdPtr; int cmdPtr;
int ctxtMatch;
}; };
/* DMA transmit context */ /* DMA transmit context */
...@@ -145,7 +146,8 @@ struct ohci1394_iso_tasklet { ...@@ -145,7 +146,8 @@ struct ohci1394_iso_tasklet {
struct tasklet_struct tasklet; struct tasklet_struct tasklet;
struct list_head link; struct list_head link;
int context; int context;
enum { OHCI_ISO_TRANSMIT, OHCI_ISO_RECEIVE } type; enum { OHCI_ISO_TRANSMIT, OHCI_ISO_RECEIVE,
OHCI_ISO_MULTICHANNEL_RECEIVE } type;
}; };
struct ti_ohci { struct ti_ohci {
...@@ -187,18 +189,28 @@ struct ti_ohci { ...@@ -187,18 +189,28 @@ struct ti_ohci {
struct dma_trm_ctx at_req_context; struct dma_trm_ctx at_req_context;
/* iso receive */ /* iso receive */
struct dma_rcv_ctx ir_context;
struct ohci1394_iso_tasklet ir_tasklet;
spinlock_t IR_channel_lock;
int nb_iso_rcv_ctx; int nb_iso_rcv_ctx;
unsigned long ir_ctx_usage; /* use test_and_set_bit() for atomicity */ unsigned long ir_ctx_usage; /* use test_and_set_bit() for atomicity */
unsigned long ir_multichannel_used; /* ditto */
spinlock_t IR_channel_lock;
/* iso receive (legacy API) */
u64 ir_legacy_channels; /* note: this differs from ISO_channel_usage;
it only accounts for channels listened to
by the legacy API, so that we can know when
it is safe to free the legacy API context */
struct dma_rcv_ctx ir_legacy_context;
struct ohci1394_iso_tasklet ir_legacy_tasklet;
/* iso transmit */ /* iso transmit */
struct dma_trm_ctx it_context;
struct ohci1394_iso_tasklet it_tasklet;
int nb_iso_xmit_ctx; int nb_iso_xmit_ctx;
unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */ unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */
/* iso transmit (legacy API) */
struct dma_trm_ctx it_legacy_context;
struct ohci1394_iso_tasklet it_legacy_tasklet;
u64 ISO_channel_usage; u64 ISO_channel_usage;
/* IEEE-1394 part follows */ /* IEEE-1394 part follows */
...@@ -385,7 +397,7 @@ static inline u32 reg_read(const struct ti_ohci *ohci, int offset) ...@@ -385,7 +397,7 @@ static inline u32 reg_read(const struct ti_ohci *ohci, int offset)
/* OHCI evt_* error types, table 3-2 of the OHCI 1.1 spec. */ /* OHCI evt_* error types, table 3-2 of the OHCI 1.1 spec. */
#define EVT_NO_STATUS 0x0 /* No event status */ #define EVT_NO_STATUS 0x0 /* No event status */
#define EVT_RESERVED 0x1 /* Reserved, not used !!! */ #define EVT_RESERVED_A 0x1 /* Reserved, not used !!! */
#define EVT_LONG_PACKET 0x2 /* The revc data was longer than the buf */ #define EVT_LONG_PACKET 0x2 /* The revc data was longer than the buf */
#define EVT_MISSING_ACK 0x3 /* A subaction gap was detected before an ack #define EVT_MISSING_ACK 0x3 /* A subaction gap was detected before an ack
arrived, or recv'd ack had a parity error */ arrived, or recv'd ack had a parity error */
...@@ -404,6 +416,17 @@ static inline u32 reg_read(const struct ti_ohci *ohci, int offset) ...@@ -404,6 +416,17 @@ static inline u32 reg_read(const struct ti_ohci *ohci, int offset)
16-bit host memory write */ 16-bit host memory write */
#define EVT_BUS_RESET 0x9 /* Identifies a PHY packet in the recv buffer as #define EVT_BUS_RESET 0x9 /* Identifies a PHY packet in the recv buffer as
being a synthesized bus reset packet */ being a synthesized bus reset packet */
#define EVT_TIMEOUT 0xa /* Indicates that the asynchronous transmit response
packet expired and was not transmitted, or that an
IT DMA context experienced a skip processing overflow */
#define EVT_TCODE_ERR 0xb /* A bad tCode is associated with this packet.
The packet was flushed */
#define EVT_RESERVED_B 0xc /* Reserved, not used !!! */
#define EVT_RESERVED_C 0xd /* Reserved, not used !!! */
#define EVT_UNKNOWN 0xe /* An error condition has occurred that cannot be
represented by any other event codes defined herein. */
#define EVT_FLUSHED 0xf /* Send by the link side of output FIFO when asynchronous
packets are being flushed due to a bus reset. */
#define OHCI1394_TCODE_PHY 0xE #define OHCI1394_TCODE_PHY 0xE
...@@ -416,8 +439,8 @@ int ohci1394_register_iso_tasklet(struct ti_ohci *ohci, ...@@ -416,8 +439,8 @@ int ohci1394_register_iso_tasklet(struct ti_ohci *ohci,
void ohci1394_unregister_iso_tasklet(struct ti_ohci *ohci, void ohci1394_unregister_iso_tasklet(struct ti_ohci *ohci,
struct ohci1394_iso_tasklet *tasklet); struct ohci1394_iso_tasklet *tasklet);
void ohci1394_stop_context (struct ti_ohci *ohci, int reg, char *msg); /* returns zero if successful, one if DMA context is locked up */
int ohci1394_stop_context (struct ti_ohci *ohci, int reg, char *msg);
struct ti_ohci *ohci1394_get_struct(int card_num); struct ti_ohci *ohci1394_get_struct(int card_num);
#endif #endif
This diff is collapsed.
...@@ -95,6 +95,7 @@ struct ti_lynx { ...@@ -95,6 +95,7 @@ struct ti_lynx {
struct lynx_send_data { struct lynx_send_data {
pcl_t pcl_start, pcl; pcl_t pcl_start, pcl;
struct list_head queue; struct list_head queue;
struct list_head pcl_queue; /* this queue contains at most one packet */
spinlock_t queue_lock; spinlock_t queue_lock;
dma_addr_t header_dma, data_dma; dma_addr_t header_dma, data_dma;
int channel; int channel;
...@@ -514,13 +515,13 @@ static inline void run_pcl(const struct ti_lynx *lynx, pcl_t pclid, int dmachan) ...@@ -514,13 +515,13 @@ static inline void run_pcl(const struct ti_lynx *lynx, pcl_t pclid, int dmachan)
static quadlet_t lynx_csr_rom[] = { static quadlet_t lynx_csr_rom[] = {
/* bus info block offset (hex) */ /* bus info block offset (hex) */
_(0x04040000), /* info/CRC length, CRC 400 */ _(0x04046aaf), /* info/CRC length, CRC 400 */
_(0x31333934), /* 1394 magic number 404 */ _(0x31333934), /* 1394 magic number 404 */
_(0xf064a000), /* misc. settings 408 */ _(0xf064a000), /* misc. settings 408 */
_(0x08002850), /* vendor ID, chip ID high 40c */ _(0x08002850), /* vendor ID, chip ID high 40c */
_(0x0000ffff), /* chip ID low 410 */ _(0x0000ffff), /* chip ID low 410 */
/* root directory */ /* root directory */
_(0x00090000), /* directory length, CRC 414 */ _(0x00095778), /* directory length, CRC 414 */
_(0x03080028), /* vendor ID (Texas Instr.) 418 */ _(0x03080028), /* vendor ID (Texas Instr.) 418 */
_(0x81000008), /* offset to textual ID 41c */ _(0x81000008), /* offset to textual ID 41c */
_(0x0c000200), /* node capabilities 420 */ _(0x0c000200), /* node capabilities 420 */
...@@ -530,8 +531,8 @@ static quadlet_t lynx_csr_rom[] = { ...@@ -530,8 +531,8 @@ static quadlet_t lynx_csr_rom[] = {
_(0x81000014), /* offset to textual ID 430 */ _(0x81000014), /* offset to textual ID 430 */
_(0x09000000), /* node hardware version 434 */ _(0x09000000), /* node hardware version 434 */
_(0x81000018), /* offset to textual ID 438 */ _(0x81000018), /* offset to textual ID 438 */
/* module vendor ID textual */ /* module vendor ID textual */
_(0x00070000), /* CRC length, CRC 43c */ _(0x00070812), /* CRC length, CRC 43c */
_(0x00000000), /* 440 */ _(0x00000000), /* 440 */
_(0x00000000), /* 444 */ _(0x00000000), /* 444 */
_(0x54455841), /* "Texas Instruments" 448 */ _(0x54455841), /* "Texas Instruments" 448 */
...@@ -540,25 +541,25 @@ static quadlet_t lynx_csr_rom[] = { ...@@ -540,25 +541,25 @@ static quadlet_t lynx_csr_rom[] = {
_(0x4d454e54), /* 454 */ _(0x4d454e54), /* 454 */
_(0x53000000), /* 458 */ _(0x53000000), /* 458 */
/* node unique ID leaf */ /* node unique ID leaf */
_(0x00020000), /* CRC length, CRC 45c */ _(0x00022ead), /* CRC length, CRC 45c */
_(0x08002850), /* vendor ID, chip ID high 460 */ _(0x08002850), /* vendor ID, chip ID high 460 */
_(0x0000ffff), /* chip ID low 464 */ _(0x0000ffff), /* chip ID low 464 */
/* module dependent info */ /* module dependent info */
_(0x00050000), /* CRC length, CRC 468 */ _(0x0005d837), /* CRC length, CRC 468 */
_(0x81000012), /* offset to module textual ID 46c */ _(0x81000012), /* offset to module textual ID 46c */
_(0x81000017), /* textual descriptor 470 */ _(0x81000017), /* textual descriptor 470 */
_(0x39010000), /* SRAM size 474 */ _(0x39010000), /* SRAM size 474 */
_(0x3a010000), /* AUXRAM size 478 */ _(0x3a010000), /* AUXRAM size 478 */
_(0x3b000000), /* AUX device 47c */ _(0x3b000000), /* AUX device 47c */
/* module textual ID */ /* module textual ID */
_(0x00050000), /* CRC length, CRC 480 */ _(0x000594df), /* CRC length, CRC 480 */
_(0x00000000), /* 484 */ _(0x00000000), /* 484 */
_(0x00000000), /* 488 */ _(0x00000000), /* 488 */
_(0x54534231), /* "TSB12LV21" 48c */ _(0x54534231), /* "TSB12LV21" 48c */
_(0x324c5632), /* 490 */ _(0x324c5632), /* 490 */
_(0x31000000), /* 494 */ _(0x31000000), /* 494 */
/* part number */ /* part number */
_(0x00060000), /* CRC length, CRC 498 */ _(0x00068405), /* CRC length, CRC 498 */
_(0x00000000), /* 49c */ _(0x00000000), /* 49c */
_(0x00000000), /* 4a0 */ _(0x00000000), /* 4a0 */
_(0x39383036), /* "9806000-0001" 4a4 */ _(0x39383036), /* "9806000-0001" 4a4 */
...@@ -566,14 +567,14 @@ static quadlet_t lynx_csr_rom[] = { ...@@ -566,14 +567,14 @@ static quadlet_t lynx_csr_rom[] = {
_(0x30303031), /* 4ac */ _(0x30303031), /* 4ac */
_(0x20000001), /* 4b0 */ _(0x20000001), /* 4b0 */
/* module hardware version textual */ /* module hardware version textual */
_(0x00050000), /* CRC length, CRC 4b4 */ _(0x00056501), /* CRC length, CRC 4b4 */
_(0x00000000), /* 4b8 */ _(0x00000000), /* 4b8 */
_(0x00000000), /* 4bc */ _(0x00000000), /* 4bc */
_(0x5453424b), /* "TSBKPCITST" 4c0 */ _(0x5453424b), /* "TSBKPCITST" 4c0 */
_(0x50434954), /* 4c4 */ _(0x50434954), /* 4c4 */
_(0x53540000), /* 4c8 */ _(0x53540000), /* 4c8 */
/* node hardware version textual */ /* node hardware version textual */
_(0x00050000), /* CRC length, CRC 4d0 */ _(0x0005d805), /* CRC length, CRC 4d0 */
_(0x00000000), /* 4d4 */ _(0x00000000), /* 4d4 */
_(0x00000000), /* 4d8 */ _(0x00000000), /* 4d8 */
_(0x54534232), /* "TSB21LV03" 4dc */ _(0x54534232), /* "TSB21LV03" 4dc */
......
#ifndef IEEE1394_RAW1394_PRIVATE_H
#define IEEE1394_RAW1394_PRIVATE_H
/* header for definitions that are private to the raw1394 driver
and not visible to user-space */
#define RAW1394_DEVICE_MAJOR 171
#define RAW1394_DEVICE_NAME "raw1394"
struct iso_block_store {
atomic_t refcount;
size_t data_size;
quadlet_t data[0];
};
enum raw1394_iso_state { RAW1394_ISO_INACTIVE = 0,
RAW1394_ISO_RECV = 1,
RAW1394_ISO_XMIT = 2 };
struct file_info {
struct list_head list;
enum { opened, initialized, connected } state;
unsigned int protocol_version;
struct hpsb_host *host;
struct list_head req_pending;
struct list_head req_complete;
struct semaphore complete_sem;
spinlock_t reqlists_lock;
wait_queue_head_t poll_wait_complete;
struct list_head addr_list;
u8 *fcp_buffer;
/* old ISO API */
u64 listen_channels;
quadlet_t *iso_buffer;
size_t iso_buffer_length;
u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */
/* new rawiso API */
enum raw1394_iso_state iso_state;
struct hpsb_iso *iso_handle;
};
struct arm_addr {
struct list_head addr_list; /* file_info list */
u64 start, end;
u64 arm_tag;
u8 access_rights;
u8 notification_options;
u8 client_transactions;
u64 recvb;
u16 rec_length;
u8 *addr_space_buffer; /* accessed by read/write/lock */
};
struct pending_request {
struct list_head list;
struct file_info *file_info;
struct hpsb_packet *packet;
struct iso_block_store *ibs;
quadlet_t *data;
int free_data;
struct raw1394_request req;
};
struct host_info {
struct list_head list;
struct hpsb_host *host;
struct list_head file_info_list;
};
#endif /* IEEE1394_RAW1394_PRIVATE_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#ifndef _VIDEO_1394_H #ifndef _VIDEO_1394_H
#define _VIDEO_1394_H #define _VIDEO_1394_H
#include "ieee1394-ioctl.h"
#define VIDEO1394_DRIVER_NAME "video1394" #define VIDEO1394_DRIVER_NAME "video1394"
#define VIDEO1394_MAX_SIZE 0x4000000 #define VIDEO1394_MAX_SIZE 0x4000000
...@@ -31,18 +33,6 @@ enum { ...@@ -31,18 +33,6 @@ enum {
VIDEO1394_BUFFER_READY VIDEO1394_BUFFER_READY
}; };
enum {
VIDEO1394_LISTEN_CHANNEL = 0,
VIDEO1394_UNLISTEN_CHANNEL,
VIDEO1394_LISTEN_QUEUE_BUFFER,
VIDEO1394_LISTEN_WAIT_BUFFER, // wait until buffer is ready
VIDEO1394_TALK_CHANNEL,
VIDEO1394_UNTALK_CHANNEL,
VIDEO1394_TALK_QUEUE_BUFFER,
VIDEO1394_TALK_WAIT_BUFFER,
VIDEO1394_LISTEN_POLL_BUFFER // return immediately with -EINTR if not ready
};
#define VIDEO1394_SYNC_FRAMES 0x00000001 #define VIDEO1394_SYNC_FRAMES 0x00000001
#define VIDEO1394_INCLUDE_ISO_HEADERS 0x00000002 #define VIDEO1394_INCLUDE_ISO_HEADERS 0x00000002
#define VIDEO1394_VARIABLE_PACKET_SIZE 0x00000004 #define VIDEO1394_VARIABLE_PACKET_SIZE 0x00000004
......
/* /*
* Linux ARCnet driver - COM20020 PCI support (Contemporary Controls PCI20) * Linux ARCnet driver - COM20020 PCI support
* Contemporary Controls PCI20 and SOHARD SH-ARC PCI
* *
* Written 1994-1999 by Avery Pennarun, * Written 1994-1999 by Avery Pennarun,
* based on an ISA version by David Woodhouse. * based on an ISA version by David Woodhouse.
...@@ -86,7 +87,21 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de ...@@ -86,7 +87,21 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
memset(lp, 0, sizeof(struct arcnet_local)); memset(lp, 0, sizeof(struct arcnet_local));
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
// SOHARD needs PCI base addr 4
if (pdev->vendor==0x10B5) {
BUGMSG(D_NORMAL, "SOHARD\n");
ioaddr = pci_resource_start(pdev, 4);
}
else {
BUGMSG(D_NORMAL, "Contemporary Controls\n");
ioaddr = pci_resource_start(pdev, 2); ioaddr = pci_resource_start(pdev, 2);
}
// Dummy access after Reset
// ARCNET controller needs this access to detect bustype
outb(0x00,ioaddr+1);
inb(ioaddr+1);
dev->base_addr = ioaddr; dev->base_addr = ioaddr;
dev->irq = pdev->irq; dev->irq = pdev->irq;
dev->dev_addr[0] = node; dev->dev_addr[0] = node;
...@@ -152,6 +167,7 @@ static struct pci_device_id com20020pci_id_table[] __devinitdata = { ...@@ -152,6 +167,7 @@ static struct pci_device_id com20020pci_id_table[] __devinitdata = {
{ 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, { 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
{ 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, { 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
{ 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, { 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
{ 0x10B5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
{0,} {0,}
}; };
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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