diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-12-01 05:06:48 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-12-01 05:06:48 -0800 |
| commit | 97ae712423fd10284012a665abcf6f8a44c95a66 (patch) | |
| tree | 636d4bb118ea71449abc8889433b40eec07754ad | |
| parent | b5a8e8b86026ef3b6ddfcebea1d69344707c1bad (diff) | |
| parent | 8d81094b01532c758cc166325997cd3c36a3dbd8 (diff) | |
Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
126 files changed, 5136 insertions, 3910 deletions
@@ -2248,6 +2248,15 @@ D: Ziatech ZT5550 and generic CompactPCI hotplug drivers S: Toronto, Ontario S: Canada +N: Zwane Mwaikambo +E: zwane@linuxpower.ca +W: http://function.linuxpower.ca +D: Various driver hacking +D: Lowlevel x86 kernel hacking +D: General debugging +S: (ask for current address) +S: Tanzania + N: Trond Myklebust E: trond.myklebust@fys.uio.no D: current NFS client hacker. @@ -2722,7 +2731,7 @@ S: Finland N: Thomas Sailer E: t.sailer@alumni.ethz.ch E: HB9JNX@HB9W.CHE.EU (packet radio) -D: hfmodem, Baycom and sound card radio modem driver +D: Baycom driver S: Markusstrasse 18 S: 8006 Zuerich S: Switzerland @@ -3093,8 +3102,14 @@ S: 97078 Wuerzburg S: Germany N: Greg Ungerer -E: gerg@moreton.com.au +E: gerg@snapgear.com +D: uClinux kernel hacker +D: Port uClinux to the Motorola ColdFire CPU D: Author of Stallion multiport serial drivers +S: SnapGear Inc. +S: 825 Stanley St +S: Woolloongabba. QLD. 4102 +S: Australia N: Jeffrey A. Uphoff E: juphoff@transmeta.com diff --git a/MAINTAINERS b/MAINTAINERS index 0a2786da6bc7..4bd8689bbf40 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -261,11 +261,11 @@ M: ralf@linux-mips.org L: linux-hams@vger.kernel.org S: Maintained -BAYCOM/HDLCDRV/SOUNDMODEM DRIVERS FOR AX.25 +BAYCOM/HDLCDRV DRIVERS FOR AX.25 P: Thomas Sailer -M: sailer@ife.ee.ethz.ch +M: t.sailer@alumni.ethz.ch L: linux-hams@vger.kernel.org -W: http://www.ife.ee.ethz.ch/~sailer/ham/ham.html +W: http://www.baycom.org/~tom/ham/ham.html S: Maintained BERKSHIRE PRODUCTS PC WATCHDOG DRIVER diff --git a/arch/ia64/sn/kernel/sn1/synergy.c b/arch/ia64/sn/kernel/sn1/synergy.c index 9524e8bef9f0..ddd3e95b0fab 100644 --- a/arch/ia64/sn/kernel/sn1/synergy.c +++ b/arch/ia64/sn/kernel/sn1/synergy.c @@ -449,7 +449,7 @@ synergy_perf_ioctl(struct inode *inode, struct file *file, } struct file_operations synergy_mon_fops = { - ioctl: synergy_perf_ioctl, + .ioctl = synergy_perf_ioctl, }; void diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index d4a3b0e5ecab..f09a9419796a 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -112,27 +112,43 @@ static inline void unmask_cpu_irq(void *unused, int irq) * do_cpu_irq_mask() index into the matching irq_action array. */ struct irqaction cpu_irq_actions[IRQ_PER_REGION] = { - [IRQ_OFFSET(TIMER_IRQ)] { handler: timer_interrupt, name: "timer", }, + [IRQ_OFFSET(TIMER_IRQ)] = { + .handler = timer_interrupt, + .name = "timer", + }, #ifdef CONFIG_SMP - [IRQ_OFFSET(IPI_IRQ)] { handler: ipi_interrupt, name: "IPI", }, + [IRQ_OFFSET(IPI_IRQ)] = { + .handler = ipi_interrupt, + .name = "IPI", + }, #endif }; struct irq_region_ops cpu_irq_ops = { - disable_cpu_irq, enable_cpu_irq, unmask_cpu_irq, unmask_cpu_irq + .disable_irq = disable_cpu_irq, + .enable_irq = enable_cpu_irq, + .mask_irq = unmask_cpu_irq, + .unmask_irq = unmask_cpu_irq }; struct irq_region cpu0_irq_region = { - ops: { disable_cpu_irq, enable_cpu_irq, unmask_cpu_irq, unmask_cpu_irq }, - data: { dev: &cpu_data[0], - name: "PARISC-CPU", - irqbase: IRQ_FROM_REGION(CPU_IRQ_REGION), }, - action: cpu_irq_actions, + .ops = { + .disable_irq = disable_cpu_irq, + .enable_irq = enable_cpu_irq, + .mask_irq = unmask_cpu_irq, + .unmask_irq = unmask_cpu_irq + }, + .data = { + .dev = &cpu_data[0], + .name = "PARISC-CPU", + .irqbase = IRQ_FROM_REGION(CPU_IRQ_REGION), + }, + .action = cpu_irq_actions, }; struct irq_region *irq_region[NR_IRQ_REGS] = { - [ 0 ] NULL, /* reserved for EISA, else causes data page fault (aka code 15) */ - [ CPU_IRQ_REGION ] &cpu0_irq_region, + [ 0 ] = NULL, /* reserved for EISA, else causes data page fault (aka code 15) */ + [ CPU_IRQ_REGION ] = &cpu0_irq_region, }; diff --git a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c index 73b772518e2f..a12e2f8f5e0f 100644 --- a/arch/ppc/amiga/amiints.c +++ b/arch/ppc/amiga/amiints.c @@ -310,14 +310,14 @@ static void ami_int7(int irq, void *dev_id, struct pt_regs *fp) and executes them in a loop. Having ami_badint at the end of the chain is a bad idea. */ struct irqaction amiga_sys_irqaction[AUTO_IRQS] = { - { handler: ami_badint, name: "spurious int" }, - { handler: ami_int1, name: "int1 handler" }, + { .handler = ami_badint, .name = "spurious int" }, + { .handler = ami_int1, .name = "int1 handler" }, { 0, /* CIAA */ }, - { handler: ami_int3, name: "int3 handler" }, - { handler: ami_int4, name: "int4 handler" }, - { handler: ami_int5, name: "int5 handler" }, + { .handler = ami_int3, .name = "int3 handler" }, + { .handler = ami_int4, .name = "int4 handler" }, + { .handler = ami_int5, .name = "int5 handler" }, { 0, /* CIAB */ }, - { handler: ami_int7, name: "int7 handler" }, + { .handler = ami_int7, .name = "int7 handler" }, }; #else void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { diff --git a/drivers/acorn/scsi/acornscsi.c b/drivers/acorn/scsi/acornscsi.c index 85b2df1aa8fd..f37ff3f411ce 100644 --- a/drivers/acorn/scsi/acornscsi.c +++ b/drivers/acorn/scsi/acornscsi.c @@ -2935,9 +2935,9 @@ int acornscsi_proc_info(char *buffer, char **start, off_t offset, } } - p += sprintf(p, "\nAttached devices:%s\n", instance->host_queue ? "" : " none"); + p += sprintf(p, "\nAttached devices:\n"); - for (scd = instance->host_queue; scd; scd = scd->next) { + list_for_each_entry(scd, &instance->my_devices, siblings) { int len; proc_print_scsidevice(scd, p, &len, 0); @@ -3051,7 +3051,7 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id) acornscsi_resetcard(ashost); - ret = scsi_add_host(host); + ret = scsi_add_host(host, &ec->dev); if (ret == 0) goto out; diff --git a/drivers/acorn/scsi/arxescsi.c b/drivers/acorn/scsi/arxescsi.c index ab1d43c0d153..6a54f887b61a 100644 --- a/drivers/acorn/scsi/arxescsi.c +++ b/drivers/acorn/scsi/arxescsi.c @@ -311,7 +311,7 @@ int arxescsi_proc_info(char *buffer, char **start, off_t offset, pos += sprintf (buffer+pos, "\nAttached devices:\n"); - for (scd = host->host_queue; scd; scd = scd->next) { + list_for_each_entry(scd, &host->my_devices, siblings) { pos += fas216_print_device(&info->info, scd, buffer + pos); if (pos + begin < offset) { @@ -398,7 +398,7 @@ arxescsi_probe(struct expansion_card *ec, const struct ecard_id *id) fas216_init(host); - ret = scsi_add_host(host); + ret = scsi_add_host(host, &ec->dev); if (ret == 0) goto out; diff --git a/drivers/acorn/scsi/cumana_1.c b/drivers/acorn/scsi/cumana_1.c index 4be5d242fd28..4da215d97759 100644 --- a/drivers/acorn/scsi/cumana_1.c +++ b/drivers/acorn/scsi/cumana_1.c @@ -299,7 +299,7 @@ cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) NCR5380_print_options(host); printk("\n"); - ret = scsi_add_host(host); + ret = scsi_add_host(host, &ec->dev); if (ret == 0) goto out; diff --git a/drivers/acorn/scsi/cumana_2.c b/drivers/acorn/scsi/cumana_2.c index 88924510a03b..efd1ead5dd17 100644 --- a/drivers/acorn/scsi/cumana_2.c +++ b/drivers/acorn/scsi/cumana_2.c @@ -387,7 +387,7 @@ int cumanascsi_2_proc_info (char *buffer, char **start, off_t offset, pos += sprintf(buffer+pos, "\nAttached devices:\n"); - for (scd = host->host_queue; scd; scd = scd->next) { + list_for_each_entry(scd, &host->my_devices, siblings) { int len; proc_print_scsidevice(scd, buffer, &len, pos); @@ -503,7 +503,7 @@ cumanascsi2_probe(struct expansion_card *ec, const struct ecard_id *id) fas216_init(host); - ret = scsi_add_host(host); + ret = scsi_add_host(host, &ec->dev); if (ret == 0) goto out; diff --git a/drivers/acorn/scsi/eesox.c b/drivers/acorn/scsi/eesox.c index a6129836d601..0d31f5740ffa 100644 --- a/drivers/acorn/scsi/eesox.c +++ b/drivers/acorn/scsi/eesox.c @@ -390,7 +390,7 @@ int eesoxscsi_proc_info(char *buffer, char **start, off_t offset, pos += sprintf(buffer+pos, "\nAttached devices:\n"); - for (scd = host->host_queue; scd; scd = scd->next) { + list_for_each_entry(scd, &host->my_devices, siblings) { int len; proc_print_scsidevice(scd, buffer, &len, pos); @@ -502,7 +502,7 @@ eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id) } fas216_init(host); - ret = scsi_add_host(host); + ret = scsi_add_host(host, &ec->dev); if (ret == 0) goto out; diff --git a/drivers/acorn/scsi/fas216.c b/drivers/acorn/scsi/fas216.c index 69894a1601d4..577888dfa5f2 100644 --- a/drivers/acorn/scsi/fas216.c +++ b/drivers/acorn/scsi/fas216.c @@ -2631,7 +2631,7 @@ int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt) * all command structures. Leave the running * command in place. */ - for (SDpnt = info->host->host_queue; SDpnt; SDpnt = SDpnt->next) { + list_for_each_entry(SDpnt, &info->host->my_devices, siblings) { int i; if (SDpnt->soft_reset) diff --git a/drivers/acorn/scsi/oak.c b/drivers/acorn/scsi/oak.c index cb76e8424138..283e96275547 100644 --- a/drivers/acorn/scsi/oak.c +++ b/drivers/acorn/scsi/oak.c @@ -160,7 +160,7 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) NCR5380_print_options(host); printk("\n"); - ret = scsi_add_host(host); + ret = scsi_add_host(host, &ec->dev); if (ret == 0) goto out; diff --git a/drivers/acorn/scsi/powertec.c b/drivers/acorn/scsi/powertec.c index 9d41ae3b9396..877c3c8e0504 100644 --- a/drivers/acorn/scsi/powertec.c +++ b/drivers/acorn/scsi/powertec.c @@ -269,7 +269,7 @@ int powertecscsi_proc_info(char *buffer, char **start, off_t offset, pos += sprintf(buffer+pos, "\nAttached devices:\n"); - for (scd = host->host_queue; scd; scd = scd->next) { + list_for_each_entry(scd, &host->my_devices, siblings) { pos += fas216_print_device(&info->info, scd, buffer + pos); if (pos + begin < offset) { @@ -376,7 +376,7 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id) fas216_init(host); - ret = scsi_add_host(host); + ret = scsi_add_host(host, &ec->dev); if (ret == 0) goto out; diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index d693b48f47db..cf880e8cacae 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -372,6 +372,8 @@ int tty_check_change(struct tty_struct * tty) return -ERESTARTSYS; } +EXPORT_SYMBOL(tty_check_change); + static ssize_t hung_up_tty_read(struct file * file, char * buf, size_t count, loff_t *ppos) { @@ -540,6 +542,8 @@ void tty_hangup(struct tty_struct * tty) schedule_work(&tty->hangup_work); } +EXPORT_SYMBOL(tty_hangup); + void tty_vhangup(struct tty_struct * tty) { #ifdef TTY_DEBUG_HANGUP @@ -556,6 +560,8 @@ int tty_hung_up_p(struct file * filp) return (filp->f_op == &hung_up_tty_fops); } +EXPORT_SYMBOL(tty_hung_up_p); + /* * This function is typically called only by the session leader, when * it wants to disassociate itself from its controlling tty. @@ -1886,6 +1892,8 @@ void do_SAK(struct tty_struct *tty) schedule_work(&tty->SAK_work); } +EXPORT_SYMBOL(do_SAK); + /* * This routine is called out of the software interrupt to flush data * from the flip buffer to the line discipline. @@ -1946,34 +1954,44 @@ static int baud_table[] = { #endif }; -static int n_baud_table = sizeof(baud_table)/sizeof(int); +static int n_baud_table = ARRAY_SIZE(baud_table); -int tty_get_baud_rate(struct tty_struct *tty) +int tty_termios_baud_rate(struct termios *termios) { - unsigned int cflag, i; + unsigned int cbaud = termios->c_cflag & CBAUD; - cflag = tty->termios->c_cflag; + if (cbaud & CBAUDEX) { + cbaud &= ~CBAUDEX; - i = cflag & CBAUD; - if (i & CBAUDEX) { - i &= ~CBAUDEX; - if (i < 1 || i+15 >= n_baud_table) - tty->termios->c_cflag &= ~CBAUDEX; + if (cbaud < 1 || cbaud + 15 > n_baud_table) + termios->c_cflag &= ~CBAUDEX; else - i += 15; + cbaud += 15; } - if (i==15 && tty->alt_speed) { + + return baud_table[cbaud]; +} + +EXPORT_SYMBOL(tty_termios_baud_rate); + +int tty_get_baud_rate(struct tty_struct *tty) +{ + int baud = tty_termios_baud_rate(tty->termios); + + if (baud == 38400 && tty->alt_speed) { if (!tty->warned) { printk(KERN_WARNING "Use of setserial/setrocket to " "set SPD_* flags is deprecated\n"); tty->warned = 1; } - return(tty->alt_speed); + baud = tty->alt_speed; } - return baud_table[i]; + return baud; } +EXPORT_SYMBOL(tty_get_baud_rate); + void tty_flip_buffer_push(struct tty_struct *tty) { if (tty->low_latency) diff --git a/drivers/media/dvb/av7110/av7110_ir.c b/drivers/media/dvb/av7110/av7110_ir.c index 096fa0c62716..da87e87d9465 100644 --- a/drivers/media/dvb/av7110/av7110_ir.c +++ b/drivers/media/dvb/av7110/av7110_ir.c @@ -54,7 +54,7 @@ void av7110_emit_keyup (unsigned long data) static -struct timer_list keyup_timer = { function: av7110_emit_keyup }; +struct timer_list keyup_timer = { .function = av7110_emit_keyup }; static diff --git a/drivers/media/dvb/av7110/saa7146_core.c b/drivers/media/dvb/av7110/saa7146_core.c index e18cb6c6ab1b..0690689bd2f9 100644 --- a/drivers/media/dvb/av7110/saa7146_core.c +++ b/drivers/media/dvb/av7110/saa7146_core.c @@ -905,12 +905,12 @@ static struct pci_device_id saa7146_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, saa7146_pci_tbl); static struct pci_driver saa7146_driver = { - name: "saa7146", - id_table: saa7146_pci_tbl, - probe: saa7146_init_one, - remove: saa7146_remove_one, - suspend: saa7146_suspend, - resume: saa7146_resume, + .name = "saa7146", + .id_table = saa7146_pci_tbl, + .probe = saa7146_init_one, + .remove = saa7146_remove_one, + .suspend = saa7146_suspend, + .resume = saa7146_resume, }; diff --git a/drivers/media/dvb/frontends/alps_bsru6.c b/drivers/media/dvb/frontends/alps_bsru6.c index f67ab386a51d..4839811a7641 100644 --- a/drivers/media/dvb/frontends/alps_bsru6.c +++ b/drivers/media/dvb/frontends/alps_bsru6.c @@ -39,22 +39,22 @@ static int debug = 0; static struct dvb_frontend_info bsru6_info = { #ifdef CONFIG_ALPS_BSRU6_IS_LG_TDQBS00X - name: "LG TDQB-S00x", + .name = "LG TDQB-S00x", #else - name: "Alps BSRU6", + .name = "Alps BSRU6", #endif - type: FE_QPSK, - frequency_min: 950000, - frequency_max: 2150000, - frequency_stepsize: 125, /* kHz for QPSK frontends */ - frequency_tolerance: M_CLK/2000, - symbol_rate_min: 1000000, - symbol_rate_max: 45000000, - symbol_rate_tolerance: 500, /* ppm */ - notifier_delay: 0, - caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 125, /* kHz for QPSK frontends */ + .frequency_tolerance = M_CLK/2000, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .symbol_rate_tolerance = 500, /* ppm */ + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK }; @@ -158,7 +158,7 @@ int stv0299_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) { int ret; u8 buf [] = { reg, data }; - struct i2c_msg msg = { addr: 0x68, flags: 0, buf: buf, len: 2 }; + struct i2c_msg msg = { .addr = 0x68, .flags = 0, .buf = buf, .len = 2 }; dprintk ("%s\n", __FUNCTION__); @@ -178,8 +178,8 @@ u8 stv0299_readreg (struct dvb_i2c_bus *i2c, u8 reg) int ret; u8 b0 [] = { reg }; u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { addr: 0x68, flags: 0, buf: b0, len: 1 }, - { addr: 0x68, flags: I2C_M_RD, buf: b1, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = b0, .len = 1 }, + { .addr = 0x68, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; dprintk ("%s\n", __FUNCTION__); @@ -196,8 +196,8 @@ static int stv0299_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len) { int ret; - struct i2c_msg msg [] = { { addr: 0x68, flags: 0, buf: ®1, len: 1 }, - { addr: 0x68, flags: I2C_M_RD, buf: b, len: len } }; + struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = ®1, .len = 1 }, + { .addr = 0x68, .flags = I2C_M_RD, .buf = b, .len = len } }; dprintk ("%s\n", __FUNCTION__); @@ -216,8 +216,8 @@ int tsa5059_write (struct dvb_i2c_bus *i2c, u8 data [4]) { int ret; u8 rpt1 [] = { 0x05, 0xb5 }; /* enable i2c repeater on stv0299 */ - struct i2c_msg msg [] = {{ addr: 0x68, flags: 0, buf: rpt1, len: 2 }, - { addr: 0x61, flags: 0, buf: data, len: 4 }}; + struct i2c_msg msg [] = {{ .addr = 0x68, .flags = 0, .buf = rpt1, .len = 2 }, + { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }}; dprintk ("%s\n", __FUNCTION__); diff --git a/drivers/media/dvb/frontends/alps_bsrv2.c b/drivers/media/dvb/frontends/alps_bsrv2.c index e0ecd0e2447b..be7855f12446 100644 --- a/drivers/media/dvb/frontends/alps_bsrv2.c +++ b/drivers/media/dvb/frontends/alps_bsrv2.c @@ -32,20 +32,20 @@ static int debug = 0; static struct dvb_frontend_info bsrv2_info = { - name: "Alps BSRV2", - type: FE_QPSK, - frequency_min: 950000, - frequency_max: 2150000, - frequency_stepsize: 250, /* kHz for QPSK frontends */ - frequency_tolerance: 29500, - symbol_rate_min: 1000000, - symbol_rate_max: 45000000, -/* symbol_rate_tolerance: ???,*/ - notifier_delay: 50, /* 1/20 s */ - caps: FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK + .name = "Alps BSRV2", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 250, /* kHz for QPSK frontends */ + .frequency_tolerance = 29500, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .notifier_delay = 50, /* 1/20 s */ + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK }; @@ -76,7 +76,7 @@ static int ves1893_writereg (struct dvb_i2c_bus *i2c, int reg, int data) { u8 buf [] = { 0x00, reg, data }; - struct i2c_msg msg = { addr: 0x08, flags: 0, buf: buf, len: 3 }; + struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 3 }; int err; if ((err = i2c->xfer (i2c, &msg, 1)) != 1) { @@ -94,8 +94,8 @@ u8 ves1893_readreg (struct dvb_i2c_bus *i2c, u8 reg) int ret; u8 b0 [] = { 0x00, reg }; u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { addr: 0x08, flags: 0, buf: b0, len: 2 }, - { addr: 0x08, flags: I2C_M_RD, buf: b1, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x08, .flags = 0, .buf = b0, .len = 2 }, + { .addr = 0x08, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; ret = i2c->xfer (i2c, msg, 2); @@ -110,7 +110,7 @@ static int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4]) { int ret; - struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }; ret = i2c->xfer (i2c, &msg, 1); diff --git a/drivers/media/dvb/frontends/alps_tdlb7.c b/drivers/media/dvb/frontends/alps_tdlb7.c index d5700041eccd..2d3482e0b3c6 100644 --- a/drivers/media/dvb/frontends/alps_tdlb7.c +++ b/drivers/media/dvb/frontends/alps_tdlb7.c @@ -73,21 +73,15 @@ static int errno; static struct dvb_frontend_info tdlb7_info = { - name: "Alps TDLB7", - type: FE_OFDM, - frequency_min: 470000000, - frequency_max: 860000000, - frequency_stepsize: 166666, -#if 0 - frequency_tolerance: ???, - symbol_rate_min: ???, - symbol_rate_max: ???, - symbol_rate_tolerance: ???, - notifier_delay: 0, -#endif - caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 + .name = "Alps TDLB7", + .type = FE_OFDM, + .frequency_min = 470000000, + .frequency_max = 860000000, + .frequency_stepsize = 166666, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 }; @@ -95,7 +89,7 @@ static int sp8870_writereg (struct dvb_i2c_bus *i2c, u16 reg, u16 data) { u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff }; - struct i2c_msg msg = { addr: 0x71, flags: 0, buf: buf, len: 4 }; + struct i2c_msg msg = { .addr = 0x71, .flags = 0, .buf = buf, .len = 4 }; int err; if ((err = i2c->xfer (i2c, &msg, 1)) != 1) { @@ -113,8 +107,8 @@ u16 sp8870_readreg (struct dvb_i2c_bus *i2c, u16 reg) int ret; u8 b0 [] = { reg >> 8 , reg & 0xff }; u8 b1 [] = { 0, 0 }; - struct i2c_msg msg [] = { { addr: 0x71, flags: 0, buf: b0, len: 2 }, - { addr: 0x71, flags: I2C_M_RD, buf: b1, len: 2 } }; + struct i2c_msg msg [] = { { .addr = 0x71, .flags = 0, .buf = b0, .len = 2 }, + { .addr = 0x71, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; ret = i2c->xfer (i2c, msg, 2); @@ -129,7 +123,7 @@ static int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4]) { int ret; - struct i2c_msg msg = { addr: 0x60, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = 4 }; ret = i2c->xfer (i2c, &msg, 1); @@ -377,7 +371,7 @@ static int tdlb7_attach (struct dvb_i2c_bus *i2c) { - struct i2c_msg msg = { addr: 0x71, flags: 0, buf: NULL, len: 0 }; + struct i2c_msg msg = { .addr = 0x71, .flags = 0, .buf = NULL, .len = 0 }; dprintk ("%s\n", __FUNCTION__); diff --git a/drivers/media/dvb/frontends/alps_tdmb7.c b/drivers/media/dvb/frontends/alps_tdmb7.c index ddc5e818666b..9a8f2f72b6b9 100644 --- a/drivers/media/dvb/frontends/alps_tdmb7.c +++ b/drivers/media/dvb/frontends/alps_tdmb7.c @@ -33,21 +33,15 @@ static int debug = 0; static struct dvb_frontend_info tdmb7_info = { - name: "Alps TDMB7", - type: FE_OFDM, - frequency_min: 470000000, - frequency_max: 860000000, - frequency_stepsize: 166667, -#if 0 - frequency_tolerance: ???, - symbol_rate_min: ???, - symbol_rate_max: ???, - symbol_rate_tolerance: 500, /* ppm */ - notifier_delay: 0, -#endif - caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 + .name = "Alps TDMB7", + .type = FE_OFDM, + .frequency_min = 470000000, + .frequency_max = 860000000, + .frequency_stepsize = 166667, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 }; @@ -87,7 +81,7 @@ int cx22700_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) { int ret; u8 buf [] = { reg, data }; - struct i2c_msg msg = { addr: 0x43, flags: 0, buf: buf, len: 2 }; + struct i2c_msg msg = { .addr = 0x43, .flags = 0, .buf = buf, .len = 2 }; dprintk ("%s\n", __FUNCTION__); @@ -107,8 +101,8 @@ u8 cx22700_readreg (struct dvb_i2c_bus *i2c, u8 reg) int ret; u8 b0 [] = { reg }; u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { addr: 0x43, flags: 0, buf: b0, len: 1 }, - { addr: 0x43, flags: I2C_M_RD, buf: b1, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x43, .flags = 0, .buf = b0, .len = 1 }, + { .addr = 0x43, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; dprintk ("%s\n", __FUNCTION__); @@ -124,7 +118,7 @@ u8 cx22700_readreg (struct dvb_i2c_bus *i2c, u8 reg) static int pll_write (struct dvb_i2c_bus *i2c, u8 data [4]) { - struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }; int ret; cx22700_writereg (i2c, 0x0a, 0x00); /* open i2c bus switch */ @@ -418,7 +412,7 @@ int tdmb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) static int tdmb7_attach (struct dvb_i2c_bus *i2c) { - struct i2c_msg msg = { addr: 0x43, flags: 0, buf: NULL, len: 0 }; + struct i2c_msg msg = { .addr = 0x43, .flags = 0, .buf = NULL, .len = 0 }; dprintk ("%s\n", __FUNCTION__); diff --git a/drivers/media/dvb/frontends/grundig_29504-401.c b/drivers/media/dvb/frontends/grundig_29504-401.c index a65e9843f747..fb2c7b904bb2 100644 --- a/drivers/media/dvb/frontends/grundig_29504-401.c +++ b/drivers/media/dvb/frontends/grundig_29504-401.c @@ -34,18 +34,14 @@ static int debug = 0; struct dvb_frontend_info grundig_29504_401_info = { - name: "Grundig 29504-401", - type: FE_OFDM, -/* frequency_min: ???,*/ -/* frequency_max: ???,*/ - frequency_stepsize: 166666, -/* frequency_tolerance: ???,*/ -/* symbol_rate_tolerance: ???,*/ - notifier_delay: 0, - caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_MUTE_TS + .name = "Grundig 29504-401", + .type = FE_OFDM, + .frequency_stepsize = 166666, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | FE_CAN_QPSK | + FE_CAN_QAM_16 | FE_CAN_QAM_64 | + FE_CAN_MUTE_TS }; @@ -54,7 +50,7 @@ int l64781_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) { int ret; u8 buf [] = { reg, data }; - struct i2c_msg msg = { addr: 0x55, flags: 0, buf: buf, len: 2 }; + struct i2c_msg msg = { .addr = 0x55, .flags = 0, .buf = buf, .len = 2 }; if ((ret = i2c->xfer (i2c, &msg, 1)) != 1) dprintk ("%s: write_reg error (reg == %02x) = %02x!\n", @@ -70,8 +66,8 @@ u8 l64781_readreg (struct dvb_i2c_bus *i2c, u8 reg) int ret; u8 b0 [] = { reg }; u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { addr: 0x55, flags: 0, buf: b0, len: 1 }, - { addr: 0x55, flags: I2C_M_RD, buf: b1, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 }, + { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; ret = i2c->xfer (i2c, msg, 2); @@ -86,7 +82,7 @@ static int tsa5060_write (struct dvb_i2c_bus *i2c, u8 data [4]) { int ret; - struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }; if ((ret = i2c->xfer (i2c, &msg, 1)) != 1) dprintk ("%s: write_reg error == %02x!\n", __FUNCTION__, ret); @@ -273,7 +269,7 @@ static void reset_and_configure (struct dvb_i2c_bus *i2c) { u8 buf [] = { 0x06 }; - struct i2c_msg msg = { addr: 0x00, flags: 0, buf: buf, len: 1 }; + struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 }; i2c->xfer (i2c, &msg, 1); } @@ -432,8 +428,8 @@ int l64781_attach (struct dvb_i2c_bus *i2c) { u8 b0 [] = { 0x1a }; u8 b1 [] = { 0x00 }; - struct i2c_msg msg [] = { { addr: 0x55, flags: 0, buf: b0, len: 1 }, - { addr: 0x55, flags: I2C_M_RD, buf: b1, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 }, + { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; if (i2c->xfer (i2c, msg, 2) == 2) /* probably an EEPROM... */ return -ENODEV; diff --git a/drivers/media/dvb/frontends/grundig_29504-491.c b/drivers/media/dvb/frontends/grundig_29504-491.c index 563377137648..37bd616fd176 100644 --- a/drivers/media/dvb/frontends/grundig_29504-491.c +++ b/drivers/media/dvb/frontends/grundig_29504-491.c @@ -36,22 +36,20 @@ static int debug = 0; static struct dvb_frontend_info grundig_29504_491_info = { - name: "Grundig 29504-491, (TDA8083 based)", - type: FE_QPSK, - frequency_min: 950000, /* FIXME: guessed! */ - frequency_max: 1400000, /* FIXME: guessed! */ - frequency_stepsize: 125, /* kHz for QPSK frontends */ -/* frequency_tolerance: ???,*/ - symbol_rate_min: 1000000, /* FIXME: guessed! */ - symbol_rate_max: 45000000, /* FIXME: guessed! */ -/* symbol_rate_tolerance: ???,*/ - notifier_delay: 0, - caps: FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | - FE_CAN_MUTE_TS + .name = "Grundig 29504-491, (TDA8083 based)", + .type = FE_QPSK, + .frequency_min = 950000, /* FIXME: guessed! */ + .frequency_max = 1400000, /* FIXME: guessed! */ + .frequency_stepsize = 125, /* kHz for QPSK frontends */ + .symbol_rate_min = 1000000, /* FIXME: guessed! */ + .symbol_rate_max = 45000000, /* FIXME: guessed! */ + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | FE_CAN_FEC_4_5 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | + FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | + FE_CAN_FEC_AUTO | FE_CAN_QPSK | + FE_CAN_MUTE_TS }; @@ -73,7 +71,7 @@ int tda8083_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) { int ret; u8 buf [] = { reg, data }; - struct i2c_msg msg = { addr: 0x68, flags: 0, buf: buf, len: 2 }; + struct i2c_msg msg = { .addr = 0x68, .flags = 0, .buf = buf, .len = 2 }; ret = i2c->xfer (i2c, &msg, 1); @@ -89,8 +87,8 @@ static int tda8083_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len) { int ret; - struct i2c_msg msg [] = { { addr: 0x68, flags: 0, buf: ®1, len: 1 }, - { addr: 0x68, flags: I2C_M_RD, buf: b, len: len } }; + struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = ®1, .len = 1 }, + { .addr = 0x68, .flags = I2C_M_RD, .buf = b, .len = len } }; ret = i2c->xfer (i2c, msg, 2); @@ -117,7 +115,7 @@ static int tsa5522_write (struct dvb_i2c_bus *i2c, u8 data [4]) { int ret; - struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }; ret = i2c->xfer (i2c, &msg, 1); diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c index 30b06900102c..a4564aef9a63 100644 --- a/drivers/media/dvb/frontends/ves1820.c +++ b/drivers/media/dvb/frontends/ves1820.c @@ -59,20 +59,13 @@ static int debug = 0; static struct dvb_frontend_info ves1820_info = { - name: "VES1820/Grundig tuner as used on the Siemens DVB-C card", - type: FE_QAM, - frequency_stepsize: 62500, - frequency_min: 51000000, - frequency_max: 858000000, -#if 0 - frequency_tolerance: ???, - symbol_rate_min: ???, - symbol_rate_max: ???, - symbol_rate_tolerance: ???, /* ppm */ /* == 8% (spec p. 5) */ - notifier_delay: ?, -#endif - caps: FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 + .name = "VES1820/Grundig tuner as used on the Siemens DVB-C card", + .type = FE_QAM, + .frequency_stepsize = 62500, + .frequency_min = 51000000, + .frequency_max = 858000000, + .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | + FE_CAN_QAM_128 | FE_CAN_QAM_256 }; @@ -95,7 +88,7 @@ int ves1820_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) { int ret; u8 buf[] = { 0x00, reg, data }; - struct i2c_msg msg = { addr: 0x09, flags: 0, buf: buf, len: 3 }; + struct i2c_msg msg = { .addr = 0x09, .flags = 0, .buf = buf, .len = 3 }; ret = i2c->xfer (i2c, &msg, 1); @@ -115,8 +108,8 @@ u8 ves1820_readreg (struct dvb_i2c_bus *i2c, u8 reg) int ret; u8 b0 [] = { 0x00, reg }; u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { addr: 0x09, flags: 0, buf: b0, len: 2 }, - { addr: 0x09, flags: I2C_M_RD, buf: b1, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x09, .flags = 0, .buf = b0, .len = 2 }, + { .addr = 0x09, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; ret = i2c->xfer (i2c, msg, 2); @@ -132,7 +125,7 @@ static int tuner_write (struct dvb_i2c_bus *i2c, u8 addr, u8 data [4]) { int ret; - struct i2c_msg msg = { addr: addr, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 }; ret = i2c->xfer (i2c, &msg, 1); @@ -178,7 +171,7 @@ static int probe_tuner (struct dvb_frontend *frontend) { struct dvb_i2c_bus *i2c = frontend->i2c; - struct i2c_msg msg = { addr: 0x61, flags: 0, buf: NULL, len: 0 }; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = NULL, .len = 0 }; if (i2c->xfer(i2c, &msg, 1) == 1) { SET_TUNER(frontend,0); @@ -199,8 +192,8 @@ int ves1820_init (struct dvb_frontend *frontend) u8 b0 [] = { 0xff }; u8 pwm; int i; - struct i2c_msg msg [] = { { addr: 0x50, flags: 0, buf: b0, len: 1 }, - { addr: 0x50, flags: I2C_M_RD, buf: &pwm, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x50, .flags = 0, .buf = b0, .len = 1 }, + { .addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1 } }; dprintk("VES1820: init chip\n"); diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c index b31ba21db6ed..743e79a891c2 100644 --- a/drivers/media/radio/miropcm20-radio.c +++ b/drivers/media/radio/miropcm20-radio.c @@ -217,26 +217,25 @@ static int pcm20_ioctl(struct inode *inode, struct file *file, } static struct pcm20_device pcm20_unit = { - freq: 87*16000, - muted: 1, - stereo: 0 + .freq = 87*16000, + .muted = 1, }; static struct file_operations pcm20_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: pcm20_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = pcm20_ioctl, + .llseek = no_llseek, }; static struct video_device pcm20_radio = { - owner: THIS_MODULE, - name: "Miro PCM 20 radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_RTRACK, - fops: &pcm20_fops, - priv: &pcm20_unit + .owner = THIS_MODULE, + .name = "Miro PCM 20 radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_RTRACK, + .fops = &pcm20_fops, + .priv = &pcm20_unit }; static int __init pcm20_init(void) diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c index 417115be2a0c..de795705ede2 100644 --- a/drivers/media/radio/miropcm20-rds.c +++ b/drivers/media/radio/miropcm20-rds.c @@ -105,10 +105,10 @@ static ssize_t rds_f_read(struct file *file, char *buffer, size_t length, loff_t } static struct file_operations rds_f_ops = { - owner: THIS_MODULE, - read: rds_f_read, - open: rds_f_open, - release: rds_f_release + .owner = THIS_MODULE, + .read = rds_f_read, + .open = rds_f_open, + .release = rds_f_release }; diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index d9c1906f93a3..1929f369d3bd 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -300,20 +300,20 @@ static int rt_ioctl(struct inode *inode, struct file *file, static struct rt_device rtrack_unit; static struct file_operations rtrack_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: rt_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = rt_ioctl, + .llseek = no_llseek, }; static struct video_device rtrack_radio= { - owner: THIS_MODULE, - name: "RadioTrack radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_RTRACK, - fops: &rtrack_fops, + .owner = THIS_MODULE, + .name = "RadioTrack radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_RTRACK, + .fops = &rtrack_fops, }; static int __init rtrack_init(void) diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 6ea87a0ecf35..e23e3d5f437e 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -252,20 +252,20 @@ static int az_ioctl(struct inode *inode, struct file *file, static struct az_device aztech_unit; static struct file_operations aztech_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: az_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = az_ioctl, + .llseek = no_llseek, }; static struct video_device aztech_radio= { - owner: THIS_MODULE, - name: "Aztech radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_AZTECH, - fops: &aztech_fops, + .owner = THIS_MODULE, + .name = "Aztech radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_AZTECH, + .fops = &aztech_fops, }; static int __init aztech_init(void) diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 01f99af1846a..8a2de2bb471c 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c @@ -524,21 +524,21 @@ static int cadet_release(struct inode *inode, struct file *file) static struct file_operations cadet_fops = { - owner: THIS_MODULE, - open: cadet_open, - release: cadet_release, - read: cadet_read, - ioctl: cadet_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = cadet_open, + .release = cadet_release, + .read = cadet_read, + .ioctl = cadet_ioctl, + .llseek = no_llseek, }; static struct video_device cadet_radio= { - owner: THIS_MODULE, - name: "Cadet radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_CADET, - fops: &cadet_fops, + .owner = THIS_MODULE, + .name = "Cadet radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_CADET, + .fops = &cadet_fops, }; static int isapnp_cadet_probe(void) diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 47540dba68de..a1b359a05d15 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -298,19 +298,19 @@ MODULE_DEVICE_TABLE( pci, gemtek_pci_id ); static u8 mx = 1; static struct file_operations gemtek_pci_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: gemtek_pci_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = gemtek_pci_ioctl, + .llseek = no_llseek, }; static struct video_device vdev_template = { - owner: THIS_MODULE, - name: "Gemtek PCI Radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_GEMTEK, - fops: &gemtek_pci_fops, + .owner = THIS_MODULE, + .name = "Gemtek PCI Radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_GEMTEK, + .fops = &gemtek_pci_fops, }; static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id ) @@ -387,10 +387,10 @@ static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev ) static struct pci_driver gemtek_pci_driver = { - name: "gemtek_pci", -id_table: gemtek_pci_id, - probe: gemtek_pci_probe, - remove: __devexit_p(gemtek_pci_remove), + .name = "gemtek_pci", + .id_table = gemtek_pci_id, + .probe = gemtek_pci_probe, + .remove = __devexit_p(gemtek_pci_remove), }; static int __init gemtek_pci_init_module( void ) diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index a502dbac3957..7a57b7cecb79 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c @@ -229,20 +229,20 @@ static int gemtek_ioctl(struct inode *inode, struct file *file, static struct gemtek_device gemtek_unit; static struct file_operations gemtek_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: gemtek_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = gemtek_ioctl, + .llseek = no_llseek, }; static struct video_device gemtek_radio= { - owner: THIS_MODULE, - name: "GemTek radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_GEMTEK, - fops: &gemtek_fops, + .owner = THIS_MODULE, + .name = "GemTek radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_GEMTEK, + .fops = &gemtek_fops, }; static int __init gemtek_init(void) diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 3c5892289e71..a675e86daa54 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c @@ -68,20 +68,20 @@ static int radio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static struct file_operations maestro_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: radio_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = radio_ioctl, + .llseek = no_llseek, }; static struct video_device maestro_radio= { - owner: THIS_MODULE, - name: "Maestro radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_SF16MI, - fops: &maestro_fops, + .owner = THIS_MODULE, + .name = "Maestro radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_SF16MI, + .fops = &maestro_fops, }; static struct radio_device diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 16ebd078a06e..8830f0aaf6b1 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -76,19 +76,19 @@ static int radio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static struct file_operations maxiradio_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: radio_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = radio_ioctl, + .llseek = no_llseek, }; static struct video_device maxiradio_radio = { - owner: THIS_MODULE, - name: "Maxi Radio FM2000 radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_SF16MI, - fops: &maxiradio_fops, + .owner = THIS_MODULE, + .name = "Maxi Radio FM2000 radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_SF16MI, + .fops = &maxiradio_fops, }; static struct radio_device @@ -336,10 +336,10 @@ static struct pci_device_id maxiradio_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, maxiradio_pci_tbl); static struct pci_driver maxiradio_driver = { - name: "radio-maxiradio", - id_table: maxiradio_pci_tbl, - probe: maxiradio_init_one, - remove: __devexit_p(maxiradio_remove_one), + .name = "radio-maxiradio", + .id_table = maxiradio_pci_tbl, + .probe = maxiradio_init_one, + .remove = __devexit_p(maxiradio_remove_one), }; int __init maxiradio_radio_init(void) diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index 8ec9cbcfd571..8e6fe4d268cc 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c @@ -195,20 +195,20 @@ static int rt_ioctl(struct inode *inode, struct file *file, static struct rt_device rtrack2_unit; static struct file_operations rtrack2_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: rt_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = rt_ioctl, + .llseek = no_llseek, }; static struct video_device rtrack2_radio= { - owner: THIS_MODULE, - name: "RadioTrack II radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_RTRACK2, - fops: &rtrack2_fops, + .owner = THIS_MODULE, + .name = "RadioTrack II radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_RTRACK2, + .fops = &rtrack2_fops, }; static int __init rtrack2_init(void) diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index c227a24c2b1c..53c8509ba8f2 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -223,20 +223,20 @@ static int fmi_ioctl(struct inode *inode, struct file *file, static struct fmi_device fmi_unit; static struct file_operations fmi_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: fmi_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = fmi_ioctl, + .llseek = no_llseek, }; static struct video_device fmi_radio= { - owner: THIS_MODULE, - name: "SF16FMx radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_SF16MI, - fops: &fmi_fops, + .owner = THIS_MODULE, + .name = "SF16FMx radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_SF16MI, + .fops = &fmi_fops, }; /* ladis: this is my card. does any other types exist? */ diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index 8ec2682c6a0b..2459573203b9 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c @@ -272,20 +272,20 @@ static int tt_ioctl(struct inode *inode, struct file *file, static struct tt_device terratec_unit; static struct file_operations terratec_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: tt_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = tt_ioctl, + .llseek = no_llseek, }; static struct video_device terratec_radio= { - owner: THIS_MODULE, - name: "TerraTec ActiveRadio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_TERRATEC, - fops: &terratec_fops, + .owner = THIS_MODULE, + .name = "TerraTec ActiveRadio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_TERRATEC, + .fops = &terratec_fops, }; static int __init terratec_init(void) diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 6cd0f6aa41a6..8dd4cd2e1dbd 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c @@ -251,20 +251,20 @@ static int tr_ioctl(struct inode *inode, struct file *file, } static struct file_operations trust_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: tr_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = tr_ioctl, + .llseek = no_llseek, }; static struct video_device trust_radio= { - owner: THIS_MODULE, - name: "Trust FM Radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_TRUST, - fops: &trust_fops, + .owner = THIS_MODULE, + .name = "Trust FM Radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_TRUST, + .fops = &trust_fops, }; static int __init trust_init(void) diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 66bdcc01fd22..f1db827ee708 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c @@ -251,26 +251,26 @@ static int typhoon_ioctl(struct inode *inode, struct file *file, static struct typhoon_device typhoon_unit = { - iobase: CONFIG_RADIO_TYPHOON_PORT, - curfreq: CONFIG_RADIO_TYPHOON_MUTEFREQ, - mutefreq: CONFIG_RADIO_TYPHOON_MUTEFREQ, + .iobase = CONFIG_RADIO_TYPHOON_PORT, + .curfreq = CONFIG_RADIO_TYPHOON_MUTEFREQ, + .mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ, }; static struct file_operations typhoon_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: typhoon_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = typhoon_ioctl, + .llseek = no_llseek, }; static struct video_device typhoon_radio = { - owner: THIS_MODULE, - name: "Typhoon Radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_TYPHOON, - fops: &typhoon_fops, + .owner = THIS_MODULE, + .name = "Typhoon Radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_TYPHOON, + .fops = &typhoon_fops, }; #ifdef CONFIG_RADIO_TYPHOON_PROC_FS diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 8add82dbae6b..2c309c5e8ed1 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c @@ -320,20 +320,20 @@ static struct zol_device zoltrix_unit; static struct file_operations zoltrix_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: zol_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = zol_ioctl, + .llseek = no_llseek, }; static struct video_device zoltrix_radio = { - owner: THIS_MODULE, - name: "Zoltrix Radio Plus", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_ZOLTRIX, - fops: &zoltrix_fops, + .owner = THIS_MODULE, + .name = "Zoltrix Radio Plus", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_ZOLTRIX, + .fops = &zoltrix_fops, }; static int __init zoltrix_init(void) diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index 0b84b028e455..0936646dbc8d 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c @@ -410,30 +410,30 @@ static void adv717x_dec_use(struct i2c_client *client) /* ----------------------------------------------------------------------- */ static struct i2c_driver i2c_driver_adv7175 = { - name: "adv7175", /* name */ - id: I2C_DRIVERID_ADV717x, /* ID */ - flags: I2C_DF_NOTIFY, //I2C_ADV7175, I2C_ADV7175 + 3, - attach_adapter: adv717x_probe, - detach_client: adv717x_detach, - command: adv717x_command, - inc_use: &adv717x_inc_use, - dec_use: &adv717x_dec_use + .name = "adv7175", /* name */ + .id = I2C_DRIVERID_ADV717x, /* ID */ + .flags = I2C_DF_NOTIFY, //I2C_ADV7175, I2C_ADV7175 + 3, + .attach_adapter = adv717x_probe, + .detach_client = adv717x_detach, + .command = adv717x_command, + .inc_use = &adv717x_inc_use, + .dec_use = &adv717x_dec_use }; static struct i2c_driver i2c_driver_adv7176 = { - name: "adv7176", /* name */ - id: I2C_DRIVERID_ADV717x, /* ID */ - flags: I2C_DF_NOTIFY, //I2C_ADV7176, I2C_ADV7176 + 3, - attach_adapter: adv717x_probe, - detach_client: adv717x_detach, - command: adv717x_command, - inc_use: &adv717x_inc_use, - dec_use: &adv717x_dec_use + .name = "adv7176", /* name */ + .id = I2C_DRIVERID_ADV717x, /* ID */ + .flags = I2C_DF_NOTIFY, //I2C_ADV7176, I2C_ADV7176 + 3, + .attach_adapter = adv717x_probe, + .detach_client = adv717x_detach, + .command = adv717x_command, + .inc_use = &adv717x_inc_use, + .dec_use = &adv717x_dec_use }; static struct i2c_client client_template = { - name: "adv7175_client", - driver: &i2c_driver_adv7175 + .name = "adv7175_client", + .driver = &i2c_driver_adv7175 }; static int adv717x_init(void) diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index 77397b9eced0..892307b07ea3 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c @@ -208,350 +208,350 @@ static struct CARD { struct tvcard bttv_tvcards[] = { { /* ---- card 0x00 ---------------------------------- */ - name: " *** UNKNOWN/GENERIC *** ", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - muxsel: { 2, 3, 1, 0}, - tuner_type: -1, -},{ - name: "MIRO PCTV", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 15, - muxsel: { 2, 3, 1, 1}, - audiomux: { 2, 0, 0, 0, 10}, - needs_tvaudio: 1, - tuner_type: -1, -},{ - name: "Hauppauge (bt848)", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 7, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 1, 2, 3, 4}, - needs_tvaudio: 1, - tuner_type: -1, -},{ - name: "STB, Gateway P/N 6000699 (bt848)", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 7, - muxsel: { 2, 3, 1, 1}, - audiomux: { 4, 0, 2, 3, 1}, - no_msp34xx: 1, - needs_tvaudio: 1, - tuner_type: TUNER_PHILIPS_NTSC, - pll: PLL_28, - has_radio: 1, + .name = " *** UNKNOWN/GENERIC *** ", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .muxsel = { 2, 3, 1, 0}, + .tuner_type = -1, +},{ + .name = "MIRO PCTV", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 15, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 2, 0, 0, 0, 10}, + .needs_tvaudio = 1, + .tuner_type = -1, +},{ + .name = "Hauppauge (bt848)", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 7, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 1, 2, 3, 4}, + .needs_tvaudio = 1, + .tuner_type = -1, +},{ + .name = "STB, Gateway P/N 6000699 (bt848)", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 7, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 4, 0, 2, 3, 1}, + .no_msp34xx = 1, + .needs_tvaudio = 1, + .tuner_type = TUNER_PHILIPS_NTSC, + .pll = PLL_28, + .has_radio = 1, },{ /* ---- card 0x04 ---------------------------------- */ - name: "Intel Create and Share PCI/ Smart Video Recorder III", - video_inputs: 4, - audio_inputs: 0, - tuner: -1, - svhs: 2, - gpiomask: 0, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0 }, - needs_tvaudio: 0, - tuner_type: 4, -},{ - name: "Diamond DTV2000", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 3, - muxsel: { 2, 3, 1, 0}, - audiomux: { 0, 1, 0, 1, 3}, - needs_tvaudio: 1, - tuner_type: -1, -},{ - name: "AVerMedia TVPhone", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 3, - muxsel: { 2, 3, 1, 1}, - gpiomask: 0x0f, - audiomux: { 0x0c, 0x04, 0x08, 0x04, 0}, + .name = "Intel Create and Share PCI/ Smart Video Recorder III", + .video_inputs = 4, + .audio_inputs = 0, + .tuner = -1, + .svhs = 2, + .gpiomask = 0, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0 }, + .needs_tvaudio = 0, + .tuner_type = 4, +},{ + .name = "Diamond DTV2000", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 3, + .muxsel = { 2, 3, 1, 0}, + .audiomux = { 0, 1, 0, 1, 3}, + .needs_tvaudio = 1, + .tuner_type = -1, +},{ + .name = "AVerMedia TVPhone", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 3, + .muxsel = { 2, 3, 1, 1}, + .gpiomask = 0x0f, + .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0}, /* 0x04 for some cards ?? */ - needs_tvaudio: 1, - tuner_type: -1, - audio_hook: avermedia_tvphone_audio, -},{ - name: "MATRIX-Vision MV-Delta", - video_inputs: 5, - audio_inputs: 1, - tuner: -1, - svhs: 3, - gpiomask: 0, - muxsel: { 2, 3, 1, 0, 0}, - audiomux: {0 }, - needs_tvaudio: 1, - tuner_type: -1, + .needs_tvaudio = 1, + .tuner_type = -1, + .audio_hook = avermedia_tvphone_audio, +},{ + .name = "MATRIX-Vision MV-Delta", + .video_inputs = 5, + .audio_inputs = 1, + .tuner = -1, + .svhs = 3, + .gpiomask = 0, + .muxsel = { 2, 3, 1, 0, 0}, + .audiomux = {0 }, + .needs_tvaudio = 1, + .tuner_type = -1, },{ /* ---- card 0x08 ---------------------------------- */ - name: "Lifeview FlyVideo II (Bt848) LR26", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xc00, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 0xc00, 0x800, 0x400, 0xc00, 0}, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, -},{ - name: "IMS/IXmicro TurboTV", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 3, - muxsel: { 2, 3, 1, 1}, - audiomux: { 1, 1, 2, 3, 0}, - needs_tvaudio: 0, - pll: PLL_28, - tuner_type: TUNER_TEMIC_PAL, -},{ - name: "Hauppauge (bt878)", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x0f, /* old: 7 */ - muxsel: { 2, 0, 1, 1}, - audiomux: { 0, 1, 2, 3, 4}, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, -},{ - name: "MIRO PCTV pro", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x3014f, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0x20001,0x10001, 0, 0,10}, - needs_tvaudio: 1, - tuner_type: -1, + .name = "Lifeview FlyVideo II (Bt848) LR26", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xc00, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0}, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "IMS/IXmicro TurboTV", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 3, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 1, 1, 2, 3, 0}, + .needs_tvaudio = 0, + .pll = PLL_28, + .tuner_type = TUNER_TEMIC_PAL, +},{ + .name = "Hauppauge (bt878)", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x0f, /* old: 7 */ + .muxsel = { 2, 0, 1, 1}, + .audiomux = { 0, 1, 2, 3, 4}, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "MIRO PCTV pro", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x3014f, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0x20001,0x10001, 0, 0,10}, + .needs_tvaudio = 1, + .tuner_type = -1, },{ /* ---- card 0x0c ---------------------------------- */ - name: "ADS Technologies Channel Surfer TV (bt848)", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 15, - muxsel: { 2, 3, 1, 1}, - audiomux: { 13, 14, 11, 7, 0, 0}, - needs_tvaudio: 1, - tuner_type: -1, -},{ - name: "AVerMedia TVCapture 98", - video_inputs: 3, - audio_inputs: 4, - tuner: 0, - svhs: 2, - gpiomask: 15, - muxsel: { 2, 3, 1, 1}, - audiomux: { 13, 14, 11, 7, 0, 0}, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: TUNER_PHILIPS_PAL, -},{ - name: "Aimslab Video Highway Xtreme (VHX)", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 7, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */ - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, -},{ - name: "Zoltrix TV-Max", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 15, - muxsel: { 2, 3, 1, 1}, - audiomux: {0 , 0, 1 , 0, 10}, - needs_tvaudio: 1, - tuner_type: -1, + .name = "ADS Technologies Channel Surfer TV (bt848)", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 15, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 13, 14, 11, 7, 0, 0}, + .needs_tvaudio = 1, + .tuner_type = -1, +},{ + .name = "AVerMedia TVCapture 98", + .video_inputs = 3, + .audio_inputs = 4, + .tuner = 0, + .svhs = 2, + .gpiomask = 15, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 13, 14, 11, 7, 0, 0}, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = TUNER_PHILIPS_PAL, +},{ + .name = "Aimslab Video Highway Xtreme (VHX)", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 7, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */ + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "Zoltrix TV-Max", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 15, + .muxsel = { 2, 3, 1, 1}, + .audiomux = {0 , 0, 1 , 0, 10}, + .needs_tvaudio = 1, + .tuner_type = -1, },{ /* ---- card 0x10 ---------------------------------- */ - name: "Prolink Pixelview PlayTV (bt878)", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x01fe00, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 }, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, -},{ - name: "Leadtek WinView 601", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x8300f8, - muxsel: { 2, 3, 1, 1,0}, - audiomux: { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}, - needs_tvaudio: 1, - tuner_type: -1, - audio_hook: winview_audio, - has_radio: 1, -},{ - name: "AVEC Intercapture", - video_inputs: 3, - audio_inputs: 2, - tuner: 0, - svhs: 2, - gpiomask: 0, - muxsel: {2, 3, 1, 1}, - audiomux: {1, 0, 0, 0, 0}, - needs_tvaudio: 1, - tuner_type: -1, -},{ - name: "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", - video_inputs: 4, - audio_inputs: 1, - tuner: -1, - svhs: -1, - gpiomask: 0x8dff00, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0 }, - no_msp34xx: 1, - tuner_type: -1, + .name = "Prolink Pixelview PlayTV (bt878)", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x01fe00, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 }, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "Leadtek WinView 601", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x8300f8, + .muxsel = { 2, 3, 1, 1,0}, + .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}, + .needs_tvaudio = 1, + .tuner_type = -1, + .audio_hook = winview_audio, + .has_radio = 1, +},{ + .name = "AVEC Intercapture", + .video_inputs = 3, + .audio_inputs = 2, + .tuner = 0, + .svhs = 2, + .gpiomask = 0, + .muxsel = {2, 3, 1, 1}, + .audiomux = {1, 0, 0, 0, 0}, + .needs_tvaudio = 1, + .tuner_type = -1, +},{ + .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = -1, + .svhs = -1, + .gpiomask = 0x8dff00, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0 }, + .no_msp34xx = 1, + .tuner_type = -1, },{ /* ---- card 0x14 ---------------------------------- */ - name: "CEI Raffles Card", - video_inputs: 3, - audio_inputs: 3, - tuner: 0, - svhs: 2, - muxsel: {2, 3, 1, 1}, - tuner_type: -1, -},{ - name: "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", - video_inputs: 4, - audio_inputs: 2, // tuner, line in - tuner: 0, - svhs: 2, - gpiomask: 0x1800, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 0x800, 0x1000, 0x1000, 0x1800}, - pll: PLL_28, - tuner_type: TUNER_PHILIPS_PAL_I, -},{ - name: "Askey CPH050/ Phoebe Tv Master + FM", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xc00, - muxsel: { 2, 3, 1, 1}, - audiomux: {0, 1, 0x800, 0x400, 0xc00, 0}, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, -},{ - name: "Modular Technology MM205 PCTV, bt878", - video_inputs: 2, - audio_inputs: 1, - tuner: 0, - svhs: -1, - gpiomask: 7, - muxsel: { 2, 3 }, - audiomux: { 0, 0, 0, 0, 0 }, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: TUNER_ALPS_TSBB5_PAL_I, + .name = "CEI Raffles Card", + .video_inputs = 3, + .audio_inputs = 3, + .tuner = 0, + .svhs = 2, + .muxsel = {2, 3, 1, 1}, + .tuner_type = -1, +},{ + .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", + .video_inputs = 4, + .audio_inputs = 2, // tuner, line in + .tuner = 0, + .svhs = 2, + .gpiomask = 0x1800, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, + .pll = PLL_28, + .tuner_type = TUNER_PHILIPS_PAL_I, +},{ + .name = "Askey CPH050/ Phoebe Tv Master + FM", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xc00, + .muxsel = { 2, 3, 1, 1}, + .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0}, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "Modular Technology MM205 PCTV, bt878", + .video_inputs = 2, + .audio_inputs = 1, + .tuner = 0, + .svhs = -1, + .gpiomask = 7, + .muxsel = { 2, 3 }, + .audiomux = { 0, 0, 0, 0, 0 }, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_ALPS_TSBB5_PAL_I, },{ /* ---- card 0x18 ---------------------------------- */ - name: "Askey CPH05X/06X (bt878) [many vendors]", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xe00, - muxsel: { 2, 3, 1, 1}, - audiomux: {0x400, 0x400, 0x400, 0x400, 0xc00}, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, -},{ - name: "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x1f0fff, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0x20000, 0x30000, 0x10000, 0, 0x40000}, - needs_tvaudio: 0, - tuner_type: TUNER_PHILIPS_PAL, - audio_hook: terratv_audio, -},{ - name: "Hauppauge WinCam newer (bt878)", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 3, - gpiomask: 7, - muxsel: { 2, 0, 1, 1}, - audiomux: { 0, 1, 2, 3, 4}, - needs_tvaudio: 1, - tuner_type: -1, -},{ - name: "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", - video_inputs: 4, - audio_inputs: 2, - tuner: 0, - svhs: 2, - gpiomask: 0x1800, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 0x800, 0x1000, 0x1000, 0x1800}, - pll: PLL_28, - tuner_type: TUNER_PHILIPS_SECAM, + .name = "Askey CPH05X/06X (bt878) [many vendors]", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xe00, + .muxsel = { 2, 3, 1, 1}, + .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00}, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x1f0fff, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000}, + .needs_tvaudio = 0, + .tuner_type = TUNER_PHILIPS_PAL, + .audio_hook = terratv_audio, +},{ + .name = "Hauppauge WinCam newer (bt878)", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 3, + .gpiomask = 7, + .muxsel = { 2, 0, 1, 1}, + .audiomux = { 0, 1, 2, 3, 4}, + .needs_tvaudio = 1, + .tuner_type = -1, +},{ + .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", + .video_inputs = 4, + .audio_inputs = 2, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x1800, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, + .pll = PLL_28, + .tuner_type = TUNER_PHILIPS_SECAM, },{ /* ---- card 0x1c ---------------------------------- */ - name: "Terratec TerraTV+ Version 1.1 (bt878)", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x1f0fff, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000}, - needs_tvaudio: 0, - tuner_type: TUNER_PHILIPS_PAL, - audio_hook: terratv_audio, + .name = "Terratec TerraTV+ Version 1.1 (bt878)", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x1f0fff, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000}, + .needs_tvaudio = 0, + .tuner_type = TUNER_PHILIPS_PAL, + .audio_hook = terratv_audio, /* GPIO wiring: External 20 pin connector (for Active Radio Upgrade board) gpio00: i2c-sda @@ -585,71 +585,71 @@ struct tvcard bttv_tvcards[] = { },{ /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */ - name: "Imagenation PXC200", - video_inputs: 5, - audio_inputs: 1, - tuner: -1, - svhs: 1, /* was: 4 */ - gpiomask: 0, - muxsel: { 2, 3, 1, 0, 0}, - audiomux: { 0 }, - needs_tvaudio: 1, - tuner_type: -1, -},{ - name: "Lifeview FlyVideo 98 LR50", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x1800, //0x8dfe00 - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 }, - pll: PLL_28, - tuner_type: -1, -},{ - name: "Formac iProTV", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 1, - muxsel: { 2, 3, 1, 1}, - audiomux: { 1, 0, 0, 0, 0 }, - tuner_type: -1, + .name = "Imagenation PXC200", + .video_inputs = 5, + .audio_inputs = 1, + .tuner = -1, + .svhs = 1, /* was: 4 */ + .gpiomask = 0, + .muxsel = { 2, 3, 1, 0, 0}, + .audiomux = { 0 }, + .needs_tvaudio = 1, + .tuner_type = -1, +},{ + .name = "Lifeview FlyVideo 98 LR50", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x1800, //0x8dfe00 + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 }, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "Formac iProTV", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 1, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 1, 0, 0, 0, 0 }, + .tuner_type = -1, },{ /* ---- card 0x20 ---------------------------------- */ - name: "Intel Create and Share PCI/ Smart Video Recorder III", - video_inputs: 4, - audio_inputs: 0, - tuner: -1, - svhs: 2, - gpiomask: 0, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0 }, - needs_tvaudio: 0, - tuner_type: 4, -},{ - name: "Terratec TerraTValue Version Bt878", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xffff00, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0x500, 0, 0x300, 0x900, 0x900}, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: TUNER_PHILIPS_PAL, -},{ - name: "Leadtek WinFast 2000/ WinFast 2000 XP", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xc33000, - muxsel: { 2, 3, 1, 1, 0}, // TV, CVid, SVid, CVid over SVid connector - audiomux: { 0x422000,0x1000,0x0000,0x620000,0x800000}, + .name = "Intel Create and Share PCI/ Smart Video Recorder III", + .video_inputs = 4, + .audio_inputs = 0, + .tuner = -1, + .svhs = 2, + .gpiomask = 0, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0 }, + .needs_tvaudio = 0, + .tuner_type = 4, +},{ + .name = "Terratec TerraTValue Version Bt878", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xffff00, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0x500, 0, 0x300, 0x900, 0x900}, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = TUNER_PHILIPS_PAL, +},{ + .name = "Leadtek WinFast 2000/ WinFast 2000 XP", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xc33000, + .muxsel = { 2, 3, 1, 1, 0}, // TV, CVid, SVid, CVid over SVid connector + .audiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000}, /* Audio Routing for "WinFast 2000 XP" (no tv stereo !) gpio23 -- hef4052:nEnable (0x800000) gpio12 -- hef4052:A1 @@ -661,216 +661,216 @@ struct tvcard bttv_tvcards[] = { Note: There exists another variant "Winfast 2000" with tv stereo !? Note: eeprom only contains FF and pci subsystem id 107d:6606 */ - needs_tvaudio: 0, - pll: PLL_28, - has_radio: 1, - tuner_type: 5, // default for now, gpio reads BFFF06 for Pal bg+dk - audio_hook: winfast2000_audio, -},{ - name: "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II", - video_inputs: 4, - audio_inputs: 3, - tuner: 0, - svhs: 2, - gpiomask: 0x1800, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 0x800, 0x1000, 0x1000, 0x1800}, - pll: PLL_28, - tuner_type: -1, + .needs_tvaudio = 0, + .pll = PLL_28, + .has_radio = 1, + .tuner_type = 5, // default for now, gpio reads BFFF06 for Pal bg+dk + .audio_hook = winfast2000_audio, +},{ + .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II", + .video_inputs = 4, + .audio_inputs = 3, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x1800, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, + .pll = PLL_28, + .tuner_type = -1, },{ /* ---- card 0x24 ---------------------------------- */ - name: "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner", - video_inputs: 4, - audio_inputs: 3, - tuner: 0, - svhs: 2, - gpiomask: 0x1800, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, - pll: PLL_28, - tuner_type: -1, - has_radio: 1, -},{ - name: "Prolink PixelView PlayTV pro", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xff, - muxsel: { 2, 3, 1, 1 }, - audiomux: { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 }, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: -1, -},{ - name: "Askey CPH06X TView99", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x551e00, - muxsel: { 2, 3, 1, 0}, - audiomux: { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 }, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, -},{ - name: "Pinnacle PCTV Studio/Rave", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x03000F, - muxsel: { 2, 3, 1, 1}, - audiomux: { 2, 0, 0, 0, 1}, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, + .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner", + .video_inputs = 4, + .audio_inputs = 3, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x1800, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, + .pll = PLL_28, + .tuner_type = -1, + .has_radio = 1, +},{ + .name = "Prolink PixelView PlayTV pro", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xff, + .muxsel = { 2, 3, 1, 1 }, + .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 }, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "Askey CPH06X TView99", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x551e00, + .muxsel = { 2, 3, 1, 0}, + .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 }, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "Pinnacle PCTV Studio/Rave", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x03000F, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 2, 0, 0, 0, 1}, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, },{ /* ---- card 0x28 ---------------------------------- */ - name: "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 7, - muxsel: { 2, 3, 1, 1}, - audiomux: { 4, 0, 2, 3, 1}, - no_msp34xx: 1, - needs_tvaudio: 1, - tuner_type: TUNER_PHILIPS_NTSC, - pll: PLL_28, - has_radio: 1, -},{ - name: "AVerMedia TVPhone 98", - video_inputs: 3, - audio_inputs: 4, - tuner: 0, - svhs: 2, - gpiomask: 15, - muxsel: { 2, 3, 1, 1}, - audiomux: { 13, 4, 11, 7, 0, 0}, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, - has_radio: 1, -},{ - name: "ProVideo PV951", /* pic16c54 */ - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 0, 0, 0, 0}, - needs_tvaudio: 1, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: 1, -},{ - name: "Little OnAir TV", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xe00b, - muxsel: {2, 3, 1, 1}, - audiomux: {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc}, - no_msp34xx: 1, - tuner_type: -1, + .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 7, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 4, 0, 2, 3, 1}, + .no_msp34xx = 1, + .needs_tvaudio = 1, + .tuner_type = TUNER_PHILIPS_NTSC, + .pll = PLL_28, + .has_radio = 1, +},{ + .name = "AVerMedia TVPhone 98", + .video_inputs = 3, + .audio_inputs = 4, + .tuner = 0, + .svhs = 2, + .gpiomask = 15, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 13, 4, 11, 7, 0, 0}, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, + .has_radio = 1, +},{ + .name = "ProVideo PV951", /* pic16c54 */ + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 0, 0, 0, 0}, + .needs_tvaudio = 1, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = 1, +},{ + .name = "Little OnAir TV", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xe00b, + .muxsel = {2, 3, 1, 1}, + .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc}, + .no_msp34xx = 1, + .tuner_type = -1, },{ /* ---- card 0x2c ---------------------------------- */ - name: "Sigma TVII-FM", - video_inputs: 2, - audio_inputs: 1, - tuner: 0, - svhs: -1, - gpiomask: 3, - muxsel: {2, 3, 1, 1}, - audiomux: {1, 1, 0, 2, 3}, - no_msp34xx: 1, - pll: PLL_NONE, - tuner_type: -1, -},{ - name: "MATRIX-Vision MV-Delta 2", - video_inputs: 5, - audio_inputs: 1, - tuner: -1, - svhs: 3, - gpiomask: 0, - muxsel: { 2, 3, 1, 0, 0}, - audiomux: {0 }, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: -1, -},{ - name: "Zoltrix Genie TV/FM", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xbcf03f, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f}, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: 21, -},{ - name: "Terratec TV/Radio+", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x70000, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 }, - needs_tvaudio: 1, - no_msp34xx: 1, - pll: PLL_35, - tuner_type: 1, - has_radio: 1, + .name = "Sigma TVII-FM", + .video_inputs = 2, + .audio_inputs = 1, + .tuner = 0, + .svhs = -1, + .gpiomask = 3, + .muxsel = {2, 3, 1, 1}, + .audiomux = {1, 1, 0, 2, 3}, + .no_msp34xx = 1, + .pll = PLL_NONE, + .tuner_type = -1, +},{ + .name = "MATRIX-Vision MV-Delta 2", + .video_inputs = 5, + .audio_inputs = 1, + .tuner = -1, + .svhs = 3, + .gpiomask = 0, + .muxsel = { 2, 3, 1, 0, 0}, + .audiomux = {0 }, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "Zoltrix Genie TV/FM", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xbcf03f, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f}, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = 21, +},{ + .name = "Terratec TV/Radio+", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x70000, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 }, + .needs_tvaudio = 1, + .no_msp34xx = 1, + .pll = PLL_35, + .tuner_type = 1, + .has_radio = 1, },{ /* ---- card 0x30 ---------------------------------- */ - name: "Askey CPH03x/ Dynalink Magic TView", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 15, - muxsel: { 2, 3, 1, 1}, - audiomux: {2,0,0,0,1}, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, -},{ - name: "IODATA GV-BCTV3/PCI", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x010f00, - muxsel: {2, 3, 0, 0}, - audiomux: {0x10000, 0, 0x10000, 0, 0, 0}, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: TUNER_ALPS_TSHC6_NTSC, - audio_hook: gvbctv3pci_audio, -},{ - name: "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 3, - gpiomask: 0xAA0000, - muxsel: { 2,3,1,1 }, - audiomux: { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 }, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: TUNER_PHILIPS_PAL_I, + .name = "Askey CPH03x/ Dynalink Magic TView", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 15, + .muxsel = { 2, 3, 1, 1}, + .audiomux = {2,0,0,0,1}, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "IODATA GV-BCTV3/PCI", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x010f00, + .muxsel = {2, 3, 0, 0}, + .audiomux = {0x10000, 0, 0x10000, 0, 0, 0}, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_ALPS_TSHC6_NTSC, + .audio_hook = gvbctv3pci_audio, +},{ + .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 3, + .gpiomask = 0xAA0000, + .muxsel = { 2,3,1,1 }, + .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 }, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_PHILIPS_PAL_I, /* GPIO wiring: (different from Rev.4C !) GPIO17: U4.A0 (first hef4052bt) GPIO19: U4.A1 @@ -881,28 +881,28 @@ struct tvcard bttv_tvcards[] = { Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22 */ },{ - name: "Eagle Wireless Capricorn2 (bt878A)", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 7, - muxsel: { 2, 0, 1, 1}, - audiomux: { 0, 1, 2, 3, 4}, - pll: PLL_28, - tuner_type: -1 /* TUNER_ALPS_TMDH2_NTSC */, + .name = "Eagle Wireless Capricorn2 (bt878A)", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 7, + .muxsel = { 2, 0, 1, 1}, + .audiomux = { 0, 1, 2, 3, 4}, + .pll = PLL_28, + .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */, },{ /* ---- card 0x34 ---------------------------------- */ /* David Härdeman <david@2gen.com> */ - name: "Pinnacle PCTV Studio Pro", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x03000F, - muxsel: { 2, 3, 1, 1}, - audiomux: { 1, 0x10001, 0, 0, 10}, + .name = "Pinnacle PCTV Studio Pro", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x03000F, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 1, 0x10001, 0, 0, 10}, /* sound path (5 sources): MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable) 0= ext. Audio IN @@ -912,273 +912,273 @@ struct tvcard bttv_tvcards[] = { MUX2 (mask 0x30000): 0,2,3= from MSP34xx 1= FM stereo Radio from Tuner */ - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, },{ /* Claas Langbehn <claas@bigfoot.com>, Sven Grothklags <sven@upb.de> */ - name: "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS", - video_inputs: 3, - audio_inputs: 3, - tuner: 0, - svhs: 2, - gpiomask: 0x1c, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 0, 0x10, 8, 4 }, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: TUNER_PHILIPS_PAL_I, - has_radio: 1, + .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS", + .video_inputs = 3, + .audio_inputs = 3, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x1c, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 0, 0x10, 8, 4 }, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = TUNER_PHILIPS_PAL_I, + .has_radio = 1, },{ /* Tim Röstermundt <rosterm@uni-muenster.de> in de.comp.os.unix.linux.hardware: options bttv card=0 pll=1 radio=1 gpiomask=0x18e0 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff options tuner type=5 */ - name: "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x18e0, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0x0000,0x0800,0x1000,0x1000,0x18e0 }, + .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x18e0, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 }, /* For cards with tda9820/tda9821: 0x0000: Tuner normal stereo 0x0080: Tuner A2 SAP (second audio program = Zweikanalton) 0x0880: Tuner A2 stereo */ - pll: PLL_28, - tuner_type: -1, + .pll = PLL_28, + .tuner_type = -1, },{ /* Miguel Angel Alvarez <maacruz@navegalia.com> old Easy TV BT848 version (model CPH031) */ - name: "Askey CPH031/ BESTBUY Easy TV", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xF, - muxsel: { 2, 3, 1, 0}, - audiomux: { 2, 0, 0, 0, 10}, - needs_tvaudio: 0, - pll: PLL_28, - tuner_type: TUNER_TEMIC_PAL, + .name = "Askey CPH031/ BESTBUY Easy TV", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xF, + .muxsel = { 2, 3, 1, 0}, + .audiomux = { 2, 0, 0, 0, 10}, + .needs_tvaudio = 0, + .pll = PLL_28, + .tuner_type = TUNER_TEMIC_PAL, },{ /* ---- card 0x38 ---------------------------------- */ /* Gordon Heydon <gjheydon@bigfoot.com ('98) */ - name: "Lifeview FlyVideo 98FM LR50", - video_inputs: 4, - audio_inputs: 3, - tuner: 0, - svhs: 2, - gpiomask: 0x1800, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, - pll: PLL_28, - tuner_type: 5, + .name = "Lifeview FlyVideo 98FM LR50", + .video_inputs = 4, + .audio_inputs = 3, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x1800, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, + .pll = PLL_28, + .tuner_type = 5, },{ /* This is the ultimate cheapo capture card * just a BT848A on a small PCB! * Steve Hosgood <steve@equiinet.com> */ - name: "GrandTec 'Grand Video Capture' (Bt848)", - video_inputs: 2, - audio_inputs: 0, - tuner: -1, - svhs: 1, - gpiomask: 0, - muxsel: { 3, 1 }, - audiomux: { 0 }, - needs_tvaudio: 0, - no_msp34xx: 1, - pll: PLL_35, - tuner_type: -1, + .name = "GrandTec 'Grand Video Capture' (Bt848)", + .video_inputs = 2, + .audio_inputs = 0, + .tuner = -1, + .svhs = 1, + .gpiomask = 0, + .muxsel = { 3, 1 }, + .audiomux = { 0 }, + .needs_tvaudio = 0, + .no_msp34xx = 1, + .pll = PLL_35, + .tuner_type = -1, },{ /* Daniel Herrington <daniel.herrington@home.com> */ - name: "Askey CPH060/ Phoebe TV Master Only (No FM)", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xe00, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 }, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: TUNER_TEMIC_4036FY5_NTSC, + .name = "Askey CPH060/ Phoebe TV Master Only (No FM)", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xe00, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 }, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = TUNER_TEMIC_4036FY5_NTSC, },{ /* Matti Mottus <mottus@physic.ut.ee> */ - name: "Askey CPH03x TV Capturer", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x03000F, - muxsel: { 2, 3, 1, 0}, - audiomux: { 2,0,0,0,1 }, - pll: PLL_28, - tuner_type: 0, + .name = "Askey CPH03x TV Capturer", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x03000F, + .muxsel = { 2, 3, 1, 0}, + .audiomux = { 2,0,0,0,1 }, + .pll = PLL_28, + .tuner_type = 0, },{ /* ---- card 0x3c ---------------------------------- */ /* Philip Blundell <philb@gnu.org> */ - name: "Modular Technology MM100PCTV", - video_inputs: 2, - audio_inputs: 2, - tuner: 0, - svhs: -1, - gpiomask: 11, - muxsel: { 2, 3, 1, 1}, - audiomux: { 2, 0, 0, 1, 8}, - pll: PLL_35, - tuner_type: TUNER_TEMIC_PAL, + .name = "Modular Technology MM100PCTV", + .video_inputs = 2, + .audio_inputs = 2, + .tuner = 0, + .svhs = -1, + .gpiomask = 11, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 2, 0, 0, 1, 8}, + .pll = PLL_35, + .tuner_type = TUNER_TEMIC_PAL, },{ /* Adrian Cox <adrian@humboldt.co.uk */ - name: "AG Electronics GMV1", - video_inputs: 2, - audio_inputs: 0, - tuner: -1, - svhs: 1, - gpiomask: 0xF, - muxsel: { 2, 2}, - audiomux: { }, - no_msp34xx: 1, - needs_tvaudio: 0, - pll: PLL_28, - tuner_type: -1, + .name = "AG Electronics GMV1", + .video_inputs = 2, + .audio_inputs = 0, + .tuner = -1, + .svhs = 1, + .gpiomask = 0xF, + .muxsel = { 2, 2}, + .audiomux = { }, + .no_msp34xx = 1, + .needs_tvaudio = 0, + .pll = PLL_28, + .tuner_type = -1, },{ /* Miguel Angel Alvarez <maacruz@navegalia.com> new Easy TV BT878 version (model CPH061) special thanks to Informatica Mieres for providing the card */ - name: "Askey CPH061/ BESTBUY Easy TV (bt878)", - video_inputs: 3, - audio_inputs: 2, - tuner: 0, - svhs: 2, - gpiomask: 0xFF, - muxsel: { 2, 3, 1, 0}, - audiomux: { 1, 0, 4, 4, 9}, - needs_tvaudio: 0, - pll: PLL_28, - tuner_type: TUNER_PHILIPS_PAL, + .name = "Askey CPH061/ BESTBUY Easy TV (bt878)", + .video_inputs = 3, + .audio_inputs = 2, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xFF, + .muxsel = { 2, 3, 1, 0}, + .audiomux = { 1, 0, 4, 4, 9}, + .needs_tvaudio = 0, + .pll = PLL_28, + .tuner_type = TUNER_PHILIPS_PAL, },{ /* Lukas Gebauer <geby@volny.cz> */ - name: "ATI TV-Wonder", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xf03f, - muxsel: { 2, 3, 1, 0 }, - audiomux: { 0xbffe, 0, 0xbfff, 0, 0xbffe}, - pll: PLL_28, - tuner_type: TUNER_TEMIC_4006FN5_MULTI_PAL, + .name = "ATI TV-Wonder", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xf03f, + .muxsel = { 2, 3, 1, 0 }, + .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe}, + .pll = PLL_28, + .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, },{ /* ---- card 0x40 ---------------------------------- */ /* Lukas Gebauer <geby@volny.cz> */ - name: "ATI TV-Wonder VE", - video_inputs: 2, - audio_inputs: 1, - tuner: 0, - svhs: -1, - gpiomask: 1, - muxsel: { 2, 3, 0, 1}, - audiomux: { 0, 0, 1, 0, 0}, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: TUNER_TEMIC_4006FN5_MULTI_PAL, + .name = "ATI TV-Wonder VE", + .video_inputs = 2, + .audio_inputs = 1, + .tuner = 0, + .svhs = -1, + .gpiomask = 1, + .muxsel = { 2, 3, 0, 1}, + .audiomux = { 0, 0, 1, 0, 0}, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, },{ /* DeeJay <deejay@westel900.net (2000S) */ - name: "Lifeview FlyVideo 2000S LR90", - video_inputs: 3, - audio_inputs: 3, - tuner: 0, - svhs: 2, - gpiomask: 0x18e0, - muxsel: { 2, 3, 0, 1}, + .name = "Lifeview FlyVideo 2000S LR90", + .video_inputs = 3, + .audio_inputs = 3, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x18e0, + .muxsel = { 2, 3, 0, 1}, /* Radio changed from 1e80 to 0x800 to make FlyVideo2000S in .hu happy (gm)*/ /* -dk-???: set mute=0x1800 for tda9874h daughterboard */ - audiomux: { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 }, - audio_hook: fv2000s_audio, - no_msp34xx: 1, - no_tda9875: 1, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: 5, -},{ - name: "Terratec TValueRadio", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0xffff00, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0x500, 0x500, 0x300, 0x900, 0x900}, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: TUNER_PHILIPS_PAL, - has_radio: 1, + .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 }, + .audio_hook = fv2000s_audio, + .no_msp34xx = 1, + .no_tda9875 = 1, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = 5, +},{ + .name = "Terratec TValueRadio", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0xffff00, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900}, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = TUNER_PHILIPS_PAL, + .has_radio = 1, },{ /* TANAKA Kei <peg00625@nifty.com> */ - name: "IODATA GV-BCTV4/PCI", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x010f00, - muxsel: {2, 3, 0, 0}, - audiomux: {0x10000, 0, 0x10000, 0, 0, 0}, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: TUNER_SHARP_2U5JF5540_NTSC, - audio_hook: gvbctv3pci_audio, + .name = "IODATA GV-BCTV4/PCI", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x010f00, + .muxsel = {2, 3, 0, 0}, + .audiomux = {0x10000, 0, 0x10000, 0, 0, 0}, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_SHARP_2U5JF5540_NTSC, + .audio_hook = gvbctv3pci_audio, },{ /* ---- card 0x44 ---------------------------------- */ - name: "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)", + .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)", // try "insmod msp3400 simple=0" if you have // sound problems with this card. - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: -1, - gpiomask: 0x4f8a00, + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = -1, + .gpiomask = 0x4f8a00, // 0x100000: 1=MSP enabled (0=disable again) // 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) - audiomux: {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff}, + .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff}, // tvtuner, radio, external,internal, mute, stereo /* tuner, Composit, SVid, Composit-on-Svid-adapter*/ - muxsel: { 2, 3 ,0 ,1}, - tuner_type: TUNER_MT2032, - pll: PLL_28, - has_radio: 1, + .muxsel = { 2, 3 ,0 ,1}, + .tuner_type = TUNER_MT2032, + .pll = PLL_28, + .has_radio = 1, },{ /* Philip Blundell <pb@nexus.co.uk> */ - name: "Active Imaging AIMMS", - video_inputs: 1, - audio_inputs: 0, - tuner: -1, - tuner_type: -1, - pll: PLL_28, - muxsel: { 2 }, - gpiomask: 0 + .name = "Active Imaging AIMMS", + .video_inputs = 1, + .audio_inputs = 0, + .tuner = -1, + .tuner_type = -1, + .pll = PLL_28, + .muxsel = { 2 }, + .gpiomask = 0 },{ /* Tomasz Pyra <hellfire@sedez.iq.pl> */ - name: "Prolink Pixelview PV-BT878P+ (Rev.4C)", - video_inputs: 3, - audio_inputs: 4, - tuner: 0, - svhs: 2, - gpiomask: 15, - muxsel: { 2, 3, 1, 1}, - audiomux: { 0, 0, 11, 7, 13, 0}, // TV and Radio with same GPIO ! - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: 25, + .name = "Prolink Pixelview PV-BT878P+ (Rev.4C)", + .video_inputs = 3, + .audio_inputs = 4, + .tuner = 0, + .svhs = 2, + .gpiomask = 15, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 0, 0, 11, 7, 13, 0}, // TV and Radio with same GPIO ! + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = 25, /* GPIO wiring: GPIO0: U4.A0 (hef4052bt) GPIO1: U4.A1 @@ -1187,33 +1187,33 @@ struct tvcard bttv_tvcards[] = { GPIO8-15: vrd866b ? */ },{ - name: "Lifeview FlyVideo 98EZ (capture only) LR51", - video_inputs: 4, - audio_inputs: 0, - tuner: -1, - svhs: 2, - muxsel: { 2, 3, 1, 1}, // AV1, AV2, SVHS, CVid adapter on SVHS - pll: PLL_28, - no_msp34xx: 1, + .name = "Lifeview FlyVideo 98EZ (capture only) LR51", + .video_inputs = 4, + .audio_inputs = 0, + .tuner = -1, + .svhs = 2, + .muxsel = { 2, 3, 1, 1}, // AV1, AV2, SVHS, CVid adapter on SVHS + .pll = PLL_28, + .no_msp34xx = 1, },{ /* ---- card 0x48 ---------------------------------- */ /* Dariusz Kowalewski <darekk@automex.pl> */ - name: "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x3f, - muxsel: { 2, 3, 1, 1 }, - audiomux: { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 }, - needs_tvaudio: 1, - no_msp34xx: 1, - no_tda9875: 1, - pll: PLL_28, - tuner_type: 5, - audio_hook: pvbt878p9b_audio, // Note: not all cards have stereo - has_radio: 1, // Note: not all cards have radio + .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x3f, + .muxsel = { 2, 3, 1, 1 }, + .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 }, + .needs_tvaudio = 1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .pll = PLL_28, + .tuner_type = 5, + .audio_hook = pvbt878p9b_audio, // Note: not all cards have stereo + .has_radio = 1, // Note: not all cards have radio /* GPIO wiring: GPIO0: A0 hef4052 GPIO1: A1 hef4052 @@ -1224,91 +1224,91 @@ struct tvcard bttv_tvcards[] = { },{ /* Clay Kunz <ckunz@mail.arc.nasa.gov> */ /* you must jumper JP5 for the card to work */ - name: "Sensoray 311", - video_inputs: 5, - audio_inputs: 0, - tuner: -1, - svhs: 4, - gpiomask: 0, - muxsel: { 2, 3, 1, 0, 0}, - audiomux: { 0 }, - needs_tvaudio: 0, - tuner_type: -1, + .name = "Sensoray 311", + .video_inputs = 5, + .audio_inputs = 0, + .tuner = -1, + .svhs = 4, + .gpiomask = 0, + .muxsel = { 2, 3, 1, 0, 0}, + .audiomux = { 0 }, + .needs_tvaudio = 0, + .tuner_type = -1, },{ /* Miguel Freitas <miguel@cetuc.puc-rio.br> */ - name: "RemoteVision MX (RV605)", - video_inputs: 16, - audio_inputs: 0, - tuner: -1, - svhs: -1, - gpiomask: 0x00, - gpiomask2: 0x07ff, - muxsel: { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, + .name = "RemoteVision MX (RV605)", + .video_inputs = 16, + .audio_inputs = 0, + .tuner = -1, + .svhs = -1, + .gpiomask = 0x00, + .gpiomask2 = 0x07ff, + .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, - no_msp34xx: 1, - no_tda9875: 1, - tuner_type: -1, - muxsel_hook: rv605_muxsel, -},{ - name: "Powercolor MTV878/ MTV878R/ MTV878F", - video_inputs: 3, - audio_inputs: 2, - tuner: 0, - svhs: 2, - gpiomask: 0x1C800F, // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset - muxsel: { 2, 1, 1, }, - audiomux: { 0, 1, 2, 2, 4 }, - needs_tvaudio: 0, - tuner_type: TUNER_PHILIPS_PAL, - pll: PLL_28, - has_radio: 1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .tuner_type = -1, + .muxsel_hook = rv605_muxsel, +},{ + .name = "Powercolor MTV878/ MTV878R/ MTV878F", + .video_inputs = 3, + .audio_inputs = 2, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x1C800F, // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset + .muxsel = { 2, 1, 1, }, + .audiomux = { 0, 1, 2, 2, 4 }, + .needs_tvaudio = 0, + .tuner_type = TUNER_PHILIPS_PAL, + .pll = PLL_28, + .has_radio = 1, },{ /* ---- card 0x4c ---------------------------------- */ /* Masaki Suzuki <masaki@btree.org> */ - name: "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x140007, - muxsel: { 2, 3, 1, 1 }, - audiomux: { 0, 1, 2, 3, 4, 0 }, - tuner_type: TUNER_PHILIPS_NTSC, - audio_hook: windvr_audio, -},{ - name: "GrandTec Multi Capture Card (Bt878)", - video_inputs: 4, - audio_inputs: 0, - tuner: -1, - svhs: -1, - gpiomask: 0, - muxsel: { 2, 3, 1, 0 }, - audiomux: { 0 }, - needs_tvaudio: 0, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: -1, -},{ - name: "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", - video_inputs: 4, - audio_inputs: 3, - tuner: 0, - svhs: 2, - gpiomask: 7, - muxsel: { 2, 3, 1, 1 }, // Tuner, SVid, SVHS, SVid to SVHS connector - audiomux: { 0 ,0 ,4, 4,4,4},// Yes, this tuner uses the same audio output for TV and FM radio! + .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x140007, + .muxsel = { 2, 3, 1, 1 }, + .audiomux = { 0, 1, 2, 3, 4, 0 }, + .tuner_type = TUNER_PHILIPS_NTSC, + .audio_hook = windvr_audio, +},{ + .name = "GrandTec Multi Capture Card (Bt878)", + .video_inputs = 4, + .audio_inputs = 0, + .tuner = -1, + .svhs = -1, + .gpiomask = 0, + .muxsel = { 2, 3, 1, 0 }, + .audiomux = { 0 }, + .needs_tvaudio = 0, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = -1, +},{ + .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", + .video_inputs = 4, + .audio_inputs = 3, + .tuner = 0, + .svhs = 2, + .gpiomask = 7, + .muxsel = { 2, 3, 1, 1 }, // Tuner, SVid, SVHS, SVid to SVHS connector + .audiomux = { 0 ,0 ,4, 4,4,4},// Yes, this tuner uses the same audio output for TV and FM radio! // This card lacks external Audio In, so we mute it on Ext. & Int. // The PCB can take a sbx1637/sbx1673, wiring unknown. // This card lacks PCI subsystem ID, sigh. // audiomux=1: lower volume, 2+3: mute // btwincap uses 0x80000/0x80003 - needs_tvaudio: 0, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: 5, // Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and + .needs_tvaudio = 0, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = 5, // Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and // radio signal strength indicators work fine. - has_radio: 1, + .has_radio = 1, /* GPIO Info: GPIO0,1: HEF4052 A0,A1 GPIO2: HEF4052 nENABLE @@ -1320,199 +1320,199 @@ struct tvcard bttv_tvcards[] = { ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/ },{ /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */ - name: "DSP Design TCVIDEO", - video_inputs: 4, - svhs: -1, - muxsel: { 2, 3, 1, 0}, - pll: PLL_28, - tuner_type: -1, + .name = "DSP Design TCVIDEO", + .video_inputs = 4, + .svhs = -1, + .muxsel = { 2, 3, 1, 0}, + .pll = PLL_28, + .tuner_type = -1, },{ /* ---- card 0x50 ---------------------------------- */ - name: "Hauppauge WinTV PVR", - video_inputs: 4, - audio_inputs: 1, - tuner: 0, - svhs: 2, - muxsel: { 2, 0, 1, 1}, - needs_tvaudio: 1, - pll: PLL_28, - tuner_type: -1, - - gpiomask: 7, - audiomux: {7}, -},{ - name: "GV-BCTV5/PCI", - video_inputs: 3, - audio_inputs: 1, - tuner: 0, - svhs: 2, - gpiomask: 0x010f00, - muxsel: {2, 3, 1, 0}, - audiomux: {0x10000, 0, 0x10000, 0, 0, 0}, - no_msp34xx: 1, - pll: PLL_28, - tuner_type: TUNER_PHILIPS_NTSC_M, - audio_hook: gvbctv3pci_audio, -},{ - name: "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ - video_inputs: 4, /* id-inputs-clock */ - audio_inputs: 0, - tuner: -1, - svhs: 3, - muxsel: { 3, 2, 0, 1 }, - pll: PLL_28, - tuner_type: -1, - no_msp34xx: 1, - no_tda9875: 1, - no_tda7432: 1, -},{ - name: "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ - video_inputs: 3, - audio_inputs: 0, - tuner: -1, - svhs: 2, - muxsel: { 2, 3, 1 }, - pll: PLL_28, - tuner_type: -1, - no_msp34xx: 1, - no_tda9875: 1, - no_tda7432: 1, + .name = "Hauppauge WinTV PVR", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .muxsel = { 2, 0, 1, 1}, + .needs_tvaudio = 1, + .pll = PLL_28, + .tuner_type = -1, + + .gpiomask = 7, + .audiomux = {7}, +},{ + .name = "GV-BCTV5/PCI", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x010f00, + .muxsel = {2, 3, 1, 0}, + .audiomux = {0x10000, 0, 0x10000, 0, 0, 0}, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_PHILIPS_NTSC_M, + .audio_hook = gvbctv3pci_audio, +},{ + .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ + .video_inputs = 4, /* id-inputs-clock */ + .audio_inputs = 0, + .tuner = -1, + .svhs = 3, + .muxsel = { 3, 2, 0, 1 }, + .pll = PLL_28, + .tuner_type = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, +},{ + .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ + .video_inputs = 3, + .audio_inputs = 0, + .tuner = -1, + .svhs = 2, + .muxsel = { 2, 3, 1 }, + .pll = PLL_28, + .tuner_type = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, },{ /* ---- card 0x54 ---------------------------------- */ - name: "Osprey 101 (848)", /* 0x05-40C0-C1 */ - video_inputs: 2, - audio_inputs: 0, - tuner: -1, - svhs: 1, - muxsel: { 3, 1 }, - pll: PLL_28, - tuner_type: -1, - no_msp34xx: 1, - no_tda9875: 1, - no_tda7432: 1, -},{ - name: "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ - video_inputs: 1, - audio_inputs: 0, - tuner: -1, - svhs: -1, - muxsel: { 0 }, - pll: PLL_28, - tuner_type: -1, - no_msp34xx: 1, - no_tda9875: 1, - no_tda7432: 1, -},{ - name: "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ - video_inputs: 2, - audio_inputs: 0, - tuner: -1, - svhs: 1, - muxsel: { 0, 1 }, - pll: PLL_28, - tuner_type: -1, - no_msp34xx: 1, - no_tda9875: 1, - no_tda7432: 1, -},{ - name: "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ - video_inputs: 1, - audio_inputs: 1, - tuner: -1, - svhs: -1, - muxsel: { 0 }, - pll: PLL_28, - tuner_type: -1, - no_msp34xx: 1, - no_tda9875: 1, - no_tda7432: 1, + .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ + .video_inputs = 2, + .audio_inputs = 0, + .tuner = -1, + .svhs = 1, + .muxsel = { 3, 1 }, + .pll = PLL_28, + .tuner_type = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, +},{ + .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ + .video_inputs = 1, + .audio_inputs = 0, + .tuner = -1, + .svhs = -1, + .muxsel = { 0 }, + .pll = PLL_28, + .tuner_type = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, +},{ + .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ + .video_inputs = 2, + .audio_inputs = 0, + .tuner = -1, + .svhs = 1, + .muxsel = { 0, 1 }, + .pll = PLL_28, + .tuner_type = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, +},{ + .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ + .video_inputs = 1, + .audio_inputs = 1, + .tuner = -1, + .svhs = -1, + .muxsel = { 0 }, + .pll = PLL_28, + .tuner_type = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, },{ /* ---- card 0x58 ---------------------------------- */ - name: "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ - video_inputs: 2, - audio_inputs: 1, - tuner: -1, - svhs: 1, - muxsel: { 0, 1 }, - pll: PLL_28, - tuner_type: -1, - no_msp34xx: 1, - no_tda9875: 1, - no_tda7432: 1, -},{ - name: "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ - video_inputs: 2, - audio_inputs: 1, - tuner: -1, - svhs: 1, - muxsel: { 2, 3 }, - pll: PLL_28, - tuner_type: -1, - no_msp34xx: 1, - no_tda9875: 1, - no_tda7432: 1, -},{ - name: "Osprey 500", /* 500 */ - video_inputs: 2, - audio_inputs: 1, - tuner: -1, - svhs: 1, - muxsel: { 2, 3 }, - pll: PLL_28, - tuner_type: -1, - no_msp34xx: 1, - no_tda9875: 1, - no_tda7432: 1, -},{ - name: "Osprey 540", /* 540 */ - video_inputs: 4, - audio_inputs: 1, - tuner: -1, + .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ + .video_inputs = 2, + .audio_inputs = 1, + .tuner = -1, + .svhs = 1, + .muxsel = { 0, 1 }, + .pll = PLL_28, + .tuner_type = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, +},{ + .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ + .video_inputs = 2, + .audio_inputs = 1, + .tuner = -1, + .svhs = 1, + .muxsel = { 2, 3 }, + .pll = PLL_28, + .tuner_type = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, +},{ + .name = "Osprey 500", /* 500 */ + .video_inputs = 2, + .audio_inputs = 1, + .tuner = -1, + .svhs = 1, + .muxsel = { 2, 3 }, + .pll = PLL_28, + .tuner_type = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, +},{ + .name = "Osprey 540", /* 540 */ + .video_inputs = 4, + .audio_inputs = 1, + .tuner = -1, #if 0 /* TODO ... */ - svhs: OSPREY540_SVID_ANALOG, - muxsel: { [OSPREY540_COMP_ANALOG] = 2, + .svhs = OSPREY540_SVID_ANALOG, + .muxsel = { [OSPREY540_COMP_ANALOG] = 2, [OSPREY540_SVID_ANALOG] = 3, }, #endif - pll: PLL_28, - tuner_type: -1, - no_msp34xx: 1, - no_tda9875: 1, - no_tda7432: 1, + .pll = PLL_28, + .tuner_type = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, #if 0 /* TODO ... */ - muxsel_hook: osprey_540_muxsel, - picture_hook: osprey_540_set_picture, + .muxsel_hook = osprey_540_muxsel, + .picture_hook = osprey_540_set_picture, #endif },{ /* ---- card 0x5C ---------------------------------- */ - name: "Osprey 2000", /* 2000 */ - video_inputs: 2, - audio_inputs: 1, - tuner: -1, - svhs: 1, - muxsel: { 2, 3 }, - pll: PLL_28, - tuner_type: -1, - no_msp34xx: 1, - no_tda9875: 1, - no_tda7432: 1, /* must avoid, conflicts with the bt860 */ + .name = "Osprey 2000", /* 2000 */ + .video_inputs = 2, + .audio_inputs = 1, + .tuner = -1, + .svhs = 1, + .muxsel = { 2, 3 }, + .pll = PLL_28, + .tuner_type = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ },{ /* M G Berberich <berberic@forwiss.uni-passau.de> */ - name: "IDS Eagle", - video_inputs: 4, - audio_inputs: 0, - tuner: -1, - tuner_type: -1, - svhs: -1, - gpiomask: 0, - muxsel: { 0, 1, 2, 3 }, - muxsel_hook: eagle_muxsel, - no_msp34xx: 1, - no_tda9875: 1, - pll: PLL_28, + .name = "IDS Eagle", + .video_inputs = 4, + .audio_inputs = 0, + .tuner = -1, + .tuner_type = -1, + .svhs = -1, + .gpiomask = 0, + .muxsel = { 0, 1, 2, 3 }, + .muxsel_hook = eagle_muxsel, + .no_msp34xx = 1, + .no_tda9875 = 1, + .pll = PLL_28, }}; const int bttv_num_tvcards = (sizeof(bttv_tvcards)/sizeof(struct tvcard)); diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 4d635d055084..97e1b41d375a 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c @@ -274,154 +274,154 @@ const int BTTV_TVNORMS = (sizeof(bttv_tvnorms)/sizeof(struct bttv_tvnorm)); packed pixel formats must come first */ const struct bttv_format bttv_formats[] = { { - name: "8 bpp, gray", - palette: VIDEO_PALETTE_GREY, - fourcc: V4L2_PIX_FMT_GREY, - btformat: BT848_COLOR_FMT_Y8, - depth: 8, - flags: FORMAT_FLAGS_PACKED, + .name = "8 bpp, gray", + .palette = VIDEO_PALETTE_GREY, + .fourcc = V4L2_PIX_FMT_GREY, + .btformat = BT848_COLOR_FMT_Y8, + .depth = 8, + .flags = FORMAT_FLAGS_PACKED, },{ - name: "8 bpp, dithered color", - palette: VIDEO_PALETTE_HI240, - fourcc: V4L2_PIX_FMT_HI240, - btformat: BT848_COLOR_FMT_RGB8, - depth: 8, - flags: FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER, + .name = "8 bpp, dithered color", + .palette = VIDEO_PALETTE_HI240, + .fourcc = V4L2_PIX_FMT_HI240, + .btformat = BT848_COLOR_FMT_RGB8, + .depth = 8, + .flags = FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER, },{ - name: "15 bpp RGB, le", - palette: VIDEO_PALETTE_RGB555, - fourcc: V4L2_PIX_FMT_RGB555, - btformat: BT848_COLOR_FMT_RGB15, - depth: 16, - flags: FORMAT_FLAGS_PACKED, + .name = "15 bpp RGB, le", + .palette = VIDEO_PALETTE_RGB555, + .fourcc = V4L2_PIX_FMT_RGB555, + .btformat = BT848_COLOR_FMT_RGB15, + .depth = 16, + .flags = FORMAT_FLAGS_PACKED, },{ - name: "15 bpp RGB, be", - palette: -1, - fourcc: V4L2_PIX_FMT_RGB555X, - btformat: BT848_COLOR_FMT_RGB15, - btswap: 0x03, /* byteswap */ - depth: 16, - flags: FORMAT_FLAGS_PACKED, + .name = "15 bpp RGB, be", + .palette = -1, + .fourcc = V4L2_PIX_FMT_RGB555X, + .btformat = BT848_COLOR_FMT_RGB15, + .btswap = 0x03, /* byteswap */ + .depth = 16, + .flags = FORMAT_FLAGS_PACKED, },{ - name: "16 bpp RGB, le", - palette: VIDEO_PALETTE_RGB565, - fourcc: V4L2_PIX_FMT_RGB565, - btformat: BT848_COLOR_FMT_RGB16, - depth: 16, - flags: FORMAT_FLAGS_PACKED, + .name = "16 bpp RGB, le", + .palette = VIDEO_PALETTE_RGB565, + .fourcc = V4L2_PIX_FMT_RGB565, + .btformat = BT848_COLOR_FMT_RGB16, + .depth = 16, + .flags = FORMAT_FLAGS_PACKED, },{ - name: "16 bpp RGB, be", - palette: -1, - fourcc: V4L2_PIX_FMT_RGB565X, - btformat: BT848_COLOR_FMT_RGB16, - btswap: 0x03, /* byteswap */ - depth: 16, - flags: FORMAT_FLAGS_PACKED, + .name = "16 bpp RGB, be", + .palette = -1, + .fourcc = V4L2_PIX_FMT_RGB565X, + .btformat = BT848_COLOR_FMT_RGB16, + .btswap = 0x03, /* byteswap */ + .depth = 16, + .flags = FORMAT_FLAGS_PACKED, },{ - name: "24 bpp RGB, le", - palette: VIDEO_PALETTE_RGB24, - fourcc: V4L2_PIX_FMT_BGR24, - btformat: BT848_COLOR_FMT_RGB24, - depth: 24, - flags: FORMAT_FLAGS_PACKED, + .name = "24 bpp RGB, le", + .palette = VIDEO_PALETTE_RGB24, + .fourcc = V4L2_PIX_FMT_BGR24, + .btformat = BT848_COLOR_FMT_RGB24, + .depth = 24, + .flags = FORMAT_FLAGS_PACKED, },{ - name: "32 bpp RGB, le", - palette: VIDEO_PALETTE_RGB32, - fourcc: V4L2_PIX_FMT_BGR32, - btformat: BT848_COLOR_FMT_RGB32, - depth: 32, - flags: FORMAT_FLAGS_PACKED, + .name = "32 bpp RGB, le", + .palette = VIDEO_PALETTE_RGB32, + .fourcc = V4L2_PIX_FMT_BGR32, + .btformat = BT848_COLOR_FMT_RGB32, + .depth = 32, + .flags = FORMAT_FLAGS_PACKED, },{ - name: "32 bpp RGB, be", - palette: -1, - fourcc: V4L2_PIX_FMT_RGB32, - btformat: BT848_COLOR_FMT_RGB32, - btswap: 0x0f, /* byte+word swap */ - depth: 32, - flags: FORMAT_FLAGS_PACKED, + .name = "32 bpp RGB, be", + .palette = -1, + .fourcc = V4L2_PIX_FMT_RGB32, + .btformat = BT848_COLOR_FMT_RGB32, + .btswap = 0x0f, /* byte+word swap */ + .depth = 32, + .flags = FORMAT_FLAGS_PACKED, },{ - name: "4:2:2, packed, YUYV", - palette: VIDEO_PALETTE_YUV422, - fourcc: V4L2_PIX_FMT_YUYV, - btformat: BT848_COLOR_FMT_YUY2, - depth: 16, - flags: FORMAT_FLAGS_PACKED, + .name = "4:2:2, packed, YUYV", + .palette = VIDEO_PALETTE_YUV422, + .fourcc = V4L2_PIX_FMT_YUYV, + .btformat = BT848_COLOR_FMT_YUY2, + .depth = 16, + .flags = FORMAT_FLAGS_PACKED, },{ - name: "4:2:2, packed, YUYV", - palette: VIDEO_PALETTE_YUYV, - fourcc: V4L2_PIX_FMT_YUYV, - btformat: BT848_COLOR_FMT_YUY2, - depth: 16, - flags: FORMAT_FLAGS_PACKED, + .name = "4:2:2, packed, YUYV", + .palette = VIDEO_PALETTE_YUYV, + .fourcc = V4L2_PIX_FMT_YUYV, + .btformat = BT848_COLOR_FMT_YUY2, + .depth = 16, + .flags = FORMAT_FLAGS_PACKED, },{ - name: "4:2:2, packed, UYVY", - palette: VIDEO_PALETTE_UYVY, - fourcc: V4L2_PIX_FMT_UYVY, - btformat: BT848_COLOR_FMT_YUY2, - btswap: 0x03, /* byteswap */ - depth: 16, - flags: FORMAT_FLAGS_PACKED, + .name = "4:2:2, packed, UYVY", + .palette = VIDEO_PALETTE_UYVY, + .fourcc = V4L2_PIX_FMT_UYVY, + .btformat = BT848_COLOR_FMT_YUY2, + .btswap = 0x03, /* byteswap */ + .depth = 16, + .flags = FORMAT_FLAGS_PACKED, },{ - name: "4:2:2, planar, Y-Cb-Cr", - palette: VIDEO_PALETTE_YUV422P, - fourcc: V4L2_PIX_FMT_YUV422P, - btformat: BT848_COLOR_FMT_YCrCb422, - depth: 16, - flags: FORMAT_FLAGS_PLANAR, - hshift: 1, - vshift: 0, + .name = "4:2:2, planar, Y-Cb-Cr", + .palette = VIDEO_PALETTE_YUV422P, + .fourcc = V4L2_PIX_FMT_YUV422P, + .btformat = BT848_COLOR_FMT_YCrCb422, + .depth = 16, + .flags = FORMAT_FLAGS_PLANAR, + .hshift = 1, + .vshift = 0, },{ - name: "4:2:0, planar, Y-Cb-Cr", - palette: VIDEO_PALETTE_YUV420P, - fourcc: V4L2_PIX_FMT_YUV420, - btformat: BT848_COLOR_FMT_YCrCb422, - depth: 12, - flags: FORMAT_FLAGS_PLANAR, - hshift: 1, - vshift: 1, + .name = "4:2:0, planar, Y-Cb-Cr", + .palette = VIDEO_PALETTE_YUV420P, + .fourcc = V4L2_PIX_FMT_YUV420, + .btformat = BT848_COLOR_FMT_YCrCb422, + .depth = 12, + .flags = FORMAT_FLAGS_PLANAR, + .hshift = 1, + .vshift = 1, },{ - name: "4:2:0, planar, Y-Cr-Cb", - palette: -1, - fourcc: V4L2_PIX_FMT_YVU420, - btformat: BT848_COLOR_FMT_YCrCb422, - depth: 12, - flags: FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb, - hshift: 1, - vshift: 1, + .name = "4:2:0, planar, Y-Cr-Cb", + .palette = -1, + .fourcc = V4L2_PIX_FMT_YVU420, + .btformat = BT848_COLOR_FMT_YCrCb422, + .depth = 12, + .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb, + .hshift = 1, + .vshift = 1, },{ - name: "4:1:1, planar, Y-Cb-Cr", - palette: VIDEO_PALETTE_YUV411P, - fourcc: V4L2_PIX_FMT_YUV411P, - btformat: BT848_COLOR_FMT_YCrCb411, - depth: 12, - flags: FORMAT_FLAGS_PLANAR, - hshift: 2, - vshift: 0, + .name = "4:1:1, planar, Y-Cb-Cr", + .palette = VIDEO_PALETTE_YUV411P, + .fourcc = V4L2_PIX_FMT_YUV411P, + .btformat = BT848_COLOR_FMT_YCrCb411, + .depth = 12, + .flags = FORMAT_FLAGS_PLANAR, + .hshift = 2, + .vshift = 0, },{ - name: "4:1:0, planar, Y-Cb-Cr", - palette: VIDEO_PALETTE_YUV410P, - fourcc: V4L2_PIX_FMT_YUV410, - btformat: BT848_COLOR_FMT_YCrCb411, - depth: 9, - flags: FORMAT_FLAGS_PLANAR, - hshift: 2, - vshift: 2, + .name = "4:1:0, planar, Y-Cb-Cr", + .palette = VIDEO_PALETTE_YUV410P, + .fourcc = V4L2_PIX_FMT_YUV410, + .btformat = BT848_COLOR_FMT_YCrCb411, + .depth = 9, + .flags = FORMAT_FLAGS_PLANAR, + .hshift = 2, + .vshift = 2, },{ - name: "4:1:0, planar, Y-Cr-Cb", - palette: -1, - fourcc: V4L2_PIX_FMT_YVU410, - btformat: BT848_COLOR_FMT_YCrCb411, - depth: 9, - flags: FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb, - hshift: 2, - vshift: 2, + .name = "4:1:0, planar, Y-Cr-Cb", + .palette = -1, + .fourcc = V4L2_PIX_FMT_YVU410, + .btformat = BT848_COLOR_FMT_YCrCb411, + .depth = 9, + .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb, + .hshift = 2, + .vshift = 2, },{ - name: "raw scanlines", - palette: VIDEO_PALETTE_RAW, - fourcc: -1, - btformat: BT848_COLOR_FMT_RAW, - depth: 8, - flags: FORMAT_FLAGS_RAW, + .name = "raw scanlines", + .palette = VIDEO_PALETTE_RAW, + .fourcc = -1, + .btformat = BT848_COLOR_FMT_RAW, + .depth = 8, + .flags = FORMAT_FLAGS_RAW, } }; const int BTTV_FORMATS = (sizeof(bttv_formats)/sizeof(struct bttv_format)); @@ -436,115 +436,115 @@ const int BTTV_FORMATS = (sizeof(bttv_formats)/sizeof(struct bttv_format)); #define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 5) static const struct v4l2_queryctrl no_ctl = { - name: "42", - flags: V4L2_CTRL_FLAG_DISABLED, + .name = "42", + .flags = V4L2_CTRL_FLAG_DISABLED, }; static const struct v4l2_queryctrl bttv_ctls[] = { /* --- video --- */ { - id: V4L2_CID_BRIGHTNESS, - name: "Brightness", - minimum: 0, - maximum: 65535, - step: 256, - default_value: 32768, - type: V4L2_CTRL_TYPE_INTEGER, + .id = V4L2_CID_BRIGHTNESS, + .name = "Brightness", + .minimum = 0, + .maximum = 65535, + .step = 256, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, },{ - id: V4L2_CID_CONTRAST, - name: "Contrast", - minimum: 0, - maximum: 65535, - step: 128, - default_value: 32768, - type: V4L2_CTRL_TYPE_INTEGER, + .id = V4L2_CID_CONTRAST, + .name = "Contrast", + .minimum = 0, + .maximum = 65535, + .step = 128, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, },{ - id: V4L2_CID_SATURATION, - name: "Saturation", - minimum: 0, - maximum: 65535, - step: 128, - default_value: 32768, - type: V4L2_CTRL_TYPE_INTEGER, + .id = V4L2_CID_SATURATION, + .name = "Saturation", + .minimum = 0, + .maximum = 65535, + .step = 128, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, },{ - id: V4L2_CID_HUE, - name: "Hue", - minimum: 0, - maximum: 65535, - step: 256, - default_value: 32768, - type: V4L2_CTRL_TYPE_INTEGER, + .id = V4L2_CID_HUE, + .name = "Hue", + .minimum = 0, + .maximum = 65535, + .step = 256, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, }, /* --- audio --- */ { - id: V4L2_CID_AUDIO_MUTE, - name: "Mute", - minimum: 0, - maximum: 1, - type: V4L2_CTRL_TYPE_BOOLEAN, + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, },{ - id: V4L2_CID_AUDIO_VOLUME, - name: "Volume", - minimum: 0, - maximum: 65535, - step: 65535/100, - default_value: 65535, - type: V4L2_CTRL_TYPE_INTEGER, + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 65535, + .type = V4L2_CTRL_TYPE_INTEGER, },{ - id: V4L2_CID_AUDIO_BALANCE, - name: "Balance", - minimum: 0, - maximum: 65535, - step: 65535/100, - default_value: 32768, - type: V4L2_CTRL_TYPE_INTEGER, + .id = V4L2_CID_AUDIO_BALANCE, + .name = "Balance", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, },{ - id: V4L2_CID_AUDIO_BASS, - name: "Bass", - minimum: 0, - maximum: 65535, - step: 65535/100, - default_value: 32768, - type: V4L2_CTRL_TYPE_INTEGER, + .id = V4L2_CID_AUDIO_BASS, + .name = "Bass", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, },{ - id: V4L2_CID_AUDIO_TREBLE, - name: "Treble", - minimum: 0, - maximum: 65535, - step: 65535/100, - default_value: 32768, - type: V4L2_CTRL_TYPE_INTEGER, + .id = V4L2_CID_AUDIO_TREBLE, + .name = "Treble", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, }, /* --- private --- */ { - id: V4L2_CID_PRIVATE_CHROMA_AGC, - name: "chroma agc", - minimum: 0, - maximum: 1, - type: V4L2_CTRL_TYPE_BOOLEAN, + .id = V4L2_CID_PRIVATE_CHROMA_AGC, + .name = "chroma agc", + .minimum = 0, + .maximum = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, },{ - id: V4L2_CID_PRIVATE_COMBFILTER, - name: "combfilter", - minimum: 0, - maximum: 1, - type: V4L2_CTRL_TYPE_BOOLEAN, + .id = V4L2_CID_PRIVATE_COMBFILTER, + .name = "combfilter", + .minimum = 0, + .maximum = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, },{ - id: V4L2_CID_PRIVATE_AUTOMUTE, - name: "automute", - minimum: 0, - maximum: 1, - type: V4L2_CTRL_TYPE_BOOLEAN, + .id = V4L2_CID_PRIVATE_AUTOMUTE, + .name = "automute", + .minimum = 0, + .maximum = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, },{ - id: V4L2_CID_PRIVATE_LUMAFILTER, - name: "luma decimation filter", - minimum: 0, - maximum: 1, - type: V4L2_CTRL_TYPE_BOOLEAN, + .id = V4L2_CID_PRIVATE_LUMAFILTER, + .name = "luma decimation filter", + .minimum = 0, + .maximum = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, },{ - id: V4L2_CID_PRIVATE_AGC_CRUSH, - name: "agc crush", - minimum: 0, - maximum: 1, - type: V4L2_CTRL_TYPE_BOOLEAN, + .id = V4L2_CID_PRIVATE_AGC_CRUSH, + .name = "agc crush", + .minimum = 0, + .maximum = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, } }; const int BTTV_CTLS = (sizeof(bttv_ctls)/sizeof(struct v4l2_queryctrl)); @@ -1314,10 +1314,10 @@ static void buffer_release(struct file *file, struct videobuf_buffer *vb) } static struct videobuf_queue_ops bttv_video_qops = { - buf_setup: buffer_setup, - buf_prepare: buffer_prepare, - buf_queue: buffer_queue, - buf_release: buffer_release, + .buf_setup = buffer_setup, + .buf_prepare = buffer_prepare, + .buf_queue = buffer_queue, + .buf_release = buffer_release, }; static const char *v4l1_ioctls[] = { @@ -2706,33 +2706,33 @@ bttv_mmap(struct file *file, struct vm_area_struct *vma) static struct file_operations bttv_fops = { - owner: THIS_MODULE, - open: bttv_open, - release: bttv_release, - ioctl: bttv_ioctl, - llseek: no_llseek, - read: bttv_read, - mmap: bttv_mmap, - poll: bttv_poll, + .owner = THIS_MODULE, + .open = bttv_open, + .release = bttv_release, + .ioctl = bttv_ioctl, + .llseek = no_llseek, + .read = bttv_read, + .mmap = bttv_mmap, + .poll = bttv_poll, }; static struct video_device bttv_video_template = { - name: "UNSET", - type: VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| + .name = "UNSET", + .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| VID_TYPE_CLIPPING|VID_TYPE_SCALES, - hardware: VID_HARDWARE_BT848, - fops: &bttv_fops, - minor: -1, + .hardware = VID_HARDWARE_BT848, + .fops = &bttv_fops, + .minor = -1, }; struct video_device bttv_vbi_template = { - name: "bt848/878 vbi", - type: VID_TYPE_TUNER|VID_TYPE_TELETEXT, - hardware: VID_HARDWARE_BT848, - fops: &bttv_fops, - minor: -1, + .name = "bt848/878 vbi", + .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT, + .hardware = VID_HARDWARE_BT848, + .fops = &bttv_fops, + .minor = -1, }; /* ----------------------------------------------------------------------- */ @@ -2841,20 +2841,20 @@ static int radio_ioctl(struct inode *inode, struct file *file, static struct file_operations radio_fops = { - owner: THIS_MODULE, - open: radio_open, - release: radio_release, - ioctl: radio_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = radio_open, + .release = radio_release, + .ioctl = radio_ioctl, + .llseek = no_llseek, }; static struct video_device radio_template = { - name: "bt848/878 radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_BT848, - fops: &radio_fops, - minor: -1, + .name = "bt848/878 radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_BT848, + .fops = &radio_fops, + .minor = -1, }; /* ----------------------------------------------------------------------- */ @@ -3439,10 +3439,10 @@ static struct pci_device_id bttv_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, bttv_pci_tbl); static struct pci_driver bttv_pci_driver = { - name: "bttv", - id_table: bttv_pci_tbl, - probe: bttv_probe, - remove: __devexit_p(bttv_remove), + .name = "bttv", + .id_table = bttv_pci_tbl, + .probe = bttv_probe, + .remove = __devexit_p(bttv_remove), }; static int bttv_init_module(void) diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c index 8702788cfc90..08eff8c66cfa 100644 --- a/drivers/media/video/bttv-if.c +++ b/drivers/media/video/bttv-if.c @@ -262,27 +262,27 @@ void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg) } static struct i2c_algo_bit_data bttv_i2c_algo_template = { - setsda: bttv_bit_setsda, - setscl: bttv_bit_setscl, - getsda: bttv_bit_getsda, - getscl: bttv_bit_getscl, - udelay: 16, - mdelay: 10, - timeout: 200, + .setsda = bttv_bit_setsda, + .setscl = bttv_bit_setscl, + .getsda = bttv_bit_getsda, + .getscl = bttv_bit_getscl, + .udelay = 16, + .mdelay = 10, + .timeout = 200, }; static struct i2c_adapter bttv_i2c_adap_template = { - name: "bt848", - id: I2C_HW_B_BT848, - inc_use: bttv_inc_use, - dec_use: bttv_dec_use, - client_register: attach_inform, - client_unregister: detach_inform, + .name = "bt848", + .id = I2C_HW_B_BT848, + .inc_use = bttv_inc_use, + .dec_use = bttv_dec_use, + .client_register = attach_inform, + .client_unregister = detach_inform, }; static struct i2c_client bttv_i2c_client_template = { - name: "bttv internal use only", - id: -1, + .name = "bttv internal use only", + .id = -1, }; diff --git a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c index 4bba17c6d51e..754256d4924e 100644 --- a/drivers/media/video/bttv-vbi.c +++ b/drivers/media/video/bttv-vbi.c @@ -123,10 +123,10 @@ static void vbi_buffer_release(struct file *file, struct videobuf_buffer *vb) } struct videobuf_queue_ops bttv_vbi_qops = { - buf_setup: vbi_buffer_setup, - buf_prepare: vbi_buffer_prepare, - buf_queue: vbi_buffer_queue, - buf_release: vbi_buffer_release, + .buf_setup = vbi_buffer_setup, + .buf_prepare = vbi_buffer_prepare, + .buf_queue = vbi_buffer_queue, + .buf_release = vbi_buffer_release, }; /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index fe6c48a9cd87..189225ebb5bf 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -885,20 +885,20 @@ static int qcam_read(struct file *file, char *buf, } static struct file_operations qcam_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: qcam_ioctl, - read: qcam_read, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = qcam_ioctl, + .read = qcam_read, + .llseek = no_llseek, }; static struct video_device qcam_template= { - owner: THIS_MODULE, - name: "Connectix Quickcam", - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_QCAM_BW, - fops: &qcam_fops, + .owner = THIS_MODULE, + .name = "Connectix Quickcam", + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_QCAM_BW, + .fops = &qcam_fops, }; #define MAX_CAMS 4 diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index e58f17589938..a28dc95daa9c 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c @@ -686,21 +686,21 @@ static int qcam_read(struct file *file, char *buf, /* video device template */ static struct file_operations qcam_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: qcam_ioctl, - read: qcam_read, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = qcam_ioctl, + .read = qcam_read, + .llseek = no_llseek, }; static struct video_device qcam_template= { - owner: THIS_MODULE, - name: "Colour QuickCam", - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_QCAM_C, - fops: &qcam_fops, + .owner = THIS_MODULE, + .name = "Colour QuickCam", + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_QCAM_C, + .fops = &qcam_fops, }; /* Initialize the QuickCam driver control structure. */ diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index d57cd471d6b4..1abef42a5896 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c @@ -3783,21 +3783,21 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma) } static struct file_operations cpia_fops = { - owner: THIS_MODULE, - open: cpia_open, - release: cpia_close, - read: cpia_read, - mmap: cpia_mmap, - ioctl: cpia_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = cpia_open, + .release = cpia_close, + .read = cpia_read, + .mmap = cpia_mmap, + .ioctl = cpia_ioctl, + .llseek = no_llseek, }; static struct video_device cpia_template = { - owner: THIS_MODULE, - name: "CPiA Camera", - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_CPIA, - fops: &cpia_fops, + .owner = THIS_MODULE, + .name = "CPiA Camera", + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_CPIA, + .fops = &cpia_fops, }; /* initialise cam_data structure */ diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c index d49f8d0fe742..1b4072e98676 100644 --- a/drivers/media/video/cpia_usb.c +++ b/drivers/media/video/cpia_usb.c @@ -582,10 +582,10 @@ MODULE_LICENSE("GPL"); static struct usb_driver cpia_driver = { - name: "cpia", - probe: cpia_probe, - disconnect: cpia_disconnect, - id_table: cpia_id_table, + .name = "cpia", + .probe = cpia_probe, + .disconnect = cpia_disconnect, + .id_table = cpia_id_table, }; /* don't use dev, it may be NULL! (see usb_cpia_cleanup) */ diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index 16e55db2a13c..343af442c095 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c @@ -1213,19 +1213,19 @@ static int msp_probe(struct i2c_adapter *adap); static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg); static struct i2c_driver driver = { - name: "i2c msp3400 driver", - id: I2C_DRIVERID_MSP3400, - flags: I2C_DF_NOTIFY, - attach_adapter: msp_probe, - detach_client: msp_detach, - command: msp_command, + .name = "i2cmsp3400driver", + .id = I2C_DRIVERID_MSP3400, + .flags = I2C_DF_NOTIFY, + .attach_adapter = msp_probe, + .detach_client = msp_detach, + .command = msp_command, }; static struct i2c_client client_template = { - name: "(unset)", - flags: I2C_CLIENT_ALLOW_USE, - driver: &driver, + .name = "(unset)", + .flags = I2C_CLIENT_ALLOW_USE, + .driver = &driver, }; static int msp_attach(struct i2c_adapter *adap, int addr, diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c index 84795ecae31f..619cc03012fb 100644 --- a/drivers/media/video/planb.c +++ b/drivers/media/video/planb.c @@ -2020,16 +2020,16 @@ static int planb_mmap(struct vm_area_struct *vma, struct video_device *dev, cons static struct video_device planb_template= { - owner: THIS_MODULE, - name: PLANB_DEVICE_NAME, - type: VID_TYPE_OVERLAY, - hardware: VID_HARDWARE_PLANB, - open: planb_open, - close: planb_close, - read: planb_read, - write: planb_write, - ioctl: planb_ioctl, - mmap: planb_mmap, /* mmap? */ + .owner = THIS_MODULE, + .name = PLANB_DEVICE_NAME, + .type = VID_TYPE_OVERLAY, + .hardware = VID_HARDWARE_PLANB, + .open = planb_open, + .close = planb_close, + .read = planb_read, + .write = planb_write, + .ioctl = planb_ioctl, + .mmap = planb_mmap, /* mmap? */ }; static int init_planb(struct planb *pb) diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 903d73fab67f..952b0b9865e1 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -875,21 +875,21 @@ static int pms_read(struct file *file, char *buf, } static struct file_operations pms_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: pms_ioctl, - read: pms_read, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = pms_ioctl, + .read = pms_read, + .llseek = no_llseek, }; static struct video_device pms_template= { - owner: THIS_MODULE, - name: "Mediavision PMS", - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_PMS, - fops: &pms_fops, + .owner = THIS_MODULE, + .name = "Mediavision PMS", + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_PMS, + .fops = &pms_fops, }; struct pms_device pms_device; diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 8082f27ad51a..30041f612215 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -678,20 +678,20 @@ module_init(init_saa_5249); module_exit(cleanup_saa_5249); static struct file_operations saa_fops = { - owner: THIS_MODULE, - open: saa5249_open, - release: saa5249_release, - ioctl: saa5249_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = saa5249_open, + .release = saa5249_release, + .ioctl = saa5249_ioctl, + .llseek = no_llseek, }; static struct video_device saa_template = { - owner: THIS_MODULE, - name: IF_NAME, - type: VID_TYPE_TELETEXT, /*| VID_TYPE_TUNER ?? */ - hardware: VID_HARDWARE_SAA5249, - fops: &saa_fops, + .owner = THIS_MODULE, + .name = IF_NAME, + .type = VID_TYPE_TELETEXT, /*| VID_TYPE_TUNER ?? */ + .hardware = VID_HARDWARE_SAA5249, + .fops = &saa_fops, }; MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index f72e30e8ca27..71b87992b921 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c @@ -1970,16 +1970,16 @@ static void saa_close(struct video_device *dev) /* template for video_device-structure */ static struct video_device saa_template = { - owner: THIS_MODULE, - name: "SAA7146A", - type: VID_TYPE_CAPTURE | VID_TYPE_OVERLAY, - hardware: VID_HARDWARE_SAA7146, - open: saa_open, - close: saa_close, - read: saa_read, - write: saa_write, - ioctl: saa_ioctl, - mmap: saa_mmap, + .owner = THIS_MODULE, + .name = "SAA7146A", + .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY, + .hardware = VID_HARDWARE_SAA7146, + .open = saa_open, + .close = saa_close, + .read = saa_read, + .write = saa_write, + .ioctl = saa_ioctl, + .mmap = saa_mmap, }; static int configure_saa7146(struct pci_dev *dev, int num) diff --git a/drivers/media/video/tuner.c b/drivers/media/video/tuner.c index 30667c249859..0c08bf609dc4 100644 --- a/drivers/media/video/tuner.c +++ b/drivers/media/video/tuner.c @@ -975,18 +975,18 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) /* ----------------------------------------------------------------------- */ static struct i2c_driver driver = { - name: "i2c TV tuner driver", - id: I2C_DRIVERID_TUNER, - flags: I2C_DF_NOTIFY, - attach_adapter: tuner_probe, - detach_client: tuner_detach, - command: tuner_command, + .name = "i2cTVtunerdriver", + .id = I2C_DRIVERID_TUNER, + .flags = I2C_DF_NOTIFY, + .attach_adapter = tuner_probe, + .detach_client = tuner_detach, + .command = tuner_command, }; -static struct i2c_client client_template = +static structi2c_clientclient_template = { - name: "(tuner unset)", - flags: I2C_CLIENT_ALLOW_USE, - driver: &driver, + .name = "(tunerunset)", + .flags = I2C_CLIENT_ALLOW_USE, + .driver = &driver, }; static int tuner_init_module(void) diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 918279589180..3aba1116f4d7 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1156,167 +1156,167 @@ MODULE_PARM(pic16c54,"i"); static struct CHIPDESC chiplist[] = { { - name: "tda9840", - id: I2C_DRIVERID_TDA9840, - insmodopt: &tda9840, - addr_lo: I2C_TDA9840 >> 1, - addr_hi: I2C_TDA9840 >> 1, - registers: 5, - - getmode: tda9840_getmode, - setmode: tda9840_setmode, - checkmode: generic_checkmode, - - init: { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN + .name = "tda9840", + .id = I2C_DRIVERID_TDA9840, + .insmodopt = &tda9840, + .addr_lo = I2C_TDA9840 >> 1, + .addr_hi = I2C_TDA9840 >> 1, + .registers = 5, + + .getmode = tda9840_getmode, + .setmode = tda9840_setmode, + .checkmode = generic_checkmode, + + .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN /* ,TDA9840_SW, TDA9840_MONO */} } }, { - name: "tda9873h", - id: I2C_DRIVERID_TDA9873, - checkit: tda9873_checkit, - insmodopt: &tda9873, - addr_lo: I2C_TDA985x_L >> 1, - addr_hi: I2C_TDA985x_H >> 1, - registers: 3, - flags: CHIP_HAS_INPUTSEL, - - getmode: tda9873_getmode, - setmode: tda9873_setmode, - checkmode: generic_checkmode, - - init: { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } }, - inputreg: TDA9873_SW, - inputmute: TDA9873_MUTE | TDA9873_AUTOMUTE, - inputmap: {0xa0, 0xa2, 0xa0, 0xa0, 0xc0}, - inputmask: TDA9873_INP_MASK | TDA9873_MUTE | TDA9873_AUTOMUTE + .name = "tda9873h", + .id = I2C_DRIVERID_TDA9873, + .checkit = tda9873_checkit, + .insmodopt = &tda9873, + .addr_lo = I2C_TDA985x_L >> 1, + .addr_hi = I2C_TDA985x_H >> 1, + .registers = 3, + .flags = CHIP_HAS_INPUTSEL, + + .getmode = tda9873_getmode, + .setmode = tda9873_setmode, + .checkmode = generic_checkmode, + + .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } }, + .inputreg = TDA9873_SW, + .inputmute = TDA9873_MUTE | TDA9873_AUTOMUTE, + .inputmap = {0xa0, 0xa2, 0xa0, 0xa0, 0xc0}, + .inputmask = TDA9873_INP_MASK | TDA9873_MUTE | TDA9873_AUTOMUTE }, { - name: "tda9874h/a", - id: I2C_DRIVERID_TDA9874, - checkit: tda9874a_checkit, - initialize: tda9874a_initialize, - insmodopt: &tda9874a, - addr_lo: I2C_TDA9874 >> 1, - addr_hi: I2C_TDA9874 >> 1, - - getmode: tda9874a_getmode, - setmode: tda9874a_setmode, - checkmode: generic_checkmode, + .name = "tda9874h/a", + .id = I2C_DRIVERID_TDA9874, + .checkit = tda9874a_checkit, + .initialize = tda9874a_initialize, + .insmodopt = &tda9874a, + .addr_lo = I2C_TDA9874 >> 1, + .addr_hi = I2C_TDA9874 >> 1, + + .getmode = tda9874a_getmode, + .setmode = tda9874a_setmode, + .checkmode = generic_checkmode, }, { - name: "tda9850", - id: I2C_DRIVERID_TDA9850, - insmodopt: &tda9850, - addr_lo: I2C_TDA985x_L >> 1, - addr_hi: I2C_TDA985x_H >> 1, - registers: 11, + .name = "tda9850", + .id = I2C_DRIVERID_TDA9850, + .insmodopt = &tda9850, + .addr_lo = I2C_TDA985x_L >> 1, + .addr_hi = I2C_TDA985x_H >> 1, + .registers = 11, - getmode: tda985x_getmode, - setmode: tda985x_setmode, + .getmode = tda985x_getmode, + .setmode = tda985x_setmode, - init: { 8, { TDA9850_C4, 0x08, 0x08, TDA985x_STEREO, 0x07, 0x10, 0x10, 0x03 } } + .init = { 8, { TDA9850_C4, 0x08, 0x08, TDA985x_STEREO, 0x07, 0x10, 0x10, 0x03 } } }, { - name: "tda9855", - id: I2C_DRIVERID_TDA9855, - insmodopt: &tda9855, - addr_lo: I2C_TDA985x_L >> 1, - addr_hi: I2C_TDA985x_H >> 1, - registers: 11, - flags: CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE, - - leftreg: TDA9855_VL, - rightreg: TDA9855_VR, - bassreg: TDA9855_BA, - treblereg: TDA9855_TR, - volfunc: tda9855_volume, - bassfunc: tda9855_bass, - treblefunc: tda9855_treble, - - getmode: tda985x_getmode, - setmode: tda985x_setmode, - - init: { 12, { 0, 0x6f, 0x6f, 0x0e, 0x07<<1, 0x8<<2, + .name = "tda9855", + .id = I2C_DRIVERID_TDA9855, + .insmodopt = &tda9855, + .addr_lo = I2C_TDA985x_L >> 1, + .addr_hi = I2C_TDA985x_H >> 1, + .registers = 11, + .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE, + + .leftreg = TDA9855_VL, + .rightreg = TDA9855_VR, + .bassreg = TDA9855_BA, + .treblereg = TDA9855_TR, + .volfunc = tda9855_volume, + .bassfunc = tda9855_bass, + .treblefunc = tda9855_treble, + + .getmode = tda985x_getmode, + .setmode = tda985x_setmode, + + .init = { 12, { 0, 0x6f, 0x6f, 0x0e, 0x07<<1, 0x8<<2, TDA9855_MUTE | TDA9855_AVL | TDA9855_LOUD | TDA9855_INT, TDA985x_STEREO | TDA9855_LINEAR | TDA9855_TZCM | TDA9855_VZCM, 0x07, 0x10, 0x10, 0x03 }} }, { - name: "tea6300", - id: I2C_DRIVERID_TEA6300, - insmodopt: &tea6300, - addr_lo: I2C_TEA6300 >> 1, - addr_hi: I2C_TEA6300 >> 1, - registers: 6, - flags: CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL, - - leftreg: TEA6300_VR, - rightreg: TEA6300_VL, - bassreg: TEA6300_BA, - treblereg: TEA6300_TR, - volfunc: tea6300_shift10, - bassfunc: tea6300_shift12, - treblefunc: tea6300_shift12, - - inputreg: TEA6300_S, - inputmap: { TEA6300_S_SA, TEA6300_S_SB, TEA6300_S_SC }, - inputmute: TEA6300_S_GMU, + .name = "tea6300", + .id = I2C_DRIVERID_TEA6300, + .insmodopt = &tea6300, + .addr_lo = I2C_TEA6300 >> 1, + .addr_hi = I2C_TEA6300 >> 1, + .registers = 6, + .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL, + + .leftreg = TEA6300_VR, + .rightreg = TEA6300_VL, + .bassreg = TEA6300_BA, + .treblereg = TEA6300_TR, + .volfunc = tea6300_shift10, + .bassfunc = tea6300_shift12, + .treblefunc = tea6300_shift12, + + .inputreg = TEA6300_S, + .inputmap = { TEA6300_S_SA, TEA6300_S_SB, TEA6300_S_SC }, + .inputmute = TEA6300_S_GMU, }, { - name: "tea6420", - id: I2C_DRIVERID_TEA6420, - insmodopt: &tea6420, - addr_lo: I2C_TEA6420 >> 1, - addr_hi: I2C_TEA6420 >> 1, - registers: 1, - flags: CHIP_HAS_INPUTSEL, - - inputreg: -1, - inputmap: { TEA6420_S_SA, TEA6420_S_SB, TEA6420_S_SC }, - inputmute: TEA6300_S_GMU, + .name = "tea6420", + .id = I2C_DRIVERID_TEA6420, + .insmodopt = &tea6420, + .addr_lo = I2C_TEA6420 >> 1, + .addr_hi = I2C_TEA6420 >> 1, + .registers = 1, + .flags = CHIP_HAS_INPUTSEL, + + .inputreg = -1, + .inputmap = { TEA6420_S_SA, TEA6420_S_SB, TEA6420_S_SC }, + .inputmute = TEA6300_S_GMU, }, { - name: "tda8425", - id: I2C_DRIVERID_TDA8425, - insmodopt: &tda8425, - addr_lo: I2C_TDA8425 >> 1, - addr_hi: I2C_TDA8425 >> 1, - registers: 9, - flags: CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL, - - leftreg: TDA8425_VR, - rightreg: TDA8425_VL, - bassreg: TDA8425_BA, - treblereg: TDA8425_TR, - volfunc: tda8425_shift10, - bassfunc: tda8425_shift12, - treblefunc: tda8425_shift12, - - inputreg: TDA8425_S1, - inputmap: { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 }, - inputmute: TDA8425_S1_OFF, - - setmode: tda8425_setmode, + .name = "tda8425", + .id = I2C_DRIVERID_TDA8425, + .insmodopt = &tda8425, + .addr_lo = I2C_TDA8425 >> 1, + .addr_hi = I2C_TDA8425 >> 1, + .registers = 9, + .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL, + + .leftreg = TDA8425_VR, + .rightreg = TDA8425_VL, + .bassreg = TDA8425_BA, + .treblereg = TDA8425_TR, + .volfunc = tda8425_shift10, + .bassfunc = tda8425_shift12, + .treblefunc = tda8425_shift12, + + .inputreg = TDA8425_S1, + .inputmap = { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 }, + .inputmute = TDA8425_S1_OFF, + + .setmode = tda8425_setmode, }, { - name: "pic16c54 (PV951)", - id: I2C_DRIVERID_PIC16C54_PV951, - insmodopt: &pic16c54, - addr_lo: I2C_PIC16C54 >> 1, - addr_hi: I2C_PIC16C54>> 1, - registers: 2, - flags: CHIP_HAS_INPUTSEL, - - inputreg: PIC16C54_REG_MISC, - inputmap: {PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_TUNER, + .name = "pic16c54 (PV951)", + .id = I2C_DRIVERID_PIC16C54_PV951, + .insmodopt = &pic16c54, + .addr_lo = I2C_PIC16C54 >> 1, + .addr_hi = I2C_PIC16C54>> 1, + .registers = 2, + .flags = CHIP_HAS_INPUTSEL, + + .inputreg = PIC16C54_REG_MISC, + .inputmap = {PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_TUNER, PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE, PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE, PIC16C54_MISC_SND_MUTE,PIC16C54_MISC_SND_MUTE, PIC16C54_MISC_SND_NOTMUTE}, - inputmute: PIC16C54_MISC_SND_MUTE, + .inputmute = PIC16C54_MISC_SND_MUTE, }, - { name: NULL } /* EOF */ + { .name = NULL } /* EOF */ }; @@ -1544,19 +1544,19 @@ static int chip_command(struct i2c_client *client, static struct i2c_driver driver = { - name: "generic i2c audio driver", - id: I2C_DRIVERID_TVAUDIO, - flags: I2C_DF_NOTIFY, - attach_adapter: chip_probe, - detach_client: chip_detach, - command: chip_command, + .name = "generic i2c audio driver", + .id = I2C_DRIVERID_TVAUDIO, + .flags = I2C_DF_NOTIFY, + .attach_adapter = chip_probe, + .detach_client = chip_detach, + .command = chip_command, }; static struct i2c_client client_template = { - name: "(unset)", - flags: I2C_CLIENT_ALLOW_USE, - driver: &driver, + .name = "(unset)", + .flags = I2C_CLIENT_ALLOW_USE, + .driver = &driver, }; static int audiochip_init_module(void) diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c index 9f6f353f92b4..62f1b96b0e78 100644 --- a/drivers/media/video/tvmixer.c +++ b/drivers/media/video/tvmixer.c @@ -217,19 +217,19 @@ static int tvmixer_release(struct inode *inode, struct file *file) static struct i2c_driver driver = { - name: "tv card mixer driver", - id: I2C_DRIVERID_TVMIXER, - flags: I2C_DF_DUMMY, - attach_adapter: tvmixer_adapters, - detach_client: tvmixer_clients, + .name = "tv card mixer driver", + .id = I2C_DRIVERID_TVMIXER, + .flags = I2C_DF_DUMMY, + .attach_adapter = tvmixer_adapters, + .detach_client = tvmixer_clients, }; static struct file_operations tvmixer_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - ioctl: tvmixer_ioctl, - open: tvmixer_open, - release: tvmixer_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .ioctl = tvmixer_ioctl, + .open = tvmixer_open, + .release = tvmixer_release, }; /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c index 25a1d93482c0..2f51c2a9fa2f 100644 --- a/drivers/media/video/video-buf.c +++ b/drivers/media/video/video-buf.c @@ -926,9 +926,9 @@ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr, static struct vm_operations_struct videobuf_vm_ops = { - open: videobuf_vm_open, - close: videobuf_vm_close, - nopage: videobuf_vm_nopage, + .open = videobuf_vm_open, + .close = videobuf_vm_close, + .nopage = videobuf_vm_nopage, }; int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q, diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index aef31f7155d5..a7da10718413 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -472,9 +472,9 @@ void video_unregister_device(struct video_device *vfd) static struct file_operations video_fops= { - owner: THIS_MODULE, - llseek: no_llseek, - open: video_open, + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = video_open, }; /* diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index c64efb7794ee..25f4f2fe1c97 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -222,14 +222,14 @@ static int vino_mmap(struct video_device *dev, const char *adr, } static struct video_device vino_dev = { - owner: THIS_MODULE, - name: "Vino IndyCam/TV", - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_VINO, - open: vino_open, - close: vino_close, - ioctl: vino_ioctl, - mmap: vino_mmap, + .owner = THIS_MODULE, + .name = "Vino IndyCam/TV", + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_VINO, + .open = vino_open, + .close = vino_close, + .ioctl = vino_ioctl, + .mmap = vino_mmap, }; int __init init_vino(struct video_device *dev) diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index b7fb6f24ee5f..4c8402672645 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -179,19 +179,19 @@ static int w9966_v4l_read(struct file *file, char *buf, size_t count, loff_t *ppos); static struct file_operations w9966_fops = { - owner: THIS_MODULE, - open: video_exclusive_open, - release: video_exclusive_release, - ioctl: w9966_v4l_ioctl, - read: w9966_v4l_read, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = video_exclusive_open, + .release = video_exclusive_release, + .ioctl = w9966_v4l_ioctl, + .read = w9966_v4l_read, + .llseek = no_llseek, }; static struct video_device w9966_template = { - owner: THIS_MODULE, - name: W9966_DRIVERNAME, - type: VID_TYPE_CAPTURE | VID_TYPE_SCALES, - hardware: VID_HARDWARE_W9966, - fops: &w9966_fops, + .owner = THIS_MODULE, + .name = W9966_DRIVERNAME, + .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES, + .hardware = VID_HARDWARE_W9966, + .fops = &w9966_fops, }; /* @@ -710,14 +710,13 @@ static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file, case VIDIOCGCAP: { static struct video_capability vcap = { - name: W9966_DRIVERNAME, - type: VID_TYPE_CAPTURE | VID_TYPE_SCALES, - channels: 1, - audios: 0, - maxwidth: W9966_WND_MAX_W, - maxheight: W9966_WND_MAX_H, - minwidth: 2, - minheight: 1, + .name = W9966_DRIVERNAME, + .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES, + .channels = 1, + .maxwidth = W9966_WND_MAX_W, + .maxheight = W9966_WND_MAX_H, + .minwidth = 2, + .minheight = 1, }; struct video_capability *cap = arg; *cap = vcap; diff --git a/drivers/media/video/zr36067.c b/drivers/media/video/zr36067.c index 7c7c4aab1d92..70478175aaee 100644 --- a/drivers/media/video/zr36067.c +++ b/drivers/media/video/zr36067.c @@ -4396,18 +4396,18 @@ static int zoran_init_done(struct video_device *dev) } static struct video_device zoran_template = { - owner: THIS_MODULE, - name: ZORAN_NAME, - type: VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CLIPPING | + .owner = THIS_MODULE, + .name = ZORAN_NAME, + .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM | VID_TYPE_SCALES | VID_TYPE_SUBCAPTURE, - hardware: ZORAN_HARDWARE, - open: zoran_open, - close: zoran_close, - read: zoran_read, - write: zoran_write, - ioctl: zoran_ioctl, - mmap: zoran_mmap, - initialize: zoran_init_done, + .hardware = ZORAN_HARDWARE, + .open = zoran_open, + .close = zoran_close, + .read = zoran_read, + .write = zoran_write, + .ioctl = zoran_ioctl, + .mmap = zoran_mmap, + .initialize = zoran_init_done, }; /* diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c index 931361d4abcd..7c4c9a82dc58 100644 --- a/drivers/media/video/zr36120.c +++ b/drivers/media/video/zr36120.c @@ -1490,18 +1490,18 @@ int zoran_mmap(struct vm_area_struct *vma, struct video_device* dev, const char* static struct video_device zr36120_template= { - owner: THIS_MODULE, - name: "UNSET", - type: VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY, - hardware: VID_HARDWARE_ZR36120, - open: zoran_open, - close: zoran_close, - read: zoran_read, - write: zoran_write, - poll: zoran_poll, - ioctl: zoran_ioctl, - mmap: zoran_mmap, - minor: -1, + .owner = THIS_MODULE, + .name = "UNSET", + .type = VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY, + .hardware = VID_HARDWARE_ZR36120, + .open = zoran_open, + .close = zoran_close, + .read = zoran_read, + .write = zoran_write, + .poll = zoran_poll, + .ioctl = zoran_ioctl, + .mmap = zoran_mmap, + .minor = -1, }; static @@ -1826,17 +1826,17 @@ int vbi_ioctl(struct video_device *dev, unsigned int cmd, void *arg) static struct video_device vbi_template= { - owner: THIS_MODULE, - name: "UNSET", - type: VID_TYPE_CAPTURE|VID_TYPE_TELETEXT, - hardware: VID_HARDWARE_ZR36120, - open: vbi_open, - close: vbi_close, - read: vbi_read, - write: zoran_write, - poll: vbi_poll, - ioctl: vbi_ioctl, - minor: -1, + .owner = THIS_MODULE, + .name = "UNSET", + .type = VID_TYPE_CAPTURE|VID_TYPE_TELETEXT, + .hardware = VID_HARDWARE_ZR36120, + .open = vbi_open, + .close = vbi_close, + .read = vbi_read, + .write = zoran_write, + .poll = vbi_poll, + .ioctl = vbi_ioctl, + .minor = -1, }; /* diff --git a/drivers/net/fec.c b/drivers/net/fec.c index aae5158d3cb4..045e34f6ce7f 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -196,6 +196,7 @@ static struct net_device_stats *fec_enet_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static void fec_restart(struct net_device *dev, int duplex); static void fec_stop(struct net_device *dev); +static void fec_set_mac_address(struct net_device *dev); /* MII processing. We keep this as simple as possible. Requests are @@ -1479,6 +1480,8 @@ fec_enet_open(struct net_device *dev) * a simple way to do that. */ + fec_set_mac_address(dev); + fep->sequence_done = 0; fep->link = 0; @@ -1487,6 +1490,10 @@ fec_enet_open(struct net_device *dev) mii_do_cmd(dev, fep->phy->config); mii_do_cmd(dev, phy_cmd_config); /* display configuration */ + /* FIXME: use netif_carrier_{on,off} ; this polls + * until link is up which is wrong... could be + * 30 seconds or more we are trapped in here. -jgarzik + */ while(!fep->sequence_done) schedule(); @@ -1602,6 +1609,25 @@ static void set_multicast_list(struct net_device *dev) } } +/* Set a MAC change in hardware. + */ +static void +fec_set_mac_address(struct net_device *dev) +{ + int i; + volatile fec_t *fecp; + + fecp = fec_hwp; + + /* Set our copy of the Ethernet address */ + for (i = 0; i < (ETH_ALEN / 2); i++) + my_enet_addr[i] = (dev->dev_addr[i*2] << 8) | dev->dev_addr[i*2 + 1]; + + /* Set station address. */ + fecp->fec_addr_low = (my_enet_addr[0] << 16) | my_enet_addr[1]; + fecp->fec_addr_high = my_enet_addr[2] << 16; +} + /* Initialize the FEC Ethernet on 860T (or ColdFire 5272). */ int __init fec_enet_init(struct net_device *dev) @@ -1643,6 +1669,9 @@ int __init fec_enet_init(struct net_device *dev) /* Set the Ethernet address. If using multiple Enets on the 8xx, * this needs some work to get unique addresses. + * + * This is our default MAC address unless the user changes + * it via eth_mac_addr (our dev->set_mac_addr handler). */ fec_get_mac(dev, fep); @@ -1767,9 +1796,9 @@ fec_restart(struct net_device *dev, int duplex) { struct fec_enet_private *fep; int i; - unsigned char *eap; - volatile cbd_t *bdp; - volatile fec_t *fecp; + unsigned char *eap; + volatile cbd_t *bdp; + volatile fec_t *fecp; fecp = fec_hwp; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5c7a4c036755..c973c999ef00 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -88,6 +88,8 @@ pci_max_busnr(void) * %PCI_CAP_ID_MSI Message Signalled Interrupts * * %PCI_CAP_ID_CHSWP CompactPCI HotSwap + * + * %PCI_CAP_ID_PCIX PCI-X */ int pci_find_capability(struct pci_dev *dev, int cap) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c03c9eb68d03..368628cc6457 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -301,7 +301,8 @@ static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev) #ifdef CONFIG_X86_IO_APIC -extern int nr_ioapics; + +#include <asm/io_apic.h> /* * VIA 686A/B: If an IO-APIC is active, we need to route all on-chip @@ -561,7 +562,7 @@ static struct pci_fixup pci_fixups[] __devinitdata = { #ifdef CONFIG_X86_IO_APIC { PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic }, - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_SIS, PCI_ANY_ID, quirk_ioapic_rmw }, + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw }, #endif { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi }, diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 9f12ff77a60e..864cbfdc40e9 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -124,8 +124,6 @@ #include <linux/spinlock.h> #include <linux/sched.h> #include <linux/proc_fs.h> -#include <linux/init.h> -#include <linux/mca.h> #include <asm/dma.h> #include <asm/system.h> #include <asm/io.h> @@ -236,7 +234,7 @@ static __u8 NCR_700_SDTR_msg[] = { NCR_700_MAX_OFFSET }; -struct Scsi_Host * __init +struct Scsi_Host * NCR_700_detect(Scsi_Host_Template *tpnt, struct NCR_700_Host_Parameters *hostdata) { @@ -2020,3 +2018,5 @@ NCR_700_slave_destroy(Scsi_Device *SDp) EXPORT_SYMBOL(NCR_700_detect); EXPORT_SYMBOL(NCR_700_release); EXPORT_SYMBOL(NCR_700_intr); + +no_module_init; diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 4f0f1924b832..0aa695f1df9d 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -123,7 +123,8 @@ obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o obj-$(CONFIG_CHR_DEV_SG) += sg.o scsi_mod-objs := scsi.o hosts.o scsi_ioctl.o constants.o scsicam.o \ - scsi_error.o scsi_lib.o scsi_scan.o scsi_syms.o + scsi_error.o scsi_lib.o scsi_scan.o scsi_syms.o \ + scsi_sysfs.o ifdef CONFIG_PROC_FS scsi_mod-objs += scsi_proc.o diff --git a/drivers/scsi/NCR_D700.h b/drivers/scsi/NCR_D700.h index cd9e4829b3a9..7ac6adeddf14 100644 --- a/drivers/scsi/NCR_D700.h +++ b/drivers/scsi/NCR_D700.h @@ -22,11 +22,11 @@ static int D700_release(struct Scsi_Host *host); * remaining parameters shown below must be filled in. The 53c700 * routine NCR_700_detect will fill in all of the missing routines */ #define NCR_D700_SCSI { \ - name: "NCR Dual 700 MCA", \ - proc_name: "NCR_D700", \ - detect: D700_detect, \ - release: D700_release, \ - this_id: 7, \ + .name = "NCR Dual 700 MCA", \ + .proc_name = "NCR_D700", \ + .detect = D700_detect, \ + .release = D700_release, \ + .this_id = 7, \ } diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 19ba1fa9a770..c5b1a9352393 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1113,12 +1113,12 @@ static int query_disk(struct aac_dev *dev, void *arg) qd.locked = fsa_dev_ptr->locked[qd.cnum]; qd.deleted = fsa_dev_ptr->deleted[qd.cnum]; - if (fsa_dev_ptr->devno[qd.cnum][0] == '\0') + if (fsa_dev_ptr->devname[qd.cnum][0] == '\0') qd.unmapped = 1; else qd.unmapped = 0; - strncpy(dq.name, fsa_dev_ptr->devname[qd.cnum], 8); + strncpy(qd.name, fsa_dev_ptr->devname[qd.cnum], 8); if (copy_to_user(arg, &qd, sizeof (struct aac_query_disk))) return -EFAULT; @@ -1170,7 +1170,7 @@ static int delete_disk(struct aac_dev *dev, void *arg) * Mark the container as no longer being valid. */ fsa_dev_ptr->valid[dd.cnum] = 0; - fsa_dev_ptr->devno[dd.cnum][0] = '\0'; + fsa_dev_ptr->devname[dd.cnum][0] = '\0'; return 0; } } diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 94060b3059ce..4256415819a0 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -36,7 +36,6 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/list.h> -#include <linux/smp_lock.h> #define __KERNEL_SYSCALLS__ @@ -50,7 +49,6 @@ static LIST_HEAD(scsi_host_list); static spinlock_t scsi_host_list_lock = SPIN_LOCK_UNLOCKED; static int scsi_host_next_hn; /* host_no for next new host */ -static int scsi_hosts_registered; /* cnt of registered scsi hosts */ static char *scsihosts; MODULE_PARM(scsihosts, "s"); @@ -173,14 +171,14 @@ int scsi_tp_for_each_host(Scsi_Host_Template *shost_tp, int } /** - * scsi_host_generic_release - default release function for hosts + * scsi_host_legacy_release - default release function for hosts * @shost: * * Description: * This is the default case for the release function. Its completely * useless for anything but old ISA adapters **/ -static void scsi_host_legacy_release(struct Scsi_Host *shost) +static int scsi_host_legacy_release(struct Scsi_Host *shost) { if (shost->irq) free_irq(shost->irq, NULL); @@ -188,23 +186,17 @@ static void scsi_host_legacy_release(struct Scsi_Host *shost) free_dma(shost->dma_channel); if (shost->io_port && shost->n_io_port) release_region(shost->io_port, shost->n_io_port); + + return 0; } static int scsi_remove_legacy_host(struct Scsi_Host *shost) { - int error, pcount = scsi_hosts_registered; + int error; error = scsi_remove_host(shost); - if (error) - return error; - - if (shost->hostt->release) + if (!error) (*shost->hostt->release)(shost); - else - scsi_host_legacy_release(shost); - - if (pcount == scsi_hosts_registered) - scsi_unregister(shost); return 0; } @@ -260,7 +252,6 @@ active: int scsi_remove_host(struct Scsi_Host *shost) { struct scsi_device *sdev; - struct list_head *le, *lh; /* * FIXME Do ref counting. We force all of the devices offline to @@ -287,20 +278,13 @@ int scsi_remove_host(struct Scsi_Host *shost) sdev->attached); return 1; } - devfs_unregister(sdev->de); - device_unregister(&sdev->sdev_driverfs_dev); - } - - /* Next we free up the Scsi_Cmnd structures for this host */ - - list_for_each_safe(le, lh, &shost->my_devices) { - scsi_free_sdev(list_entry(le, Scsi_Device, siblings)); } + scsi_forget_host(shost); return 0; } -int scsi_add_host(struct Scsi_Host *shost) +int __scsi_add_host(struct Scsi_Host *shost) { Scsi_Host_Template *sht = shost->hostt; struct scsi_device *sdev; @@ -309,7 +293,6 @@ int scsi_add_host(struct Scsi_Host *shost) printk(KERN_INFO "scsi%d : %s\n", shost->host_no, sht->info ? sht->info(shost) : sht->name); - device_register(&shost->host_driverfs_dev); scsi_scan_host(shost); list_for_each_entry (sdev, &shost->my_devices, siblings) { @@ -322,6 +305,22 @@ int scsi_add_host(struct Scsi_Host *shost) } /** + * scsi_add_host - add a scsi host + * @shost: scsi host pointer to add + * @dev: a struct device of type scsi class + * + * Return value: + * 0 on success / != 0 for error + **/ +int scsi_add_host(struct Scsi_Host *shost, struct device *dev) +{ + dev->class_data = shost; + shost->host_gendev = dev; + + return __scsi_add_host(shost); +} + +/** * scsi_unregister - unregister a scsi host * @shost: scsi host to be unregistered **/ @@ -343,12 +342,10 @@ void scsi_unregister(struct Scsi_Host *shost) shost->eh_notify = NULL; } - scsi_hosts_registered--; shost->hostt->present--; - /* Cleanup proc and driverfs */ + /* Cleanup proc */ scsi_proc_host_rm(shost); - device_unregister(&shost->host_driverfs_dev); kfree(shost); } @@ -395,7 +392,6 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes) memset(shost, 0, sizeof(struct Scsi_Host) + xtr_bytes); shost->host_no = scsi_alloc_host_num(shost_tp->proc_name); - scsi_hosts_registered++; spin_lock_init(&shost->default_lock); scsi_assign_lock(shost, &shost->default_lock); @@ -462,11 +458,6 @@ found: scsi_proc_host_add(shost); - strncpy(shost->host_driverfs_dev.name, shost_tp->proc_name, - DEVICE_NAME_SIZE-1); - sprintf(shost->host_driverfs_dev.bus_id, "scsi%d", - shost->host_no); - shost->eh_notify = &sem; kernel_thread((int (*)(void *)) scsi_error_handler, (void *) shost, 0); /* @@ -491,64 +482,34 @@ found: int scsi_register_host(Scsi_Host_Template *shost_tp) { struct Scsi_Host *shost; - int cur_cnt; - /* - * Check no detect routine. - */ - if (!shost_tp->detect) - return 1; + BUG_ON(!shost_tp->detect); - /* If max_sectors isn't set, default to max */ - if (!shost_tp->max_sectors) + if (!shost_tp->max_sectors) { + printk(KERN_WARNING + "scsi HBA driver %s didn't set max_sectors, " + "please fix the template", shost_tp->name); shost_tp->max_sectors = 1024; + } - cur_cnt = scsi_hosts_registered; - - /* - * The detect routine must carefully spinunlock/spinlock if it - * enables interrupts, since all interrupt handlers do spinlock as - * well. - */ + if (!shost_tp->release) { + printk(KERN_WARNING + "scsi HBA driver %s didn't set a release method, " + "please fix the template", shost_tp->name); + shost_tp->release = &scsi_host_legacy_release; + } - /* - * detect should do its own locking - * FIXME present is now set is scsi_register which breaks manual - * registration code below. - */ shost_tp->detect(shost_tp); if (!shost_tp->present) return 0; - if (cur_cnt == scsi_hosts_registered) { - if (shost_tp->present > 1) { - printk(KERN_ERR "scsi: Failure to register" - "low-level scsi driver"); - scsi_unregister_host(shost_tp); - return 1; - } - - /* - * The low-level driver failed to register a driver. - * We can do this now. - * - * XXX Who needs manual registration and why??? - */ - if (!scsi_register(shost_tp, 0)) { - printk(KERN_ERR "scsi: register failed.\n"); - scsi_unregister_host(shost_tp); - return 1; - } - } - - /* * XXX(hch) use scsi_tp_for_each_host() once it propagates * error returns properly. */ list_for_each_entry(shost, &scsi_host_list, sh_list) if (shost->hostt == shost_tp) - if (scsi_add_host(shost)) + if (__scsi_add_host(shost)) goto out_of_space; return 0; @@ -575,20 +536,7 @@ out_of_space: **/ int scsi_unregister_host(Scsi_Host_Template *shost_tp) { - int pcount; - - /* get the big kernel lock, so we don't race with open() */ - lock_kernel(); - - pcount = scsi_hosts_registered; - scsi_tp_for_each_host(shost_tp, scsi_remove_legacy_host); - - if (pcount != scsi_hosts_registered) - printk(KERN_INFO "scsi : %d host%s left.\n", scsi_hosts_registered, - (scsi_hosts_registered == 1) ? "" : "s"); - - unlock_kernel(); return 0; } @@ -668,64 +616,6 @@ void __init scsi_host_init(void) } } -/* - * Function: scsi_get_host_dev() - * - * Purpose: Create a Scsi_Device that points to the host adapter itself. - * - * Arguments: SHpnt - Host that needs a Scsi_Device - * - * Lock status: None assumed. - * - * Returns: The Scsi_Device or NULL - * - * Notes: - * Attach a single Scsi_Device to the Scsi_Host - this should - * be made to look like a "pseudo-device" that points to the - * HA itself. - * - * Note - this device is not accessible from any high-level - * drivers (including generics), which is probably not - * optimal. We can add hooks later to attach - */ -struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) -{ - struct scsi_device *sdev; - - sdev = scsi_alloc_sdev(shost, 0, shost->this_id, 0); - if (sdev) { - scsi_build_commandblocks(sdev); - if (sdev->current_queue_depth == 0) - goto fail; - sdev->borken = 0; - } - - return sdev; - -fail: - kfree(sdev); - return NULL; -} - -/* - * Function: scsi_free_host_dev() - * - * Purpose: Free a scsi_device that points to the host adapter itself. - * - * Arguments: SHpnt - Host that needs a Scsi_Device - * - * Lock status: None assumed. - * - * Returns: Nothing - * - * Notes: - */ -void scsi_free_host_dev(struct scsi_device *sdev) -{ - BUG_ON(sdev->id != sdev->host->this_id); - scsi_free_sdev(sdev); -} - void scsi_host_busy_inc(struct Scsi_Host *shost, Scsi_Device *sdev) { unsigned long flags; @@ -765,22 +655,3 @@ void scsi_host_failed_inc_and_test(struct Scsi_Host *shost) } spin_unlock_irqrestore(shost->host_lock, flags); } - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: nil - * tab-width: 8 - * End: - */ diff --git a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h index ed4299a38b9a..a620d60964c6 100644 --- a/drivers/scsi/hosts.h +++ b/drivers/scsi/hosts.h @@ -488,7 +488,7 @@ struct Scsi_Host /* * Support for driverfs filesystem */ - struct device host_driverfs_dev; + struct device *host_gendev; /* * We should ensure that this is aligned, both for better performance @@ -499,6 +499,8 @@ struct Scsi_Host __attribute__ ((aligned (sizeof(unsigned long)))); }; +#define to_scsi_host(d) d->class_data + /* * These two functions are used to allocate and free a pseudo device * which will connect to the host adapter itself rather than any @@ -524,7 +526,7 @@ static inline void scsi_set_pci_device(struct Scsi_Host *shost, struct pci_dev *pdev) { shost->pci_dev = pdev; - shost->host_driverfs_dev.parent=&pdev->dev; + shost->host_gendev = &pdev->dev; } @@ -532,12 +534,13 @@ static inline void scsi_set_pci_device(struct Scsi_Host *shost, * Prototypes for functions/data in scsi_scan.c */ extern void scsi_scan_host(struct Scsi_Host *); +extern void scsi_forget_host(struct Scsi_Host *); + struct Scsi_Device_Template { struct list_head list; const char * name; - const char * tag; struct module * module; /* Used for loadable modules */ unsigned char scsi_type; int (*attach)(Scsi_Device *); /* Attach devices to arrays */ @@ -565,7 +568,7 @@ extern void scsi_unregister(struct Scsi_Host *); /* * HBA registration/unregistration. */ -extern int scsi_add_host(struct Scsi_Host *); +extern int scsi_add_host(struct Scsi_Host *, struct device *); extern int scsi_remove_host(struct Scsi_Host *); /* @@ -603,7 +606,15 @@ static inline Scsi_Device *scsi_find_device(struct Scsi_Host *shost, break; return sdev; } - + +/* + * sysfs support + */ +extern int scsi_upper_driver_register(struct Scsi_Device_Template *); +extern void scsi_upper_driver_unregister(struct Scsi_Device_Template *); + +extern struct device_class shost_devclass; + #endif /* * Overrides for Emacs so that we follow Linus's tabbing style. diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 23c93359faba..45503e6ed485 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -13,18 +13,18 @@ order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale. - Copyright 1992 - 2000 Kai Makisara - email Kai.Makisara@metla.fi + Copyright 1992 - 2002 Kai Makisara / Willem Riede + email Kai.Makisara@metla.fi / osst@riede.org $Header: /home/cvsroot/Driver/osst.c,v 1.65 2001/11/11 20:38:56 riede Exp $ Microscopic alterations - Rik Ling, 2000/12/21 - Last modified: Wed Feb 2 22:04:05 2000 by makisara@kai.makisara.local + Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara Some small formal changes - aeb, 950809 */ static const char * cvsid = "$Id: osst.c,v 1.65 2001/11/11 20:38:56 riede Exp $"; -const char * osst_version = "0.9.10"; +const char * osst_version = "0.99.0p3"; /* The "failure to reconnect" firmware bug */ #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/ @@ -60,7 +60,6 @@ const char * osst_version = "0.9.10"; #define OSST_DEB_MSG KERN_NOTICE #define MAJOR_NR OSST_MAJOR -#define DEVICE_NR(device) (minor(device) & 0x7f) #include <linux/blk.h> #include "scsi.h" @@ -74,30 +73,32 @@ const char * osst_version = "0.9.10"; #include "osst_options.h" #include "osst_detect.h" -static int buffer_kbs = 0; +static int max_dev = 0; static int write_threshold_kbs = 0; -static int max_buffers = 0; static int max_sg_segs = 0; #ifdef MODULE MODULE_AUTHOR("Willem Riede"); -MODULE_DESCRIPTION("OnStream SCSI Tape Driver"); +MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(buffer_kbs, "i"); +MODULE_PARM(max_dev, "i"); +MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)"); + MODULE_PARM(write_threshold_kbs, "i"); -MODULE_PARM(max_buffers, "i"); +MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 30)"); + MODULE_PARM(max_sg_segs, "i"); +MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)"); #else static struct osst_dev_parm { char *name; int *val; } parms[] __initdata = { - { "buffer_kbs", &buffer_kbs }, + { "max_dev", &max_dev }, { "write_threshold_kbs", &write_threshold_kbs }, - { "max_buffers", &max_buffers }, { "max_sg_segs", &max_sg_segs } - }; +}; #endif /* Some default definitions have been moved to osst_options.h */ @@ -116,34 +117,41 @@ static int debugging = 1; // #define OSST_INJECT_ERRORS 1 #endif -#define MAX_RETRIES 0 +#define MAX_RETRIES 2 +#define MAX_READ_RETRIES 0 #define MAX_WRITE_RETRIES 0 -#define MAX_READY_RETRIES 5 +#define MAX_READY_RETRIES 0 #define NO_TAPE NOT_READY +#define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1) +#define OSST_WAIT_WRITE_COMPLETE (HZ / 12) +#define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2) + #define OSST_TIMEOUT (200 * HZ) #define OSST_LONG_TIMEOUT (1800 * HZ) -#define TAPE_NR(x) (minor(x) & ~(128 | ST_MODE_MASK)) +#define TAPE_NR(x) (minor(x) & ~(-1 << ST_MODE_SHIFT)) #define TAPE_MODE(x) ((minor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT) +#define TAPE_REWIND(x) ((minor(x) & 0x80) == 0) +#define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1)) /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower 24 bits) */ #define SET_DENS_AND_BLK 0x10001 -static int osst_nbr_buffers; static int osst_buffer_size = OSST_BUFFER_SIZE; static int osst_write_threshold = OSST_WRITE_THRESHOLD; -static int osst_max_buffers = OSST_MAX_BUFFERS; static int osst_max_sg_segs = OSST_MAX_SG; +static int osst_max_dev = OSST_MAX_TAPES; +static int osst_nr_dev; static OS_Scsi_Tape **os_scsi_tapes = NULL; -static OSST_buffer **osst_buffers = NULL; +static rwlock_t os_scsi_tapes_lock = RW_LOCK_UNLOCKED; static int modes_defined = FALSE; -static OSST_buffer *new_tape_buffer(int, int); -static int enlarge_buffer(OSST_buffer *, int, int); +static OSST_buffer *new_tape_buffer(int, int, int); +static int enlarge_buffer(OSST_buffer *, int); static void normalize_buffer(OSST_buffer *); static int append_to_buffer(const char *, OSST_buffer *, int); static int from_buffer(OSST_buffer *, char *, int); @@ -151,22 +159,20 @@ static int osst_zero_buffer_tail(OSST_buffer *); static int osst_copy_to_buffer(OSST_buffer *, unsigned char *); static int osst_copy_from_buffer(OSST_buffer *, unsigned char *); -static int osst_init(void); static int osst_attach(Scsi_Device *); static void osst_detach(Scsi_Device *); -static int osst_nr_dev; -static int osst_dev_max; - struct Scsi_Device_Template osst_template = { - .module = THIS_MODULE, - .list = LIST_HEAD_INIT(osst_template.list), - .name = "OnStream tape", - .tag = "osst", - .scsi_type = TYPE_TAPE, - .attach = osst_attach, - .detach = osst_detach + .module = THIS_MODULE, + .list = LIST_HEAD_INIT(osst_template.list), + .name = "OnStream Tape", + .scsi_type = TYPE_TAPE, + .attach = osst_attach, + .detach = osst_detach, + .scsi_driverfs_driver = { + .name = "osst", + }, }; static int osst_int_ioctl(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, unsigned int cmd_in,unsigned long arg); @@ -181,9 +187,8 @@ static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, static inline char *tape_name(OS_Scsi_Tape *tape) { - return tape->disk->disk_name; + return tape->drive->disk_name; } - /* Routines that handle the interaction with mid-layer SCSI routines */ @@ -201,13 +206,12 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) sense[0] = 0; /* We don't have sense data if this byte is zero */ return 0; } - if (driver_byte(result) & DRIVER_SENSE) + if ((driver_byte(result) & DRIVER_MASK) == DRIVER_SENSE) scode = sense[2] & 0x0f; else { sense[0] = 0; /* We don't have sense data if this byte is zero */ scode = 0; } - #if DEBUG if (debugging) { printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n", @@ -215,10 +219,12 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2], SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5], SRpnt->sr_bufflen); + if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n", + name, scode, sense[12], sense[13]); if (driver_byte(result) & DRIVER_SENSE) print_req_sense("osst", SRpnt); } - else +// else #endif if (!(driver_byte(result) & DRIVER_SENSE) || ((sense[0] & 0x70) == 0x70 && @@ -249,6 +255,8 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) } } } + STp->pos_unknown |= STp->device->was_reset; + if ((sense[0] & 0x70) == 0x70 && scode == RECOVERED_ERROR) { STp->recover_count++; @@ -275,22 +283,21 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) /* Wakeup from interrupt */ static void osst_sleep_done (Scsi_Cmnd * SCpnt) { - OS_Scsi_Tape * STp = container_of(SCpnt->request->rq_disk->private_data, - OS_Scsi_Tape, driver); + OS_Scsi_Tape * STp = container_of(SCpnt->request->rq_disk->private_data, OS_Scsi_Tape, driver); if ((STp->buffer)->writing && (SCpnt->sense_buffer[0] & 0x70) == 0x70 && (SCpnt->sense_buffer[2] & 0x40)) { /* EOM at write-behind, has all been written? */ if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW) - (STp->buffer)->midlevel_result = SCpnt->result; /* Error */ + STp->buffer->midlevel_result = SCpnt->result; /* Error */ else - (STp->buffer)->midlevel_result = INT_MAX; /* OK */ + STp->buffer->midlevel_result = INT_MAX; /* OK */ } else - (STp->buffer)->midlevel_result = SCpnt->result; + STp->buffer->midlevel_result = SCpnt->result; SCpnt->request->rq_status = RQ_SCSI_DONE; - (STp->buffer)->last_SRpnt = SCpnt->sc_request; + STp->buffer->last_SRpnt = SCpnt->sc_request; #if DEBUG STp->write_pending = 0; @@ -312,7 +319,7 @@ static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp, #endif if (SRpnt == NULL) { if ((SRpnt = scsi_allocate_request(STp->device)) == NULL) { - printk(KERN_ERR "%s:E: Can't get SCSI request->\n", tape_name(STp)); + printk(KERN_ERR "%s:E: Can't get SCSI request.\n", tape_name(STp)); if (signal_pending(current)) (STp->buffer)->syscall_result = (-EINTR); else @@ -335,7 +342,7 @@ static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp, SRpnt->sr_cmd_len = 0; SRpnt->sr_request->waiting = &(STp->wait); SRpnt->sr_request->rq_status = RQ_SCSI_BUSY; - SRpnt->sr_request->rq_disk = STp->disk; + SRpnt->sr_request->rq_disk = STp->drive; scsi_do_req(SRpnt, (void *)cmd, bp, bytes, osst_sleep_done, timeout, retries); @@ -387,7 +394,7 @@ static void osst_write_behind_check(OS_Scsi_Tape *STp) scsi_release_request((STp->buffer)->last_SRpnt); if (STbuffer->writing < STbuffer->buffer_bytes) - printk(KERN_WARNING "osst:A: write_behind_check: something left in buffer!\n"); + printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n"); STbuffer->buffer_bytes -= STbuffer->writing; STbuffer->writing = 0; @@ -537,7 +544,7 @@ static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet STp->first_frame_position); goto err_out; } - STp->frame_in_buffer = 1; +// STp->frame_in_buffer = 1; if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) { if (!quiet) @@ -565,12 +572,14 @@ static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet } if (aux->frame_type == OS_FRAME_TYPE_EOD) { STps->eof = ST_EOD_1; + STp->frame_in_buffer = 1; } if (aux->frame_type == OS_FRAME_TYPE_DATA) { blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt); blk_sz = ntohl(aux->dat.dat_list[0].blk_sz); STp->buffer->buffer_bytes = blk_cnt * blk_sz; STp->buffer->read_pointer = 0; + STp->frame_in_buffer = 1; /* See what block size was used to write file */ if (STp->block_size != blk_sz && blk_sz > 0) { @@ -597,18 +606,23 @@ err_out: /* * Wait for the unit to become Ready */ -static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout) +static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout, int initial_delay) { unsigned char cmd[MAX_COMMAND_SIZE]; Scsi_Request * SRpnt; long startwait = jiffies; #if DEBUG - int dbg = debugging; - char *name = tape_name(STp); + int dbg = debugging; + char * name = tape_name(STp); printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name); #endif + if (initial_delay > 0) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(initial_delay); + } + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; @@ -720,10 +734,10 @@ static int osst_position_tape_and_confirm(OS_Scsi_Tape * STp, Scsi_Request ** aS { int retval; - osst_wait_ready(STp, aSRpnt, 15 * 60); /* TODO - can this catch a write error? */ + osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */ retval = osst_set_frame_position(STp, aSRpnt, frame, 0); if (retval) return (retval); - osst_wait_ready(STp, aSRpnt, 15 * 60); + osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE); return (osst_get_frame_position(STp, aSRpnt)); } @@ -736,6 +750,7 @@ static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) Scsi_Request * SRpnt; int result = 0; + int delay = OSST_WAIT_LONG_WRITE_COMPLETE; #if DEBUG char *name = tape_name(STp); @@ -749,12 +764,20 @@ static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_WRITE_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); - - if ((STp->buffer)->syscall_result) - result = osst_write_error_recovery(STp, aSRpnt, 0); - - result |= osst_wait_ready(STp, aSRpnt, 5 * 60); +//printk(OSST_DEB_MSG "%s:X: Write filemark returned %x:%02x:%02x:%02x\n",dev,STp->buffer->syscall_result,SRpnt->sr_sense_buffer[2] & 0x0f,SRpnt->sr_sense_buffer[12],SRpnt->sr_sense_buffer[13]); + if (STp->buffer->syscall_result) { + if ((SRpnt->sr_sense_buffer[2] & 0x0f) == 2 && SRpnt->sr_sense_buffer[12] == 4) { + if (SRpnt->sr_sense_buffer[13] == 8) { +//printk(OSST_DEB_MSG "%s:X: Long initial delay\n", dev); + delay = OSST_WAIT_LONG_WRITE_COMPLETE; + } + } else + result = osst_write_error_recovery(STp, aSRpnt, 0); + } +//printk(OSST_DEB_MSG "%s:X: Entering wait ready (%d)\n",dev,delay); + result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay); STp->ps[STp->partition].rw = OS_WRITING_COMPLETE; + return (result); } @@ -845,7 +868,7 @@ static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeo printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name); #endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ, - STp->timeout, MAX_RETRIES, TRUE); + STp->timeout, MAX_READ_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -901,7 +924,8 @@ static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) #endif if (STps->rw != ST_READING) { /* Initialize read operation */ - if (STps->rw == ST_WRITING) { + if (STps->rw == ST_WRITING || STp->dirty) { + STp->write_type = OS_WRITE_DATA; osst_flush_write_buffer(STp, aSRpnt); osst_flush_drive_buffer(STp, aSRpnt); } @@ -919,7 +943,7 @@ static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) #if DEBUG printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name); #endif - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READ_RETRIES, TRUE); *aSRpnt = SRpnt; retval = STp->buffer->syscall_result; } @@ -938,6 +962,15 @@ static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, in position; /* + * If we want just any frame (-1) and there is a frame in the buffer, return it + */ + if (frame_seq_number == -1 && STp->frame_in_buffer) { +#if DEBUG + printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number); +#endif + return (STps->eof); + } + /* * Search and wait for the next logical tape frame */ while (1) { @@ -1090,6 +1123,7 @@ static int osst_seek_logical_blk(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1; move /= (OS_DATA_SIZE / STp->block_size); } + if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1; #if DEBUG printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n", @@ -1287,7 +1321,7 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** cmd[8] = 32768 & 0xff; SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ, - STp->timeout, MAX_RETRIES, TRUE); + STp->timeout, MAX_READ_RETRIES, TRUE); if ((STp->buffer)->syscall_result || !SRpnt) { printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name); @@ -1327,7 +1361,7 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** name, new_frame+i, frame_seq_number+i); #endif osst_set_frame_position(STp, aSRpnt, new_frame + i, 0); - osst_wait_ready(STp, aSRpnt, 60); + osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE); osst_get_frame_position(STp, aSRpnt); SRpnt = * aSRpnt; @@ -1395,6 +1429,7 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 && (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) { /* in the process of becoming ready */ + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); continue; } @@ -1467,6 +1502,8 @@ static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, osst_set_frame_position(STp, aSRpnt, frame + skip, 1); flag = 0; attempts--; + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); } if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */ #if DEBUG @@ -1909,6 +1946,7 @@ static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Reque if (mt_op == MTFSF) { STp->frame_seq_number++; STp->frame_in_buffer = 0; + STp->buffer->read_pointer = 0; STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); } return 0; @@ -2009,7 +2047,7 @@ static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int whe #if DEBUG printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where); #endif - osst_wait_ready(STp, aSRpnt, 60 * 5); + osst_wait_ready(STp, aSRpnt, 60 * 5, 0); osst_set_frame_position(STp, aSRpnt, where, 0); STp->write_type = OS_WRITE_FILLER; while (count--) { @@ -2035,7 +2073,7 @@ static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int w #if DEBUG printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where); #endif - osst_wait_ready(STp, aSRpnt, 60 * 5); + osst_wait_ready(STp, aSRpnt, 60 * 5, 0); osst_set_frame_position(STp, aSRpnt, where, 0); STp->write_type = OS_WRITE_HEADER; while (count--) { @@ -2669,7 +2707,7 @@ static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, SCSI_DATA_READ, - STp->timeout, MAX_READY_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); if (!SRpnt) { STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; return (-EBUSY); @@ -2690,7 +2728,7 @@ static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) scmd[0] = READ_POSITION; STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, SCSI_DATA_READ, - STp->timeout, MAX_READY_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); if (!STp->buffer->syscall_result) memcpy (SRpnt->sr_sense_buffer, mysense, 16); } @@ -2762,7 +2800,7 @@ static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, in scmd[9] = 0x80; SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, SCSI_DATA_NONE, STp->long_timeout, - MAX_READY_RETRIES, TRUE); + MAX_RETRIES, TRUE); if (!SRpnt) return (-EBUSY); *aSRpnt = SRpnt; @@ -2775,7 +2813,7 @@ static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, in result = (-EIO); } if (pp != ppos) - osst_wait_ready(STp, aSRpnt, 5 * 60); + osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE); } while ((pp != ppos) && (pp = ppos)); STp->first_frame_position = STp->last_frame_position = ppos; STps->eof = ST_NOEOF; @@ -2932,16 +2970,17 @@ static int osst_flush_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int see * If there was a bus reset, block further access * to this device. */ - if( STp->device->was_reset ) + if( STp->pos_unknown) return (-EIO); if (STp->ready != ST_READY) return 0; STps = &(STp->ps[STp->partition]); - if (STps->rw == ST_WRITING) /* Writing */ + if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */ + STp->write_type = OS_WRITE_DATA; return osst_flush_write_buffer(STp, aSRpnt); - + } if (STp->block_size == 0) return 0; @@ -3063,6 +3102,43 @@ static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sync return 0; } +/* Lock or unlock the drive door. Don't use when Scsi_Request allocated. */ +static int do_door_lock(OS_Scsi_Tape * STp, int do_lock) +{ + int retval, cmd; + + cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK; +#if DEBUG + printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl"); +#endif + retval = scsi_ioctl(STp->device, cmd, NULL); + if (!retval) { + STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED; + } + else { + STp->door_locked = ST_LOCK_FAILS; + } + return retval; +} + +/* Set the internal state after reset */ +static void reset_state(OS_Scsi_Tape *STp) +{ + int i; + ST_partstat *STps; + + STp->pos_unknown = 0; + for (i = 0; i < ST_NBR_PARTITIONS; i++) { + STps = &(STp->ps[i]); + STps->rw = ST_IDLE; + STps->eof = ST_NOEOF; + STps->at_sm = 0; + STps->last_block_valid = FALSE; + STps->drv_block = -1; + STps->drv_file = -1; + } +} + /* Entry points to osst */ @@ -3120,7 +3196,7 @@ static ssize_t osst_write(struct file * filp, const char * buf, size_t count, lo * If there was a bus reset, block further access * to this device. */ - if (STp->device->was_reset) { + if (STp->pos_unknown) { retval = (-EIO); goto out; } @@ -3154,20 +3230,22 @@ static ssize_t osst_write(struct file * filp, const char * buf, size_t count, lo goto out; } - STps = &(STp->ps[STp->partition]); - - if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && - !osst_int_ioctl(STp, &SRpnt, MTLOCK, 0)) + if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1)) STp->door_locked = ST_LOCKED_AUTO; + STps = &(STp->ps[STp->partition]); if (STps->rw == ST_READING) { +#if DEBUG + printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name, + STps->drv_file, STps->drv_block); +#endif retval = osst_flush_buffer(STp, &SRpnt, 0); if (retval) goto out; STps->rw = ST_IDLE; } - else if (STps->rw != ST_WRITING) { + if (STps->rw != ST_WRITING) { /* Are we totally rewriting this tape? */ if (!STp->header_ok || (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) || @@ -3518,9 +3596,19 @@ static ssize_t osst_read(struct file * filp, char * buf, size_t count, loff_t *p printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name, STps->eof, (STp->buffer)->buffer_bytes, count - total); #endif + /* force multiple of block size, note block_size may have been adjusted */ transfer = (((STp->buffer)->buffer_bytes < count - total ? (STp->buffer)->buffer_bytes : count - total)/ - STp->block_size) * STp->block_size; /* force multiple of block size */ + STp->block_size) * STp->block_size; + + if (transfer == 0) { + printk(KERN_WARNING + "%s:W: Nothing can be transfered, requested %d, tape block size (%d%c).\n", + name, count, STp->block_size < 1024? + STp->block_size:STp->block_size/1024, + STp->block_size<1024?'b':'k'); + break; + } i = from_buffer(STp->buffer, buf, transfer); if (i) { retval = i; @@ -3870,9 +3958,10 @@ static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned i } break; case MTWEOF: - if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) + if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) { + STp->write_type = OS_WRITE_DATA; ioctl_result = osst_flush_write_buffer(STp, &SRpnt); - else + } else ioctl_result = 0; #if DEBUG if (debugging) @@ -3993,26 +4082,6 @@ static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned i fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ; break; - case MTLOCK: - chg_eof = FALSE; - cmd[0] = ALLOW_MEDIUM_REMOVAL; - cmd[4] = SCSI_REMOVAL_PREVENT; -#if DEBUG - if (debugging) - printk(OSST_DEB_MSG "%s:D: Locking drive door.\n", name); -#endif - break; - - case MTUNLOCK: - chg_eof = FALSE; - cmd[0] = ALLOW_MEDIUM_REMOVAL; - cmd[4] = SCSI_REMOVAL_ALLOW; -#if DEBUG - if (debugging) - printk(OSST_DEB_MSG "%s:D: Unlocking drive door.\n", name); -#endif - break; - case MTSETBLK: /* Set block length */ case MTSETDENSITY: /* Set tape density */ case MTSETDRVBUFFER: /* Set drive buffering */ @@ -4070,13 +4139,10 @@ os_bypass: STps->drv_file = fileno; STps->at_sm = at_sm; - if (cmd_in == MTLOCK) - STp->door_locked = ST_LOCKED_EXPLICIT; - else if (cmd_in == MTUNLOCK) - STp->door_locked = ST_UNLOCKED; - if (cmd_in == MTEOM) STps->eof = ST_EOD; + else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) + ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num - 1); else if (cmd_in == MTFSF) STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM; else if (chg_eof) @@ -4085,7 +4151,6 @@ os_bypass: if (cmd_in == MTOFFL || cmd_in == MTUNLOAD) STp->rew_at_close = 0; else if (cmd_in == MTLOAD) { -/* STp->rew_at_close = (minor(inode->i_rdev) & 0x80) == 0; FIXME */ for (i=0; i < ST_NBR_PARTITIONS; i++) { STp->ps[i].rw = ST_IDLE; STp->ps[i].last_block_valid = FALSE;/* FIXME - where else is this field maintained? */ @@ -4130,11 +4195,8 @@ os_bypass: if ((SRpnt->sr_sense_buffer[2] & 0x0f) == BLANK_CHECK) STps->eof = ST_EOD; - if (cmd_in == MTLOCK) - STp->door_locked = ST_LOCK_FAILS; - if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60)) - ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60); + ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE); } *aSRpnt = SRpnt; @@ -4146,38 +4208,48 @@ os_bypass: static int os_scsi_tape_open(struct inode * inode, struct file * filp) { unsigned short flags; - int i, b_size, need_dma_buffer, new_session = FALSE, retval = 0; + int i, b_size, new_session = FALSE, retval = 0; unsigned char cmd[MAX_COMMAND_SIZE]; Scsi_Request * SRpnt; OS_Scsi_Tape * STp; ST_mode * STm; ST_partstat * STps; - int dev = TAPE_NR(inode->i_rdev); char *name; + int dev = TAPE_NR(inode->i_rdev); int mode = TAPE_MODE(inode->i_rdev); - if (dev >= osst_dev_max || (STp = os_scsi_tapes[dev]) == NULL || !STp->device) + write_lock(&os_scsi_tapes_lock); + if (dev >= osst_max_dev || os_scsi_tapes == NULL || + (STp = os_scsi_tapes[dev]) == NULL || !STp->device) { + write_unlock(&os_scsi_tapes_lock); return (-ENXIO); + } - filp->private_data = STp; name = tape_name(STp); - if( !scsi_block_when_processing_errors(STp->device) ) { - return -ENXIO; - } - if (STp->in_use) { + write_unlock(&os_scsi_tapes_lock); #if DEBUG printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name); #endif return (-EBUSY); } - - if (!try_module_get(STp->device->host->hostt->module)) + + if (!scsi_device_get(STp->device)) { + write_unlock(&os_scsi_tapes_lock); +#if DEBUG + printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name); +#endif return (-ENXIO); - STp->device->access_count++; - STp->in_use = 1; - STp->rew_at_close = (minor(inode->i_rdev) & 0x80) == 0; + } + filp->private_data = STp; + STp->in_use = 1; + write_unlock(&os_scsi_tapes_lock); + STp->rew_at_close = TAPE_REWIND(inode->i_rdev); + + if( !scsi_block_when_processing_errors(STp->device) ) { + return -ENXIO; + } if (mode != STp->current_mode) { #if DEBUG @@ -4193,10 +4265,10 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) flags = filp->f_flags; STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY); - STp->raw = (minor(inode->i_rdev) & 0x40) != 0; + STp->raw = TAPE_IS_RAW(inode->i_rdev); if (STp->raw) STp->header_ok = 0; - +#if 0 /* Allocate a buffer for this user */ need_dma_buffer = STp->restr_dma; for (i=0; i < osst_nbr_buffers; i++) @@ -4213,9 +4285,16 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) } else STp->buffer = osst_buffers[i]; - (STp->buffer)->in_use = 1; +#endif /* now pre_allocated */ + /* Allocate data segments for this device's tape buffer */ + if (!enlarge_buffer(STp->buffer, STp->restr_dma)) { + printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name); + retval = (-EOVERFLOW); + goto err_out; + } (STp->buffer)->writing = 0; (STp->buffer)->syscall_result = 0; +#if 0 (STp->buffer)->use_sg = STp->device->host->sg_tablesize; /* Compute the usable buffer size for this SCSI adapter */ @@ -4226,7 +4305,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) i < (STp->buffer)->sg_segs; i++) (STp->buffer)->buffer_size += (STp->buffer)->sg[i].length; } - +#endif STp->dirty = 0; for (i=0; i < ST_NBR_PARTITIONS; i++) { STps = &(STp->ps[i]); @@ -4251,6 +4330,10 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) #if DEBUG printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sr_sense_buffer[13]); #endif + if (filp->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + goto err_out; + } if (SRpnt->sr_sense_buffer[13] == 2) { /* initialize command required (LOAD) */ memset (cmd, 0, MAX_COMMAND_SIZE); cmd[0] = START_STOP; @@ -4259,7 +4342,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); } - osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60); + osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0); } if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 && (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */ @@ -4280,7 +4363,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) break; } - STp->device->was_reset = 0; + STp->pos_unknown = 0; STp->partition = STp->new_partition = 0; if (STp->can_partitions) STp->nbr_partitions = 1; /* This guess will be updated later if necessary */ @@ -4388,7 +4471,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) break; if ((SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { - STp->device->was_reset = 0; + STp->pos_unknown = 0; STp->partition = STp->new_partition = 0; if (STp->can_partitions) STp->nbr_partitions = 1; /* This guess will be updated later if necessary */ @@ -4406,8 +4489,8 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) } } - if (osst_wait_ready(STp, &SRpnt, 15 * 60)) /* FIXME - not allowed with NOBLOCK */ - printk(KERN_INFO "%s:I: Device did not become Ready in open\n",name); + if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */ + printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name); if ((STp->buffer)->syscall_result != 0) { if ((STp->device)->scsi_level >= SCSI_2 && @@ -4430,19 +4513,9 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) osst_configure_onstream(STp, &SRpnt); -/* STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0; FIXME */ - - if (OS_FRAME_SIZE > (STp->buffer)->buffer_size && - !enlarge_buffer(STp->buffer, OS_FRAME_SIZE, STp->restr_dma)) { - printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, - OS_FRAME_SIZE); - retval = (-EIO); - goto err_out; - } - - if ((STp->buffer)->buffer_size >= OS_FRAME_SIZE) { + if (STp->buffer->buffer_size >= OS_FRAME_SIZE) { for (i = 0, b_size = 0; - i < STp->buffer->sg_segs && (b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE; + (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); b_size += STp->buffer->sg[i++].length); STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size); #if DEBUG @@ -4451,8 +4524,12 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name, STp->buffer->aux, i, page_address(STp->buffer->sg[i].page)); #endif - } else + } else { STp->buffer->aux = NULL; /* this had better never happen! */ + printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE); + retval = (-EIO); + goto err_out; + } STp->block_size = STp->raw ? OS_FRAME_SIZE : ( (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE); @@ -4509,15 +4586,10 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) err_out: if (SRpnt != NULL) scsi_release_request(SRpnt); - if (STp->buffer != NULL) { - STp->buffer->in_use = 0; - STp->buffer = NULL; - } - STp->in_use = 0; + normalize_buffer(STp->buffer); STp->header_ok = 0; - STp->device->access_count--; - - module_put(STp->device->host->hostt->module); + STp->in_use = 0; + scsi_device_put(STp->device); return retval; } @@ -4536,12 +4608,13 @@ static int os_scsi_tape_flush(struct file * filp) if (file_count(filp) > 1) return 0; - if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) { + if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) { + STp->write_type = OS_WRITE_DATA; result = osst_flush_write_buffer(STp, &SRpnt); if (result != 0 && result != (-ENOSPC)) goto out; } - if ( STps->rw >= ST_WRITING && !(STp->device)->was_reset) { + if ( STps->rw >= ST_WRITING && !STp->pos_unknown) { #if DEBUG if (debugging) { @@ -4632,20 +4705,20 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp) OS_Scsi_Tape * STp = filp->private_data; Scsi_Request * SRpnt = NULL; - if (STp->door_locked == ST_LOCKED_AUTO) - osst_int_ioctl(STp, &SRpnt, MTUNLOCK, 0); if (SRpnt) scsi_release_request(SRpnt); - if (STp->buffer != NULL) - STp->buffer->in_use = 0; + if (STp->door_locked == ST_LOCKED_AUTO) + do_door_lock(STp, 0); if (STp->raw) STp->header_ok = 0; - + + normalize_buffer(STp->buffer); + write_lock(&os_scsi_tapes_lock); STp->in_use = 0; - STp->device->access_count--; + write_unlock(&os_scsi_tapes_lock); - module_put(STp->device->host->hostt->module); + scsi_device_put(STp->device); return result; } @@ -4718,7 +4791,7 @@ static int osst_ioctl(struct inode * inode,struct file * file, goto out; } - if (!(STp->device)->was_reset) { + if (!STp->pos_unknown) { if (STps->eof == ST_FM_HIT) { if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) { @@ -4764,15 +4837,9 @@ static int osst_ioctl(struct inode * inode,struct file * file, retval = (-EIO); goto out; } + reset_state(STp); + /* remove this when the midlevel properly clears was_reset */ STp->device->was_reset = 0; - if (STp->door_locked != ST_UNLOCKED && - STp->door_locked != ST_LOCK_FAILS) { - if (osst_int_ioctl(STp, &SRpnt, MTLOCK, 0)) { - printk(KERN_NOTICE "%s:I: Could not relock door after bus reset.\n", - name); - STp->door_locked = ST_UNLOCKED; - } - } } if (mtc.mt_op != MTNOP && mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM && @@ -4781,7 +4848,7 @@ static int osst_ioctl(struct inode * inode,struct file * file, STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */ if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED) - osst_int_ioctl(STp, &SRpnt, MTUNLOCK, 0); /* Ignore result! */ + do_door_lock(STp, 0); /* Ignore result! */ if (mtc.mt_op == MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) != 0) { @@ -4837,7 +4904,12 @@ static int osst_ioctl(struct inode * inode,struct file * file, retval = i; goto out; } - + + if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) { + retval = do_door_lock(STp, (mtc.mt_op == MTLOCK)); + goto out; + } + /* if (STp->can_partitions && STp->ready == ST_READY && (i = update_partition(inode)) < 0) {retval=i;goto out;}*/ @@ -4967,15 +5039,12 @@ out: /* Memory handling routines */ -/* Try to allocate a new tape buffer */ -static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma ) +/* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */ +static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg ) { - int i, priority, b_size, order, got = 0, segs = 0; + int i, priority; OSST_buffer *tb; - if (osst_nbr_buffers >= osst_dev_max) - return NULL; /* Should never happen */ - if (from_initialization) priority = GFP_ATOMIC; else @@ -4983,144 +5052,94 @@ static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma ) i = sizeof(OSST_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); tb = (OSST_buffer *)kmalloc(i, priority); - if (tb) { -// tb->this_size = i; - if (need_dma) - priority |= GFP_DMA; - - /* Try to allocate the first segment up to OSST_FIRST_ORDER and the - others big enough to reach the goal */ - for (b_size = PAGE_SIZE, order = 0; - b_size < osst_buffer_size && order < OSST_FIRST_ORDER; - b_size *= 2, order++ ); - - for ( ; b_size >= PAGE_SIZE; order--, b_size /= 2) { - tb->sg[0].page = alloc_pages(priority, order); - tb->sg[0].offset = 0; - if (tb->sg[0].page != NULL) { - tb->sg[0].length = b_size; - break; - } - } - if (tb->sg[segs].page == NULL) { - kfree(tb); - tb = NULL; - } - else { /* Got something, continue */ - - for (b_size = PAGE_SIZE, order = 0; - osst_buffer_size > tb->sg[0].length + (OSST_FIRST_SG - 1) * b_size; - b_size *= 2, order++ ); - - for (segs=1, got=tb->sg[0].length; - got < osst_buffer_size && segs < OSST_FIRST_SG; ) { - tb->sg[segs].page = alloc_pages(priority, order); - tb->sg[segs].offset = 0; - if (tb->sg[segs].page == NULL) { - if (osst_buffer_size - got <= - (OSST_FIRST_SG - segs) * b_size / 2) { - b_size /= 2; /* Large enough for the rest of the buffers */ - order--; - continue; - } - tb->sg_segs = segs; - tb->orig_sg_segs = 0; -#if DEBUG - tb->buffer_size = got; -#endif - normalize_buffer(tb); - kfree(tb); - tb = NULL; - break; - } - tb->sg[segs].page = NULL; - tb->sg[segs].length = b_size; - got += b_size; - segs++; - } - } - } if (!tb) { - printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer (nbr %d).\n", - osst_nbr_buffers); + printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n"); return NULL; } - tb->sg_segs = tb->orig_sg_segs = segs; - tb->b_data = page_address(tb->sg[0].page); - + memset(tb, 0, i); + tb->sg_segs = tb->orig_sg_segs = 0; + tb->use_sg = max_sg; + tb->in_use = TRUE; + tb->dma = need_dma; + tb->buffer_size = 0; #if DEBUG - if (debugging) { + if (debugging) printk(OSST_DEB_MSG - "osst :D: Allocated tape buffer %d (%d bytes, %d segments, dma: %d, a: %p).\n", - osst_nbr_buffers, got, tb->sg_segs, need_dma, tb->b_data); - printk(OSST_DEB_MSG - "osst :D: segment sizes: first %d, last %d bytes.\n", - tb->sg[0].length, tb->sg[segs-1].length); - } + "osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n", + i, max_sg, need_dma); #endif - tb->in_use = 0; - tb->dma = need_dma; - tb->buffer_size = got; - tb->writing = 0; - osst_buffers[osst_nbr_buffers++] = tb; - return tb; } - -/* Try to allocate a temporary enlarged tape buffer */ -static int enlarge_buffer(OSST_buffer *STbuffer, int new_size, int need_dma) +/* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */ +static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma) { int segs, nbr, max_segs, b_size, priority, order, got; - normalize_buffer(STbuffer); + if (STbuffer->buffer_size >= OS_FRAME_SIZE) + return TRUE; - max_segs = STbuffer->use_sg; - if (max_segs > osst_max_sg_segs) - max_segs = osst_max_sg_segs; - nbr = max_segs - STbuffer->sg_segs; - if (nbr <= 0) + if (STbuffer->sg_segs) { + printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n"); + normalize_buffer(STbuffer); + } + /* See how many segments we can use -- need at least two */ + nbr = max_segs = STbuffer->use_sg; + if (nbr <= 2) return FALSE; priority = GFP_KERNEL; if (need_dma) priority |= GFP_DMA; - for (b_size = PAGE_SIZE, order = 0; - b_size * nbr < new_size - STbuffer->buffer_size; - b_size *= 2, order++); - for (segs=STbuffer->sg_segs, got=STbuffer->buffer_size; - segs < max_segs && got < new_size; ) { - STbuffer->sg[segs].page = alloc_pages(priority, order); + /* Try to allocate the first segment up to OS_DATA_SIZE and the others + big enough to reach the goal (code assumes no segments in place) */ + for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) { + STbuffer->sg[0].page = alloc_pages(priority, order); + STbuffer->sg[0].offset = 0; + if (STbuffer->sg[0].page != NULL) { + STbuffer->sg[0].length = b_size; + STbuffer->b_data = page_address(STbuffer->sg[0].page); + break; + } + } + if (STbuffer->sg[0].page == NULL) { + printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n"); + return FALSE; + } + /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */ + for (segs=STbuffer->sg_segs=1, got=b_size; + segs < max_segs && got < OS_FRAME_SIZE; ) { + STbuffer->sg[segs].page = + (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? + kmalloc(OS_FRAME_SIZE - got, priority): + alloc_pages(priority, order); STbuffer->sg[segs].offset = 0; if (STbuffer->sg[segs].page == NULL) { - if (new_size - got <= (max_segs - segs) * b_size / 2) { + if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) { b_size /= 2; /* Large enough for the rest of the buffers */ order--; continue; } printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n", - new_size); + OS_FRAME_SIZE); #if DEBUG STbuffer->buffer_size = got; #endif normalize_buffer(STbuffer); return FALSE; } - STbuffer->sg[segs].page = NULL; - STbuffer->sg[segs].length = b_size; - STbuffer->sg_segs += 1; - got += b_size; + STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size; + got += STbuffer->sg[segs].length; STbuffer->buffer_size = got; - segs++; + STbuffer->sg_segs = ++segs; } #if DEBUG if (debugging) { - for (nbr=0; osst_buffers[nbr] != STbuffer && nbr < osst_nbr_buffers; nbr++); - printk(OSST_DEB_MSG - "osst :D: Expanded tape buffer %d (%d bytes, %d->%d segments, dma: %d, a: %p).\n", - nbr, got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data); - printk(OSST_DEB_MSG + printk(OSST_DEB_MSG + "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n", + got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data); + printk(OSST_DEB_MSG "osst :D: segment sizes: first %d, last %d bytes.\n", STbuffer->sg[0].length, STbuffer->sg[segs-1].length); } @@ -5130,12 +5149,12 @@ static int enlarge_buffer(OSST_buffer *STbuffer, int new_size, int need_dma) } -/* Release the extra buffer */ +/* Release the segments */ static void normalize_buffer(OSST_buffer *STbuffer) { int i, order, b_size; - for (i=STbuffer->orig_sg_segs; i < STbuffer->sg_segs; i++) { + for (i=0; i < STbuffer->sg_segs; i++) { for (b_size = PAGE_SIZE, order = 0; b_size < STbuffer->sg[i].length; @@ -5149,7 +5168,7 @@ static void normalize_buffer(OSST_buffer *STbuffer) printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n", STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs); #endif - STbuffer->sg_segs = STbuffer->orig_sg_segs; + STbuffer->sg_segs = STbuffer->orig_sg_segs = 0; } @@ -5293,19 +5312,17 @@ static int osst_copy_from_buffer(OSST_buffer *st_bp, unsigned char *ptr) static void validate_options (void) { - if (buffer_kbs > 0) - osst_buffer_size = buffer_kbs * ST_KILOBYTE; + if (max_dev > 0) + osst_max_dev = max_dev; if (write_threshold_kbs > 0) osst_write_threshold = write_threshold_kbs * ST_KILOBYTE; if (osst_write_threshold > osst_buffer_size) osst_write_threshold = osst_buffer_size; - if (max_buffers > 0) - osst_max_buffers = max_buffers; if (max_sg_segs >= OSST_FIRST_SG) osst_max_sg_segs = max_sg_segs; #if DEBUG - printk(OSST_DEB_MSG "osst :D: bufsize %d, wrt %d, max buffers %d, s/g segs %d.\n", - osst_buffer_size, osst_write_threshold, osst_max_buffers, osst_max_sg_segs); + printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, s/g segs %d.\n", + osst_max_dev, osst_write_threshold, osst_max_sg_segs); //printk(OSST_DEB_MSG "osst :D: sizeof(header) = %d (%s)\n", // sizeof(os_header_t),sizeof(os_header_t)==OS_DATA_SIZE?"ok":"error"); #endif @@ -5313,8 +5330,8 @@ static void validate_options (void) #ifndef MODULE /* Set the boot options. Syntax: osst=xxx,yyy,... - where xxx is buffer size in 1024 byte blocks and yyy is write threshold - in 1024 byte blocks. */ + where xxx is write threshold in 1024 byte blocks, + and yyy is number of s/g segments to use. */ static int __init osst_setup (char *str) { int i, ints[5]; @@ -5352,14 +5369,30 @@ __setup("osst=", osst_setup); #endif +/* Driverfs file support */ +static ssize_t osst_device_kdev_read(struct device *driverfs_dev, char *page, size_t count, loff_t off) +{ + kdev_t kdev; + kdev.value=(int)(long)driverfs_dev->driver_data; + return off ? 0 : sprintf(page, "%x\n",kdev.value); +} +static DEVICE_ATTR(kdev,S_IRUGO,osst_device_kdev_read,NULL); + +static ssize_t osst_device_type_read(struct device *driverfs_dev, char *page, size_t count, loff_t off) +{ + return off ? 0 : sprintf (page, "CHR\n"); +} +static DEVICE_ATTR(type,S_IRUGO,osst_device_type_read,NULL); + static struct file_operations osst_fops = { - .read = osst_read, - .write = osst_write, - .ioctl = osst_ioctl, - .open = os_scsi_tape_open, - .flush = os_scsi_tape_flush, - .release = os_scsi_tape_close, + .owner = THIS_MODULE, + .read = osst_read, + .write = osst_write, + .ioctl = osst_ioctl, + .open = os_scsi_tape_open, + .flush = os_scsi_tape_flush, + .release = os_scsi_tape_close, }; static int osst_supports(Scsi_Device * SDp) @@ -5390,102 +5423,93 @@ static struct osst_support_data support_list[] = { return 0; } +/* + * osst startup / cleanup code + */ + static int osst_attach(Scsi_Device * SDp) { OS_Scsi_Tape * tpnt; ST_mode * STm; ST_partstat * STps; - int i, dev; - struct gendisk *disk; -#ifdef CONFIG_DEVFS_FS - int mode; -#endif + OSST_buffer *buffer; + struct gendisk *drive; + int i, mode, dev_num; if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) - return 1; - - osst_init(); - - disk = alloc_disk(1); - if (!disk) return 1; - if (osst_nr_dev >= osst_dev_max) { - put_disk(disk); - return 1; + if (scsi_slave_attach(SDp)) { + printk(KERN_ERR "osst :E: Failed to attach scsi slave.\n"); + return 1; } - if (scsi_slave_attach(SDp)) + drive = alloc_disk(1); + if (!drive) { + printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n"); return 1; + } + + /* if this is the first attach, build the infrastructure */ + write_lock(&os_scsi_tapes_lock); + if (os_scsi_tapes == NULL) { + os_scsi_tapes = + (OS_Scsi_Tape **)kmalloc(osst_max_dev * sizeof(OS_Scsi_Tape *), + GFP_ATOMIC); + if (os_scsi_tapes == NULL) { + write_unlock(&os_scsi_tapes_lock); + printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n"); + return 1; + } + for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL; + } + if (osst_nr_dev >= osst_max_dev) { + write_unlock(&os_scsi_tapes_lock); + printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev); + put_disk(drive); + return 1; + } + /* find a free minor number */ - for (i=0; os_scsi_tapes[i] && i<osst_dev_max; i++); - if(i >= osst_dev_max) panic ("Scsi_devices corrupt (osst)"); + for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++); + if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)"); + dev_num = i; /* allocate a OS_Scsi_Tape for this device */ tpnt = (OS_Scsi_Tape *)kmalloc(sizeof(OS_Scsi_Tape), GFP_ATOMIC); if (tpnt == NULL) { - printk(KERN_WARNING "osst :W: Can't allocate device descriptor.\n"); - put_disk(disk); - - scsi_slave_detach(SDp); - return 1; + write_unlock(&os_scsi_tapes_lock); + printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n"); + put_disk(drive); + scsi_slave_detach(SDp); + return 1; } memset(tpnt, 0, sizeof(OS_Scsi_Tape)); - os_scsi_tapes[i] = tpnt; - dev = i; - tpnt->capacity = 0xfffff; /* allocate a buffer for this device */ - if (!new_tape_buffer(TRUE, TRUE)) - printk(KERN_ERR "osst :W: Unable to allocate a tape buffer.\n"); - -#ifdef CONFIG_DEVFS_FS - for (mode = 0; mode < ST_NBR_MODES; ++mode) { - char name[8]; - static char *formats[ST_NBR_MODES] ={"", "l", "m", "a"}; - - /* Rewind entry */ - sprintf (name, "mt%s", formats[mode]); -# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tpnt->de_r[mode] = - devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, - MAJOR_NR, i + (mode << 5), - S_IFCHR | S_IRUGO | S_IWUGO, - &osst_fops, NULL); -# else - tpnt->de_r[mode] = - devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT, - MAJOR_NR, i + (mode << 5), - S_IFCHR | S_IRUGO | S_IWUGO, - 0, 0, &osst_fops, NULL); -# endif - /* No-rewind entry */ - sprintf (name, "mt%sn", formats[mode]); -# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - tpnt->de_n[mode] = - devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, - MAJOR_NR, i + (mode << 5) + 128, - S_IFCHR | S_IRUGO | S_IWUGO, - &osst_fops, NULL); -# else - tpnt->de_n[mode] = - devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT, - MAJOR_NR, i + (mode << 5) + 128, - S_IFCHR | S_IRUGO | S_IWUGO, - 0, 0, &osst_fops, NULL); -# endif + i = SDp->host->sg_tablesize; + if (osst_max_sg_segs < i) + i = osst_max_sg_segs; + buffer = new_tape_buffer(TRUE, SDp->host->unchecked_isa_dma, i); + if (buffer == NULL) { + write_unlock(&os_scsi_tapes_lock); + printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n"); + kfree(tpnt); + put_disk(drive); + scsi_slave_detach(SDp); + return 1; } - disk->number = devfs_register_tape(SDp->de); -#endif - + os_scsi_tapes[dev_num] = tpnt; + tpnt->buffer = buffer; tpnt->device = SDp; - disk->private_data = &tpnt->driver; - sprintf(disk->disk_name, "osst%d", i); + drive->private_data = &tpnt->driver; + sprintf(drive->disk_name, "osst%d", dev_num); tpnt->driver = &osst_template; - tpnt->disk = disk; - tpnt->dirty = 0; + tpnt->drive = drive; tpnt->in_use = 0; + tpnt->capacity = 0xfffff; + tpnt->dirty = 0; tpnt->drv_buffer = 1; /* Try buffering if no mode sense */ tpnt->restr_dma = (SDp->host)->unchecked_isa_dma; tpnt->density = 0; @@ -5510,7 +5534,8 @@ static int osst_attach(Scsi_Device * SDp) tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev); tpnt->omit_blklims = 1; - tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp); + tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || + (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp); tpnt->frame_in_buffer = 0; tpnt->header_ok = 0; tpnt->linux_media = 0; @@ -5543,9 +5568,56 @@ static int osst_attach(Scsi_Device * SDp) tpnt->modes[0].defined = TRUE; tpnt->modes[2].defined = TRUE; tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = FALSE; - init_MUTEX(&tpnt->lock); + init_MUTEX(&tpnt->lock); osst_nr_dev++; + write_unlock(&os_scsi_tapes_lock); + + for (mode = 0; mode < ST_NBR_MODES; ++mode) { + char name[8]; + static char *formats[ST_NBR_MODES] ={"", "l", "m", "a"}; + + /* Rewind entry */ + sprintf (name, "ot%s", formats[mode]); + sprintf(tpnt->driverfs_dev_r[mode].bus_id, "%s:%s", + SDp->sdev_driverfs_dev.bus_id, name); + sprintf(tpnt->driverfs_dev_r[mode].name, "%s%s", + SDp->sdev_driverfs_dev.name, name); + tpnt->driverfs_dev_r[mode].parent = &SDp->sdev_driverfs_dev; + tpnt->driverfs_dev_r[mode].bus = SDp->sdev_driverfs_dev.bus; + tpnt->driverfs_dev_r[mode].driver_data = + (void *)(long)__mkdev(MAJOR_NR, dev_num + (mode << 5)); + device_register(&tpnt->driverfs_dev_r[mode]); + device_create_file(&tpnt->driverfs_dev_r[mode], + &dev_attr_type); + device_create_file(&tpnt->driverfs_dev_r[mode], &dev_attr_kdev); + tpnt->de_r[mode] = + devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, + MAJOR_NR, dev_num + (mode << 5), + S_IFCHR | S_IRUGO | S_IWUGO, + &osst_fops, NULL); + /* No-rewind entry */ + sprintf (name, "ot%sn", formats[mode]); + sprintf(tpnt->driverfs_dev_n[mode].bus_id, "%s:%s", + SDp->sdev_driverfs_dev.bus_id, name); + sprintf(tpnt->driverfs_dev_n[mode].name, "%s%s", + SDp->sdev_driverfs_dev.name, name); + tpnt->driverfs_dev_n[mode].parent= &SDp->sdev_driverfs_dev; + tpnt->driverfs_dev_n[mode].bus = SDp->sdev_driverfs_dev.bus; + tpnt->driverfs_dev_n[mode].driver_data = + (void *)(long)__mkdev(MAJOR_NR, dev_num + (mode << 5) + 128); + device_register(&tpnt->driverfs_dev_n[mode]); + device_create_file(&tpnt->driverfs_dev_n[mode], + &dev_attr_type); + device_create_file(&tpnt->driverfs_dev_n[mode], + &dev_attr_kdev); + tpnt->de_n[mode] = + devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, + MAJOR_NR, dev_num + (mode << 5) + 128, + S_IFCHR | S_IRUGO | S_IWUGO, + &osst_fops, NULL); + } + drive->number = devfs_register_tape (SDp->de); printk(KERN_INFO "osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as %s\n", @@ -5554,94 +5626,72 @@ static int osst_attach(Scsi_Device * SDp) return 0; }; -static int osst_registered = 0; - -/* Driver initialization (not __initfunc because may be called later) */ -static int osst_init() -{ - int i; - - if (!osst_registered) { - if (register_chrdev(MAJOR_NR,"osst",&osst_fops)) { - printk(KERN_ERR "osst :W: Unable to get major %d for OnStream tapes\n",MAJOR_NR); - return 1; - } - osst_registered++; - } - - if (os_scsi_tapes) - return 0; - osst_dev_max = OSST_MAX_TAPES; - if (osst_dev_max > 128 / ST_NBR_MODES) - printk(KERN_INFO "osst :I: Only %d tapes accessible.\n", 128 / ST_NBR_MODES); - os_scsi_tapes = kmalloc(osst_dev_max * sizeof(OS_Scsi_Tape *), - GFP_ATOMIC); - if (!os_scsi_tapes) { - printk(KERN_ERR "osst :W: Unable to allocate array for OnStream SCSI tapes.\n"); - unregister_chrdev(MAJOR_NR, "osst"); - return 1; - } - - for (i=0; i < osst_dev_max; ++i) - os_scsi_tapes[i] = NULL; - - /* Allocate the buffer pointers */ - osst_buffers = kmalloc(osst_dev_max * sizeof(OSST_buffer *), - GFP_ATOMIC); - if (!osst_buffers) { - printk(KERN_ERR "osst :W: Unable to allocate tape buffer pointers.\n"); - unregister_chrdev(MAJOR_NR, "osst"); - kfree(os_scsi_tapes); - return 1; - } - osst_nbr_buffers = 0; - - printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid); - -#if DEBUG - printk(OSST_DEB_MSG "osst :D: Buffer size %d bytes, write threshold %d bytes.\n", - osst_buffer_size, osst_write_threshold); -#endif - return 0; -} - - static void osst_detach(Scsi_Device * SDp) { OS_Scsi_Tape * tpnt; - int i; -#ifdef CONFIG_DEVFS_FS - int mode; -#endif - - for(i=0; i<osst_dev_max; i++) { - tpnt = os_scsi_tapes[i]; - if(tpnt != NULL && tpnt->device == SDp) { - tpnt->device = NULL; -#ifdef CONFIG_DEVFS_FS - for (mode = 0; mode < ST_NBR_MODES; ++mode) { - devfs_unregister (tpnt->de_r[mode]); - tpnt->de_r[mode] = NULL; - devfs_unregister (tpnt->de_n[mode]); - tpnt->de_n[mode] = NULL; + int i, mode; + + write_lock(&os_scsi_tapes_lock); + if (os_scsi_tapes != NULL) { + for(i=0; i<osst_max_dev; i++) { + tpnt = os_scsi_tapes[i]; + if(tpnt != NULL && tpnt->device == SDp) { + tpnt->device = NULL; + for (mode = 0; mode < ST_NBR_MODES; ++mode) { + devfs_unregister (tpnt->de_r[mode]); + tpnt->de_r[mode] = NULL; + devfs_unregister (tpnt->de_n[mode]); + tpnt->de_n[mode] = NULL; + } + devfs_unregister_tape(tpnt->drive->number); + put_disk(tpnt->drive); + os_scsi_tapes[i] = NULL; + scsi_slave_detach(SDp); + osst_nr_dev--; + write_unlock(&os_scsi_tapes_lock); + for (mode = 0; mode < ST_NBR_MODES; ++mode) { + device_remove_file(&tpnt->driverfs_dev_r[mode], + &dev_attr_type); + device_remove_file(&tpnt->driverfs_dev_r[mode], + &dev_attr_kdev); + device_unregister(&tpnt->driverfs_dev_r[mode]); + device_remove_file(&tpnt->driverfs_dev_n[mode], + &dev_attr_type); + device_remove_file(&tpnt->driverfs_dev_n[mode], + &dev_attr_kdev); + device_unregister(&tpnt->driverfs_dev_n[mode]); + } + if (tpnt->header_cache != NULL) + vfree(tpnt->header_cache); + if (tpnt->buffer) { + normalize_buffer(tpnt->buffer); + kfree(tpnt->buffer); + } + kfree(tpnt); + break; } - devfs_unregister_tape(tpnt->disk->number); -#endif - put_disk(tpnt->disk); - kfree(tpnt); - os_scsi_tapes[i] = NULL; - scsi_slave_detach(SDp); - osst_nr_dev--; - return; - } + } } + + write_unlock(&os_scsi_tapes_lock); return; } static int __init init_osst(void) { + printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid); + validate_options(); - return scsi_register_device(&osst_template); +#if DEBUG + printk(OSST_DEB_MSG "osst :D: %d s/g segments, write threshold %d bytes.\n", + max_sg_segs, osst_write_threshold); +#endif + if ((register_chrdev(MAJOR_NR,"osst",&osst_fops) < 0) || scsi_register_device(&osst_template)) { + printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n",MAJOR_NR); + return 1; + } + + return 0; } static void __exit exit_osst (void) @@ -5651,31 +5701,22 @@ static void __exit exit_osst (void) scsi_unregister_device(&osst_template); unregister_chrdev(MAJOR_NR, "osst"); - osst_registered--; + if (os_scsi_tapes) { - for (i=0; i < osst_dev_max; ++i) { - STp = os_scsi_tapes[i]; - if (!STp) - continue; + for (i=0; i < osst_max_dev; ++i) { + if (!(STp = os_scsi_tapes[i])) continue; + /* This is defensive, supposed to happen during detach */ if (STp->header_cache) vfree(STp->header_cache); - put_disk(STp->disk); + if (STp->buffer) { + normalize_buffer(STp->buffer); + kfree(STp->buffer); + } + put_disk(STp->drive); kfree(STp); } kfree(os_scsi_tapes); - - if (osst_buffers) { - for (i=0; i < osst_nbr_buffers; i++) { - if (osst_buffers[i]) { - osst_buffers[i]->orig_sg_segs = 0; - normalize_buffer(osst_buffers[i]); - kfree(osst_buffers[i]); - } - } - kfree(osst_buffers); - } } - osst_dev_max = 0; printk(KERN_INFO "osst :I: Unloaded.\n"); } diff --git a/drivers/scsi/osst.h b/drivers/scsi/osst.h index 581421ddf59d..d322df1fd383 100644 --- a/drivers/scsi/osst.h +++ b/drivers/scsi/osst.h @@ -510,7 +510,7 @@ typedef struct os_header_s { #define OS_AUX_SIZE (512) //#define OSST_MAX_SG 2 -/* The tape buffer descriptor. */ +/* The OnStream tape buffer descriptor. */ typedef struct { unsigned char in_use; unsigned char dma; /* DMA-able buffer */ @@ -523,14 +523,14 @@ typedef struct { int syscall_result; Scsi_Request *last_SRpnt; unsigned char *b_data; - os_aux_t *aux; /* onstream AUX structure at end of each block */ - unsigned short use_sg; /* zero or number of segments for this adapter */ - unsigned short sg_segs; /* total number of allocated segments */ - unsigned short orig_sg_segs; /* number of segments allocated at first try */ - struct scatterlist sg[1]; /* MUST BE last item */ + os_aux_t *aux; /* onstream AUX structure at end of each block */ + unsigned short use_sg; /* zero or number of s/g segments for this adapter */ + unsigned short sg_segs; /* number of segments in s/g list */ + unsigned short orig_sg_segs; /* number of segments allocated at first try */ + struct scatterlist sg[1]; /* MUST BE last item */ } OSST_buffer; -/* The tape drive descriptor */ +/* The OnStream tape drive descriptor */ typedef struct { struct Scsi_Device_Template *driver; unsigned capacity; @@ -549,6 +549,7 @@ typedef struct { unsigned char restr_dma; unsigned char scsi2_logical; unsigned char default_drvbuffer; /* 0xff = don't touch, value 3 bits */ + unsigned char pos_unknown; /* after reset position unknown */ int write_threshold; int timeout; /* timeout for normal commands */ int long_timeout; /* timeout for commands known to take long time*/ @@ -556,10 +557,10 @@ typedef struct { /* Mode characteristics */ ST_mode modes[ST_NBR_MODES]; int current_mode; -#ifdef CONFIG_DEVFS_FS devfs_handle_t de_r[ST_NBR_MODES]; /* Rewind entries */ devfs_handle_t de_n[ST_NBR_MODES]; /* No-rewind entries */ -#endif + struct device driverfs_dev_r[ST_NBR_MODES]; + struct device driverfs_dev_n[ST_NBR_MODES]; /* Status variables */ int partition; @@ -628,7 +629,7 @@ typedef struct { unsigned char last_cmnd[6]; unsigned char last_sense[16]; #endif - struct gendisk *disk; + struct gendisk *drive; } OS_Scsi_Tape; /* Values of write_type */ diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 3fa62128e661..84fef0b16331 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -92,7 +92,8 @@ static int fdomain_event(event_t event, int priority, static dev_link_t *fdomain_attach(void); static void fdomain_detach(dev_link_t *); -static Scsi_Host_Template driver_template = FDOMAIN_16X0; +#define driver_template fdomain_driver_template +extern Scsi_Host_Template fdomain_driver_template; static dev_link_t *dev_list = NULL; diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index fc232e579518..6e7b79d5b93e 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -50,8 +50,6 @@ #include <../drivers/scsi/qlogicfas.h> -#define qlogic_reset(h) qlogicfas_reset(h, 0) - #include <pcmcia/version.h> #include <pcmcia/cs_types.h> #include <pcmcia/cs.h> @@ -65,8 +63,7 @@ extern void qlogicfas_preset(int port, int irq); static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) -static char *version = -"qlogic_cs.c 1.79 2000/06/12 21:27:26 (David Hinds)"; +static char *version = "qlogic_cs.c 1.79-ac 2002/10/26 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -76,7 +73,7 @@ static char *version = /* Parameters that can be set with 'insmod' */ /* Bit map of interrupts to choose from */ -static u_int irq_mask = 0xdeb8; +static unsigned int irq_mask = 0xdeb8; static int irq_list[4] = { -1 }; MODULE_PARM(irq_mask, "i"); @@ -85,20 +82,21 @@ MODULE_PARM(irq_list, "1-4i"); /*====================================================================*/ typedef struct scsi_info_t { - dev_link_t link; - u_short manf_id; - int ndev; - dev_node_t node[8]; + dev_link_t link; + unsigned short manf_id; + int ndev; + dev_node_t node[8]; } scsi_info_t; static void qlogic_release(u_long arg); -static int qlogic_event(event_t event, int priority, - event_callback_args_t *args); +static int qlogic_event(event_t event, int priority, event_callback_args_t * args); static dev_link_t *qlogic_attach(void); static void qlogic_detach(dev_link_t *); -static Scsi_Host_Template driver_template = QLOGICFAS; +/* Import our driver template */ +extern Scsi_Host_Template qlogicfas_driver_template; +#define driver_template qlogicfas_driver_template static dev_link_t *dev_list = NULL; @@ -108,97 +106,97 @@ static dev_info_t dev_info = "qlogic_cs"; static void cs_error(client_handle_t handle, int func, int ret) { - error_info_t err = { func, ret }; - CardServices(ReportError, handle, &err); + error_info_t err = { func, ret }; + CardServices(ReportError, handle, &err); } /*====================================================================*/ static dev_link_t *qlogic_attach(void) { - scsi_info_t *info; - client_reg_t client_reg; - dev_link_t *link; - int i, ret; - - DEBUG(0, "qlogic_attach()\n"); - - /* Create new SCSI device */ - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) return NULL; - memset(info, 0, sizeof(*info)); - link = &info->link; link->priv = info; - link->release.function = &qlogic_release; - link->release.data = (u_long)link; - - link->io.NumPorts1 = 16; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 10; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; - if (irq_list[0] == -1) - link->irq.IRQInfo2 = irq_mask; - else - for (i = 0; i < 4; i++) - link->irq.IRQInfo2 |= 1 << irq_list[i]; - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.Present = PRESENT_OPTION; - - /* Register with Card Services */ - link->next = dev_list; - dev_list = link; - client_reg.dev_info = &dev_info; - client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; - client_reg.event_handler = &qlogic_event; - client_reg.EventMask = - CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET | - CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | - CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; - client_reg.Version = 0x0210; - client_reg.event_callback_args.client_data = link; - ret = CardServices(RegisterClient, &link->handle, &client_reg); - if (ret != 0) { - cs_error(link->handle, RegisterClient, ret); - qlogic_detach(link); - return NULL; - } - - return link; -} /* qlogic_attach */ + scsi_info_t *info; + client_reg_t client_reg; + dev_link_t *link; + int i, ret; + + DEBUG(0, "qlogic_attach()\n"); + + /* Create new SCSI device */ + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return NULL; + memset(info, 0, sizeof(*info)); + link = &info->link; + link->priv = info; + link->release.function = &qlogic_release; + link->release.data = (u_long) link; + + link->io.NumPorts1 = 16; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + link->io.IOAddrLines = 10; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; + if (irq_list[0] == -1) + link->irq.IRQInfo2 = irq_mask; + else + for (i = 0; i < 4; i++) + link->irq.IRQInfo2 |= 1 << irq_list[i]; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.Present = PRESENT_OPTION; + + /* Register with Card Services */ + link->next = dev_list; + dev_list = link; + client_reg.dev_info = &dev_info; + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; + client_reg.event_handler = &qlogic_event; + client_reg.EventMask = CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + ret = CardServices(RegisterClient, &link->handle, &client_reg); + if (ret != 0) { + cs_error(link->handle, RegisterClient, ret); + qlogic_detach(link); + return NULL; + } + + return link; +} /* qlogic_attach */ /*====================================================================*/ -static void qlogic_detach(dev_link_t *link) +static void qlogic_detach(dev_link_t * link) { - dev_link_t **linkp; + dev_link_t **linkp; - DEBUG(0, "qlogic_detach(0x%p)\n", link); - - /* Locate device structure */ - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) break; - if (*linkp == NULL) - return; + DEBUG(0, "qlogic_detach(0x%p)\n", link); + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) + break; + if (*linkp == NULL) + return; - del_timer(&link->release); - if (link->state & DEV_CONFIG) { - qlogic_release((u_long)link); - if (link->state & DEV_STALE_CONFIG) { - link->state |= DEV_STALE_LINK; - return; + del_timer_sync(&link->release); + if (link->state & DEV_CONFIG) { + qlogic_release((u_long) link); + if (link->state & DEV_STALE_CONFIG) { + link->state |= DEV_STALE_LINK; + return; + } } - } - if (link->handle) - CardServices(DeregisterClient, link->handle); - - /* Unlink device structure, free bits */ - *linkp = link->next; - kfree(link->priv); - -} /* qlogic_detach */ + if (link->handle) + CardServices(DeregisterClient, link->handle); + + /* Unlink device structure, free bits */ + *linkp = link->next; + kfree(link->priv); + +} /* qlogic_detach */ /*====================================================================*/ @@ -208,220 +206,216 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed #define CFG_CHECK(fn, args...) \ if (CardServices(fn, args) != 0) goto next_entry -static void qlogic_config(dev_link_t *link) +static void qlogic_config(dev_link_t * link) { - client_handle_t handle = link->handle; - scsi_info_t *info = link->priv; - tuple_t tuple; - cisparse_t parse; - int i, last_ret, last_fn; - u_short tuple_data[32]; - Scsi_Device *dev; - dev_node_t **tail, *node; - struct Scsi_Host *host; - - DEBUG(0, "qlogic_config(0x%p)\n", link); - - tuple.TupleData = (cisdata_t *)tuple_data; - tuple.TupleDataMax = 64; - tuple.TupleOffset = 0; - tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, handle, &tuple); - CS_CHECK(GetTupleData, handle, &tuple); - CS_CHECK(ParseTuple, handle, &tuple, &parse); - link->conf.ConfigBase = parse.config.base; - - tuple.DesiredTuple = CISTPL_MANFID; - if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) && - (CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS)) - info->manf_id = le16_to_cpu(tuple.TupleData[0]); - - /* Configure card */ - driver_template.module = &__this_module; - link->state |= DEV_CONFIG; - - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, handle, &tuple); - while (1) { - CFG_CHECK(GetTupleData, handle, &tuple); - CFG_CHECK(ParseTuple, handle, &tuple, &parse); - link->conf.ConfigIndex = parse.cftable_entry.index; - link->io.BasePort1 = parse.cftable_entry.io.win[0].base; - link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; - if (link->io.BasePort1 != 0) { - i = CardServices(RequestIO, handle, &link->io); - if (i == CS_SUCCESS) break; + client_handle_t handle = link->handle; + scsi_info_t *info = link->priv; + tuple_t tuple; + cisparse_t parse; + int i, last_ret, last_fn; + unsigned short tuple_data[32]; + Scsi_Device *dev; + dev_node_t **tail, *node; + struct Scsi_Host *host; + + DEBUG(0, "qlogic_config(0x%p)\n", link); + + tuple.TupleData = (cisdata_t *) tuple_data; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, handle, &tuple); + CS_CHECK(GetTupleData, handle, &tuple); + CS_CHECK(ParseTuple, handle, &tuple, &parse); + link->conf.ConfigBase = parse.config.base; + + tuple.DesiredTuple = CISTPL_MANFID; + if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) && (CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS)) + info->manf_id = le16_to_cpu(tuple.TupleData[0]); + + /* Configure card */ + driver_template.module = &__this_module; + link->state |= DEV_CONFIG; + + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, handle, &tuple); + while (1) { + CFG_CHECK(GetTupleData, handle, &tuple); + CFG_CHECK(ParseTuple, handle, &tuple, &parse); + link->conf.ConfigIndex = parse.cftable_entry.index; + link->io.BasePort1 = parse.cftable_entry.io.win[0].base; + link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; + if (link->io.BasePort1 != 0) { + i = CardServices(RequestIO, handle, &link->io); + if (i == CS_SUCCESS) + break; + } + next_entry: + CS_CHECK(GetNextTuple, handle, &tuple); } - next_entry: - CS_CHECK(GetNextTuple, handle, &tuple); - } - - CS_CHECK(RequestIRQ, handle, &link->irq); - CS_CHECK(RequestConfiguration, handle, &link->conf); - - if ((info->manf_id == MANFID_MACNICA) || - (info->manf_id == MANFID_PIONEER) || - (info->manf_id == 0x0098)) { - /* set ATAcmd */ - outb(0xb4, link->io.BasePort1+0xd); - outb(0x24, link->io.BasePort1+0x9); - outb(0x04, link->io.BasePort1+0xd); - } - - /* A bad hack... */ - release_region(link->io.BasePort1, link->io.NumPorts1); - - /* The KXL-810AN has a bigger IO port window */ - if (link->io.NumPorts1 == 32) - qlogicfas_preset(link->io.BasePort1+16, link->irq.AssignedIRQ); - else - qlogicfas_preset(link->io.BasePort1, link->irq.AssignedIRQ); - - scsi_register_host(&driver_template); - - tail = &link->dev; - info->ndev = 0; - for (host = scsi_host_get_next(NULL); host; - host = scsi_host_get_next(host)) - if (host->hostt == &driver_template) - list_for_each_entry (dev, &host->my_devices, siblings) { - u_long arg[2], id; - kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg); - id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) + - ((arg[0]>>8)&0xf00) + ((arg[0]>>12)&0xf000); - node = &info->node[info->ndev]; - node->minor = 0; - switch (dev->type) { - case TYPE_TAPE: - node->major = SCSI_TAPE_MAJOR; - sprintf(node->dev_name, "st#%04lx", id); - break; - case TYPE_DISK: - case TYPE_MOD: - node->major = SCSI_DISK0_MAJOR; - sprintf(node->dev_name, "sd#%04lx", id); - break; - case TYPE_ROM: - case TYPE_WORM: - node->major = SCSI_CDROM_MAJOR; - sprintf(node->dev_name, "sr#%04lx", id); - break; - default: - node->major = SCSI_GENERIC_MAJOR; - sprintf(node->dev_name, "sg#%04lx", id); - break; - } - *tail = node; tail = &node->next; - info->ndev++; + + CS_CHECK(RequestIRQ, handle, &link->irq); + CS_CHECK(RequestConfiguration, handle, &link->conf); + + if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) { + /* set ATAcmd */ + outb(0xb4, link->io.BasePort1 + 0xd); + outb(0x24, link->io.BasePort1 + 0x9); + outb(0x04, link->io.BasePort1 + 0xd); } - *tail = NULL; - if (info->ndev == 0) - printk(KERN_INFO "qlogic_cs: no SCSI devices found\n"); - - link->state &= ~DEV_CONFIG_PENDING; - return; + + /* A bad hack... */ + release_region(link->io.BasePort1, link->io.NumPorts1); + + /* The KXL-810AN has a bigger IO port window */ + if (link->io.NumPorts1 == 32) + qlogicfas_preset(link->io.BasePort1 + 16, link->irq.AssignedIRQ); + else + qlogicfas_preset(link->io.BasePort1, link->irq.AssignedIRQ); + + scsi_register_host(&driver_template); + + tail = &link->dev; + info->ndev = 0; + for (host = scsi_host_get_next(NULL); host; host = scsi_host_get_next(host)) + if (host->hostt == &driver_template) + list_for_each_entry (dev, &host->my_devices, siblings) { + u_long arg[2], id; + kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg); + id = (arg[0] & 0x0f) + ((arg[0] >> 4) & 0xf0) + ((arg[0] >> 8) & 0xf00) + ((arg[0] >> 12) & 0xf000); + node = &info->node[info->ndev]; + node->minor = 0; + switch (dev->type) { + case TYPE_TAPE: + node->major = SCSI_TAPE_MAJOR; + sprintf(node->dev_name, "st#%04lx", id); + break; + case TYPE_DISK: + case TYPE_MOD: + node->major = SCSI_DISK0_MAJOR; + sprintf(node->dev_name, "sd#%04lx", id); + break; + case TYPE_ROM: + case TYPE_WORM: + node->major = SCSI_CDROM_MAJOR; + sprintf(node->dev_name, "sr#%04lx", id); + break; + default: + node->major = SCSI_GENERIC_MAJOR; + sprintf(node->dev_name, "sg#%04lx", id); + break; + } + *tail = node; + tail = &node->next; + info->ndev++; + } + *tail = NULL; + if (info->ndev == 0) + printk(KERN_INFO "qlogic_cs: no SCSI devices found\n"); + + link->state &= ~DEV_CONFIG_PENDING; + return; cs_failed: - cs_error(link->handle, last_fn, last_ret); - qlogic_release((u_long)link); - return; + cs_error(link->handle, last_fn, last_ret); + qlogic_release((u_long) link); + return; -} /* qlogic_config */ +} /* qlogic_config */ /*====================================================================*/ static void qlogic_release(u_long arg) { - dev_link_t *link = (dev_link_t *)arg; + dev_link_t *link = (dev_link_t *) arg; - DEBUG(0, "qlogic_release(0x%p)\n", link); + DEBUG(0, "qlogic_release(0x%p)\n", link); - if (GET_USE_COUNT(&__this_module) != 0) { - DEBUG(0, "qlogic_cs: release postponed, device still open\n"); - link->state |= DEV_STALE_CONFIG; - return; - } + if (GET_USE_COUNT(&__this_module) != 0) { + DEBUG(0, "qlogic_cs: release postponed, device still open\n"); + link->state |= DEV_STALE_CONFIG; + return; + } - scsi_unregister_host(&driver_template); - link->dev = NULL; - - CardServices(ReleaseConfiguration, link->handle); - CardServices(ReleaseIO, link->handle, &link->io); - CardServices(ReleaseIRQ, link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; - if (link->state & DEV_STALE_LINK) - qlogic_detach(link); - -} /* qlogic_release */ + scsi_unregister_host(&driver_template); + link->dev = NULL; + + CardServices(ReleaseConfiguration, link->handle); + CardServices(ReleaseIO, link->handle, &link->io); + CardServices(ReleaseIRQ, link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; + if (link->state & DEV_STALE_LINK) + qlogic_detach(link); + +} /* qlogic_release */ /*====================================================================*/ -static int qlogic_event(event_t event, int priority, - event_callback_args_t *args) +static int qlogic_event(event_t event, int priority, event_callback_args_t * args) { - dev_link_t *link = args->client_data; + dev_link_t *link = args->client_data; - DEBUG(1, "qlogic_event(0x%06x)\n", event); - - switch (event) { - case CS_EVENT_CARD_REMOVAL: - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) - mod_timer(&link->release, jiffies + HZ/20); - break; - case CS_EVENT_CARD_INSERTION: - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - qlogic_config(link); - break; - case CS_EVENT_PM_SUSPEND: - link->state |= DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - if (link->state & DEV_CONFIG) - CardServices(ReleaseConfiguration, link->handle); - break; - case CS_EVENT_PM_RESUME: - link->state &= ~DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_CARD_RESET: - if (link->state & DEV_CONFIG) { - scsi_info_t *info = link->priv; - CardServices(RequestConfiguration, link->handle, &link->conf); - if ((info->manf_id == MANFID_MACNICA) || - (info->manf_id == MANFID_PIONEER) || - (info->manf_id == 0x0098)) { - outb( 0x80, link->io.BasePort1+0xd); - outb( 0x24, link->io.BasePort1+0x9); - outb( 0x04, link->io.BasePort1+0xd); - } - qlogic_reset(NULL); + DEBUG(1, "qlogic_event(0x%06x)\n", event); + + switch (event) { + case CS_EVENT_CARD_REMOVAL: + link->state &= ~DEV_PRESENT; + if (link->state & DEV_CONFIG) + mod_timer(&link->release, jiffies + HZ / 20); + break; + case CS_EVENT_CARD_INSERTION: + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + qlogic_config(link); + break; + case CS_EVENT_PM_SUSPEND: + link->state |= DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_RESET_PHYSICAL: + if (link->state & DEV_CONFIG) + CardServices(ReleaseConfiguration, link->handle); + break; + case CS_EVENT_PM_RESUME: + link->state &= ~DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_CARD_RESET: + if (link->state & DEV_CONFIG) { + scsi_info_t *info = link->priv; + CardServices(RequestConfiguration, link->handle, &link->conf); + if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) { + outb(0x80, link->io.BasePort1 + 0xd); + outb(0x24, link->io.BasePort1 + 0x9); + outb(0x04, link->io.BasePort1 + 0xd); + } + /* Ugggglllyyyy!!! */ + driver_template.eh_bus_reset_handler(NULL); + } + break; } - break; - } - return 0; -} /* qlogic_event */ + return 0; +} /* qlogic_event */ /*====================================================================*/ -static int __init init_qlogic_cs(void) { - servinfo_t serv; - DEBUG(0, "%s\n", version); - CardServices(GetCardServicesInfo, &serv); - if (serv.Revision != CS_RELEASE_CODE) { - printk(KERN_NOTICE "qlogic_cs: Card Services release " - "does not match!\n"); - return -1; - } - register_pccard_driver(&dev_info, &qlogic_attach, &qlogic_detach); - return 0; +static int __init init_qlogic_cs(void) +{ + servinfo_t serv; + DEBUG(0, "%s\n", version); + CardServices(GetCardServicesInfo, &serv); + if (serv.Revision != CS_RELEASE_CODE) { + printk(KERN_NOTICE "qlogic_cs: Card Services release " "does not match!\n"); + return -1; + } + register_pccard_driver(&dev_info, &qlogic_attach, &qlogic_detach); + return 0; } -static void __exit exit_qlogic_cs(void) { - DEBUG(0, "qlogic_cs: unloading\n"); - unregister_pccard_driver(&dev_info); - while (dev_list != NULL) - qlogic_detach(dev_list); +static void __exit exit_qlogic_cs(void) +{ + DEBUG(0, "qlogic_cs: unloading\n"); + unregister_pccard_driver(&dev_info); + while (dev_list != NULL) + qlogic_detach(dev_list); } module_init(init_qlogic_cs); diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 8974f80da1af..f9c56ce1108b 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -169,30 +169,13 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt); /* * Function: scsi_initialize_queue() * - * Purpose: Selects queue handler function for a device. + * Purpose: Sets up the block queue for a device. * * Arguments: SDpnt - device for which we need a handler function. * * Returns: Nothing * * Lock status: No locking assumed or required. - * - * Notes: Most devices will end up using scsi_request_fn for the - * handler function (at least as things are done now). - * The "block" feature basically ensures that only one of - * the blocked hosts is active at one time, mainly to work around - * buggy DMA chipsets where the memory gets starved. - * For this case, we have a special handler function, which - * does some checks and ultimately calls scsi_request_fn. - * - * The single_lun feature is a similar special case. - * - * We handle these things by stacking the handlers. The - * special case handlers simply check a few conditions, - * and return if they are not supposed to do anything. - * In the event that things are OK, then they call the next - * handler in the list - ultimately they call scsi_request_fn - * to do the dirty deed. */ void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt) { @@ -793,7 +776,6 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt) rtn = host->hostt->queuecommand(SCpnt, scsi_done); spin_unlock_irqrestore(host->host_lock, flags); if (rtn != 0) { - scsi_delete_timer(SCpnt); scsi_mlqueue_insert(SCpnt, rtn == SCSI_MLQUEUE_DEVICE_BUSY ? rtn : SCSI_MLQUEUE_HOST_BUSY); SCSI_LOG_MLQUEUE(3, printk("queuecommand : request rejected\n")); @@ -1895,20 +1877,12 @@ int scsi_attach_device(struct scsi_device *sdev) struct Scsi_Device_Template *sdt; down_read(&scsi_devicelist_mutex); - list_for_each_entry(sdt, &scsi_devicelist, list) - if (sdt->attach) { - /* - * XXX check result when the upper level attach - * return values are fixed, and on failure goto - * fail. - */ - if(try_module_get(sdt->module)) { - (*sdt->attach)(sdev); - module_put(sdt->module); - } else { - printk(KERN_WARNING "SCSI module %s not ready, skipping attach.\n", sdt->name); - } - } + list_for_each_entry(sdt, &scsi_devicelist, list) { + if (!try_module_get(sdt->module)) + continue; + (*sdt->attach)(sdev); + module_put(sdt->module); + } up_read(&scsi_devicelist_mutex); return 0; } @@ -1918,18 +1892,30 @@ void scsi_detach_device(struct scsi_device *sdev) struct Scsi_Device_Template *sdt; down_read(&scsi_devicelist_mutex); - list_for_each_entry(sdt, &scsi_devicelist, list) - if (sdt->detach) { - if(try_module_get(sdt->module)) { - (*sdt->detach)(sdev); - module_put(sdt->module); - } else { - printk(KERN_WARNING "SCSI module %s not ready, skipping detach.\n", sdt->name); - } - } + list_for_each_entry(sdt, &scsi_devicelist, list) { + if (!try_module_get(sdt->module)) + continue; + (*sdt->detach)(sdev); + module_put(sdt->module); + } up_read(&scsi_devicelist_mutex); } +int scsi_device_get(struct scsi_device *sdev) +{ + if (!try_module_get(sdev->host->hostt->module)) + return -ENXIO; + + sdev->access_count++; + return 0; +} + +void scsi_device_put(struct scsi_device *sdev) +{ + sdev->access_count--; + module_put(sdev->host->hostt->module); +} + /* * Function: scsi_slave_attach() * @@ -1953,7 +1939,7 @@ int scsi_slave_attach(struct scsi_device *sdev) printk(KERN_ERR "scsi: Allocation failure during" " attach, some SCSI devices might not be" " configured\n"); - return 1; + return -ENOMEM; } if (sdev->host->hostt->slave_configure != NULL) { if (sdev->host->hostt->slave_configure(sdev) != 0) { @@ -1961,7 +1947,7 @@ int scsi_slave_attach(struct scsi_device *sdev) " attach, some SCSI device might not be" " configured\n"); scsi_release_commandblocks(sdev); - return 1; + return -ENOMEM; } } else if (sdev->host->cmd_per_lun != 0) scsi_adjust_queue_depth(sdev, 0, @@ -2019,10 +2005,7 @@ int scsi_register_device(struct Scsi_Device_Template *tpnt) list_add_tail(&tpnt->list, &scsi_devicelist); up_write(&scsi_devicelist_mutex); - tpnt->scsi_driverfs_driver.name = (char *)tpnt->tag; - tpnt->scsi_driverfs_driver.bus = &scsi_driverfs_bus_type; - - driver_register(&tpnt->scsi_driverfs_driver); + scsi_upper_driver_register(tpnt); for (shpnt = scsi_host_get_next(NULL); shpnt; shpnt = scsi_host_get_next(shpnt)) @@ -2037,7 +2020,6 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt) Scsi_Device *SDpnt; struct Scsi_Host *shpnt; - driver_unregister(&tpnt->scsi_driverfs_driver); /* * Next, detach the devices from the driver. @@ -2055,6 +2037,8 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt) list_del(&tpnt->list); up_write(&scsi_devicelist_mutex); + scsi_upper_driver_unregister(tpnt); + /* * Final cleanup for the driver is done in the driver sources in the * cleanup function. @@ -2153,34 +2137,6 @@ void scsi_free_sgtable(struct scatterlist *sgl, int index) mempool_free(sgl, sgp->pool); } -static int scsi_bus_match(struct device *scsi_driverfs_dev, - struct device_driver *scsi_driverfs_drv) -{ - char *p=0; - - if (!strcmp("sd", scsi_driverfs_drv->name)) { - if ((p = strstr(scsi_driverfs_dev->bus_id, ":disc")) || - (p = strstr(scsi_driverfs_dev->bus_id, ":p"))) { - return 1; - } - } else if (!strcmp("sg", scsi_driverfs_drv->name)) { - if (strstr(scsi_driverfs_dev->bus_id, ":gen")) - return 1; - } else if (!strcmp("sr",scsi_driverfs_drv->name)) { - if (strstr(scsi_driverfs_dev->bus_id,":cd")) - return 1; - } else if (!strcmp("st",scsi_driverfs_drv->name)) { - if (strstr(scsi_driverfs_dev->bus_id,":mt")) - return 1; - } - return 0; -} - -struct bus_type scsi_driverfs_bus_type = { - .name = "scsi", - .match = scsi_bus_match, -}; - static int __init init_scsi(void) { int i; @@ -2207,7 +2163,7 @@ static int __init init_scsi(void) scsi_devfs_handle = devfs_mk_dir(NULL, "scsi", NULL); scsi_host_init(); scsi_dev_info_list_init(scsi_dev_flags); - bus_register(&scsi_driverfs_bus_type); + scsi_sysfs_register(); open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL); return 0; } @@ -2216,7 +2172,7 @@ static void __exit exit_scsi(void) { int i; - bus_unregister(&scsi_driverfs_bus_type); + scsi_sysfs_unregister(); scsi_dev_info_list_delete(); devfs_unregister(scsi_devfs_handle); scsi_exit_procfs(); @@ -2230,5 +2186,5 @@ static void __exit exit_scsi(void) } } -module_init(init_scsi); +subsys_initcall(init_scsi); module_exit(exit_scsi); diff --git a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h index 62b4a4ca6c7e..9070c70c1913 100644 --- a/drivers/scsi/scsi.h +++ b/drivers/scsi/scsi.h @@ -401,9 +401,6 @@ typedef struct scsi_request Scsi_Request; extern unsigned int scsi_logging_level; /* What do we log? */ -extern struct bus_type scsi_driverfs_bus_type; - - /* * These are the error handling functions defined in scsi_error.c */ @@ -451,8 +448,10 @@ extern void scsi_release_commandblocks(Scsi_Device * SDpnt); extern void scsi_build_commandblocks(Scsi_Device * SDpnt); extern void scsi_adjust_queue_depth(Scsi_Device *, int, int); extern int scsi_track_queue_full(Scsi_Device *, int); -extern int scsi_slave_attach(struct scsi_device *sdev); -extern void scsi_slave_detach(struct scsi_device *sdev); +extern int scsi_slave_attach(struct scsi_device *); +extern void scsi_slave_detach(struct scsi_device *); +extern int scsi_device_get(struct scsi_device *); +extern void scsi_device_put(struct scsi_device *); extern void scsi_done(Scsi_Cmnd * SCpnt); extern void scsi_finish_command(Scsi_Cmnd *); extern int scsi_retry_command(Scsi_Cmnd *); @@ -509,9 +508,6 @@ static inline void scsi_proc_host_rm(struct Scsi_Host *); /* * Prototypes for functions in scsi_scan.c */ -extern struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *, - uint, uint, uint); -extern void scsi_free_sdev(struct scsi_device *); extern int scsi_add_single_device(uint, uint, uint, uint); extern int scsi_remove_single_device(uint, uint, uint, uint); @@ -992,4 +988,10 @@ static inline Scsi_Cmnd *scsi_find_tag(Scsi_Device *SDpnt, int tag) { int scsi_set_medium_removal(Scsi_Device *dev, char state); +extern int scsi_device_register(struct scsi_device *); +extern void scsi_device_unregister(struct scsi_device *); + +extern int scsi_sysfs_register(void); +extern void scsi_sysfs_unregister(void); + #endif diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 6b6162eb6cc9..6e5bcf095996 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -155,6 +155,7 @@ static rwlock_t atomic_rw = RW_LOCK_UNLOCKED; static char sdebug_proc_name[] = "scsi_debug"; static struct device_driver sdebug_driverfs_driver = { .name = sdebug_proc_name, + .devclass = &shost_devclass, }; /* function declarations */ @@ -1501,7 +1502,7 @@ static void sdebug_add_shost(int num) printk(KERN_ERR "sdebug_add_shost: scsi_register failed\n"); return; } - err = scsi_add_host(hpnt); + err = scsi_add_host(hpnt, scsi_debug_hosts[num].dev); if (err) { printk(KERN_ERR "sdebug_add_shost: scsi_add_host failed\n"); scsi_unregister(hpnt); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 4759895ac607..52f75be25ed2 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -7,18 +7,15 @@ * of people at Linux Expo. */ -#include <linux/string.h> -#include <linux/slab.h> #include <linux/bio.h> -#include <linux/kernel.h> #include <linux/blk.h> -#include <asm/hardirq.h> -#include <linux/smp_lock.h> #include <linux/completion.h> +#include <linux/kernel.h> +#include <linux/slab.h> #include "scsi.h" #include "hosts.h" -#include <scsi/scsi_ioctl.h> + /* * Function: scsi_insert_special_cmd() @@ -665,7 +662,7 @@ static int scsi_init_io(Scsi_Cmnd *SCpnt) { struct request *req = SCpnt->request; struct scatterlist *sgpnt; - int count, gfp_mask, ret = 0; + int count, ret = 0; /* * if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer @@ -685,16 +682,10 @@ static int scsi_init_io(Scsi_Cmnd *SCpnt) */ SCpnt->use_sg = req->nr_phys_segments; - gfp_mask = GFP_NOIO; - if (likely(in_atomic())) { - gfp_mask &= ~__GFP_WAIT; - gfp_mask |= __GFP_HIGH; - } - /* * if sg table allocation fails, requeue request later. */ - sgpnt = scsi_alloc_sgtable(SCpnt, gfp_mask); + sgpnt = scsi_alloc_sgtable(SCpnt, GFP_ATOMIC); if (unlikely(!sgpnt)) { req->flags |= REQ_SPECIAL; ret = BLKPREP_DEFER; diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 4a3d1c3d1ef3..c6c49a2710bd 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -313,73 +313,6 @@ static void scsi_unlock_floptical(Scsi_Request *sreq, unsigned char *result) } /** - * scsi_device_type_read - copy out the SCSI type - * @driverfs_dev: driverfs device to check - * @page: copy data into this area - * @count: number of bytes to copy - * @off: start at this offset in page - * - * Description: - * Called via driverfs when the "type" (in scsi_device_type_file) - * field is read. Copy the appropriate SCSI type string into @page, - * followed by a newline and a '\0'. Go through gyrations so we don't - * write more than @count, and we don't write past @off. - * - * Notes: - * This is for the top-most scsi entry in driverfs, the upper-level - * drivers have their own type file. XXX This is not part of scanning, - * other than we reference the attr struct in this file, move to - * scsi.c or scsi_lib.c. - * - * Return: - * number of bytes written into page. - **/ -static ssize_t scsi_device_type_read(struct device *driverfs_dev, char *page, - size_t count, loff_t off) -{ - struct scsi_device *sdev = to_scsi_device(driverfs_dev); - const char *type; - size_t size, len; - - if ((sdev->type > MAX_SCSI_DEVICE_CODE) || - (scsi_device_types[(int)sdev->type] == NULL)) - type = "Unknown"; - else - type = scsi_device_types[(int)sdev->type]; - size = strlen(type); - /* - * Check if off is past size + 1 for newline + 1 for a '\0'. - */ - if (off >= (size + 2)) - return 0; - if (size > off) { - len = min((size_t) (size - off), count); - memcpy(page + off, type + off, len); - } else - len = 0; - if (((len + off) == size) && (len < count)) - /* - * We are at the end of the string and have space, add a - * new line. - */ - *(page + off + len++) = '\n'; - if (((len + off) == (size + 1)) && (len < count)) - /* - * We are past the newline and have space, add a - * terminating '\0'. - */ - *(page + off + len++) = '\0'; - return len; -} - -/* - * Create dev_attr_type. This is different from the dev_attr_type in scsi - * upper level drivers. - */ -static DEVICE_ATTR(type,S_IRUGO,scsi_device_type_read,NULL); - - -/** * print_inquiry - printk the inquiry information * @inq_result: printk this SCSI INQUIRY * @@ -472,8 +405,8 @@ static void scsi_initialize_merge_fn(struct scsi_device *sd) * Return value: * Scsi_Device pointer, or NULL on failure. **/ -struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, - uint id, uint lun) +static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, + uint channel, uint id, uint lun) { struct scsi_device *sdev, *device; @@ -542,7 +475,7 @@ struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, * Undo the actions in scsi_alloc_sdev, including removing @sdev from * the list, and freeing @sdev. **/ -void scsi_free_sdev(struct scsi_device *sdev) +static void scsi_free_sdev(struct scsi_device *sdev) { list_del(&sdev->siblings); list_del(&sdev->same_target_siblings); @@ -1365,20 +1298,8 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, * function. */ scsi_load_identifier(sdev, sreq); - - /* - * create driverfs files - */ - sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d", - sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); - sdev->sdev_driverfs_dev.parent = &sdev->host->host_driverfs_dev; - sdev->sdev_driverfs_dev.bus = &scsi_driverfs_bus_type; - device_register(&sdev->sdev_driverfs_dev); - - /* - * Create driverfs file entries - */ - device_create_file(&sdev->sdev_driverfs_dev, &dev_attr_type); + + scsi_device_register(sdev); sprintf(devname, "scsi/host%d/bus%d/target%d/lun%d", sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); @@ -1419,6 +1340,14 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, return SCSI_SCAN_LUN_PRESENT; } +static void scsi_remove_lun(struct scsi_device *sdev) +{ + devfs_unregister(sdev->de); + scsi_device_unregister(sdev); + + scsi_free_sdev(sdev); +} + /** * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it * @sdevscan: probe the LUN corresponding to this Scsi_Device @@ -1941,8 +1870,7 @@ int scsi_remove_single_device(uint host, uint channel, uint id, uint lun) if (sdev->attached) goto out; - devfs_unregister(sdev->de); - scsi_free_sdev(sdev); + scsi_remove_lun(sdev); error = 0; out: @@ -2068,3 +1996,69 @@ void scsi_scan_host(struct Scsi_Host *shost) } scsi_free_sdev(sdevscan); } + +void scsi_forget_host(struct Scsi_Host *shost) +{ + struct list_head *le, *lh; + + list_for_each_safe(le, lh, &shost->my_devices) + scsi_remove_lun(list_entry(le, struct scsi_device, siblings)); +} + +/* + * Function: scsi_get_host_dev() + * + * Purpose: Create a Scsi_Device that points to the host adapter itself. + * + * Arguments: SHpnt - Host that needs a Scsi_Device + * + * Lock status: None assumed. + * + * Returns: The Scsi_Device or NULL + * + * Notes: + * Attach a single Scsi_Device to the Scsi_Host - this should + * be made to look like a "pseudo-device" that points to the + * HA itself. + * + * Note - this device is not accessible from any high-level + * drivers (including generics), which is probably not + * optimal. We can add hooks later to attach + */ +struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) +{ + struct scsi_device *sdev; + + sdev = scsi_alloc_sdev(shost, 0, shost->this_id, 0); + if (sdev) { + scsi_build_commandblocks(sdev); + if (sdev->current_queue_depth == 0) + goto fail; + sdev->borken = 0; + } + + return sdev; + +fail: + kfree(sdev); + return NULL; +} + +/* + * Function: scsi_free_host_dev() + * + * Purpose: Free a scsi_device that points to the host adapter itself. + * + * Arguments: SHpnt - Host that needs a Scsi_Device + * + * Lock status: None assumed. + * + * Returns: Nothing + * + * Notes: + */ +void scsi_free_host_dev(struct scsi_device *sdev) +{ + BUG_ON(sdev->id != sdev->host->this_id); + scsi_free_sdev(sdev); +} diff --git a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c index cf31461da57b..85de9b673e33 100644 --- a/drivers/scsi/scsi_syms.c +++ b/drivers/scsi/scsi_syms.c @@ -81,6 +81,8 @@ EXPORT_SYMBOL(scsi_register_blocked_host); EXPORT_SYMBOL(scsi_deregister_blocked_host); EXPORT_SYMBOL(scsi_slave_attach); EXPORT_SYMBOL(scsi_slave_detach); +EXPORT_SYMBOL(scsi_device_get); +EXPORT_SYMBOL(scsi_device_put); /* * This symbol is for the highlevel drivers (e.g. sg) only. @@ -104,6 +106,6 @@ EXPORT_SYMBOL(scsi_add_timer); EXPORT_SYMBOL(scsi_delete_timer); /* - * driverfs support for determining driver types + * sysfs support */ -EXPORT_SYMBOL(scsi_driverfs_bus_type); +EXPORT_SYMBOL(shost_devclass); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c new file mode 100644 index 000000000000..447ba0e02e27 --- /dev/null +++ b/drivers/scsi/scsi_sysfs.c @@ -0,0 +1,204 @@ +/* + * scsi_sysfs.c + * + * SCSI sysfs interface routines. + * + * Created to pull SCSI mid layer sysfs routines into one file. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/blkdev.h> +#include <linux/device.h> +#include "scsi.h" +#include "hosts.h" + +/** + * scsi_host_class_name_show - copy out the SCSI host name + * @dev: device to check + * @page: copy data into this area + * @count: number of bytes to copy + * @off: start at this offset in page + * Return: + * number of bytes written into page. + **/ +static ssize_t scsi_host_class_name_show(struct device *dev, char *page, + size_t count, loff_t off) +{ + struct Scsi_Host *shost; + + if (off) + return 0; + + shost = to_scsi_host(dev); + + if (!shost) + return 0; + + return snprintf(page, count, "scsi%d\n", shost->host_no); +} + +DEVICE_ATTR(class_name, S_IRUGO, scsi_host_class_name_show, NULL); + +static int scsi_host_class_add_dev(struct device * dev) +{ + device_create_file(dev, &dev_attr_class_name); + return 0; +} + +static void scsi_host_class_rm_dev(struct device * dev) +{ + device_remove_file(dev, &dev_attr_class_name); +} + +struct device_class shost_devclass = { + .name = "scsi-host", + .add_device = scsi_host_class_add_dev, + .remove_device = scsi_host_class_rm_dev, +}; + +/** + * scsi_bus_match: + * @dev: + * @dev_driver: + * + * Return value: + **/ +static int scsi_bus_match(struct device *dev, + struct device_driver *dev_driver) +{ + if (!strcmp("sg", dev_driver->name)) { + if (strstr(dev->bus_id, ":gen")) + return 1; + } else if (!strcmp("st",dev_driver->name)) { + if (strstr(dev->bus_id,":mt")) + return 1; + } else if (!strcmp("sd", dev_driver->name)) { + if ((!strstr(dev->bus_id, ":gen")) && + (!strstr(dev->bus_id, ":mt"))) { + return 1; + } + } + return 0; +} + + +static struct bus_type scsi_bus_type = { + .name = "scsi", + .match = scsi_bus_match, +}; + + +int scsi_sysfs_register(void) +{ + bus_register(&scsi_bus_type); + devclass_register(&shost_devclass); + + return 0; +} + +void scsi_sysfs_unregister(void) +{ + devclass_unregister(&shost_devclass); + bus_unregister(&scsi_bus_type); +} + +/** + * scsi_upper_driver_register - register upper level driver. + * @sdev_tp: Upper level driver to register with the scsi bus. + * + * Return value: + * 0 on Success / non-zero on Failure + **/ +int scsi_upper_driver_register(struct Scsi_Device_Template *sdev_tp) +{ + int error = 0; + + sdev_tp->scsi_driverfs_driver.bus = &scsi_bus_type; + error = driver_register(&sdev_tp->scsi_driverfs_driver); + + return error; +} + +/** + * scsi_upper_driver_unregister - unregister upper level driver + * @sdev_tp: Upper level driver to unregister with the scsi bus. + * + **/ +void scsi_upper_driver_unregister(struct Scsi_Device_Template *sdev_tp) +{ + driver_unregister(&sdev_tp->scsi_driverfs_driver); +} + + +/** + * scsi_device_type_read - copy out the SCSI type + * @dev: device to check + * @page: copy data into this area + * @count: number of bytes to copy + * @off: start at this offset in page + * + * Return: + * number of bytes written into page. + **/ +static ssize_t scsi_device_type_read(struct device *dev, char *page, + size_t count, loff_t off) +{ + struct scsi_device *sdev = to_scsi_device(dev); + const char *type; + + if (off) + return 0; + + if ((sdev->type > MAX_SCSI_DEVICE_CODE) || + (scsi_device_types[(int)sdev->type] == NULL)) + type = "Unknown"; + else + type = scsi_device_types[(int)sdev->type]; + + return snprintf(page, count, "%s\n", type); +} + +/* + * Create dev_attr_type. This is different from the dev_attr_type in scsi + * upper level drivers. + */ +static DEVICE_ATTR(type,S_IRUGO,scsi_device_type_read,NULL); + +/** + * scsi_device_register - register a scsi device with the scsi bus + * @sdev: scsi_device to register + * + * Return value: + * 0 on Success / non-zero on Failure + **/ +int scsi_device_register(struct scsi_device *sdev) +{ + int error = 0; + + sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d", + sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); + sdev->sdev_driverfs_dev.parent = sdev->host->host_gendev; + sdev->sdev_driverfs_dev.bus = &scsi_bus_type; + + error = device_register(&sdev->sdev_driverfs_dev); + if (error) + return error; + + error = device_create_file(&sdev->sdev_driverfs_dev, &dev_attr_type); + if (error) + device_unregister(&sdev->sdev_driverfs_dev); + + return error; +} + +/** + * scsi_device_unregister - unregister a device from the scsi bus + * @sdev: scsi_device to unregister + **/ +void scsi_device_unregister(struct scsi_device *sdev) +{ + device_remove_file(&sdev->sdev_driverfs_dev, &dev_attr_type); + device_unregister(&sdev->sdev_driverfs_dev); +} diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index dc28d3c09dd0..0c13717669f1 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -29,8 +29,6 @@ * than the level indicated above to trigger output. */ -#define MAJOR_NR SCSI_DISK0_MAJOR - #include <linux/config.h> #include <linux/module.h> #include <linux/fs.h> @@ -57,8 +55,8 @@ /* * Remaining dev_t-handling stuff */ -#define SD_MAJORS 8 -#define SD_MAJOR(i) ((i) ? SCSI_DISK1_MAJOR-1+(i) : SCSI_DISK0_MAJOR) +#define SD_MAJORS 16 +#define SD_DISKS (SD_MAJORS << 4) /* * Time out in seconds for disks and Magneto-opticals (which are slower). @@ -77,18 +75,18 @@ struct scsi_disk { struct scsi_device *device; struct gendisk *disk; sector_t capacity; /* size in 512-byte sectors */ + u32 index; u8 media_present; u8 write_prot; unsigned WCE : 1; /* state of disk WCE bit */ unsigned RCD : 1; /* state of disk RCD bit */ }; -static int sd_nr_dev; /* XXX(hch) bad hack, we want a bitmap instead */ static LIST_HEAD(sd_devlist); static spinlock_t sd_devlist_lock = SPIN_LOCK_UNLOCKED; -static int check_scsidisk_media_change(struct gendisk *); -static int sd_revalidate(struct gendisk *); +static unsigned long sd_index_bits[SD_DISKS / BITS_PER_LONG]; +static spinlock_t sd_index_lock = SPIN_LOCK_UNLOCKED; static void sd_init_onedisk(struct scsi_disk * sdkp, struct gendisk *disk); static void sd_rw_intr(struct scsi_cmnd * SCpnt); @@ -105,13 +103,30 @@ static struct Scsi_Device_Template sd_template = { .module = THIS_MODULE, .list = LIST_HEAD_INIT(sd_template.list), .name = "disk", - .tag = "sd", .scsi_type = TYPE_DISK, .attach = sd_attach, .detach = sd_detach, .init_command = sd_init_command, + .scsi_driverfs_driver = { + .name = "sd", + }, }; +static int sd_major(int major_idx) +{ + switch (major_idx) { + case 0: + return SCSI_DISK0_MAJOR; + case 1 ... 7: + return SCSI_DISK1_MAJOR + major_idx - 1; + case 8 ... 15: + return SCSI_DISK8_MAJOR + major_idx; + default: + BUG(); + return 0; /* shut up gcc */ + } +} + static struct scsi_disk *sd_find_by_sdev(Scsi_Device *sd) { struct scsi_disk *sdkp; @@ -148,91 +163,6 @@ static inline struct scsi_disk *scsi_disk(struct gendisk *disk) } /** - * sd_ioctl - process an ioctl - * @inode: only i_rdev member may be used - * @filp: only f_mode and f_flags may be used - * @cmd: ioctl command number - * @arg: this is third argument given to ioctl(2) system call. - * Often contains a pointer. - * - * Returns 0 if successful (some ioctls return postive numbers on - * success as well). Returns a negated errno value in case of error. - * - * Note: most ioctls are forward onto the block subsystem or further - * down in the scsi subsytem. - **/ -static int sd_ioctl(struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long arg) -{ - struct block_device *bdev = inode->i_bdev; - struct gendisk *disk = bdev->bd_disk; - struct scsi_disk *sdkp = scsi_disk(disk); - struct scsi_device *sdp = sdkp->device; - sector_t capacity = sdkp->capacity; - struct Scsi_Host *host; - int diskinfo[4]; - int error; - - SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n", - disk->disk_name, cmd)); - if (!sdp) - return -ENODEV; - /* - * If we are in the middle of error recovery, don't let anyone - * else try and use this device. Also, if error recovery fails, it - * may try and take the device offline, in which case all further - * access to the device is prohibited. - */ - - if (!scsi_block_when_processing_errors(sdp)) - return -ENODEV; - - error = scsi_cmd_ioctl(bdev, cmd, arg); - if (error != -ENOTTY) - return error; - - switch (cmd) { - case HDIO_GETGEO: /* Return BIOS disk parameters */ - { - struct hd_geometry *loc = (struct hd_geometry *)arg; - - if (!loc) - return -EINVAL; - - host = sdp->host; - - /* default to most commonly used values */ - - diskinfo[0] = 0x40; /* 1 << 6 */ - diskinfo[1] = 0x20; /* 1 << 5 */ - diskinfo[2] = sdkp->capacity >> 11; - - /* override with calculated, extended default, - or driver values */ - - if (host->hostt->bios_param) { - host->hostt->bios_param(sdp, bdev, - capacity, diskinfo); - } else - scsicam_bios_param(bdev, capacity, diskinfo); - - if (put_user(diskinfo[0], &loc->heads)) - return -EFAULT; - if (put_user(diskinfo[1], &loc->sectors)) - return -EFAULT; - if (put_user(diskinfo[2], &loc->cylinders)) - return -EFAULT; - if (put_user((unsigned)get_start_sect(bdev), - (unsigned long *)&loc->start)) - return -EFAULT; - return 0; - } - default: - return scsi_ioctl(sdp, cmd, (void *)arg); - } -} - -/** * sd_init_command - build a scsi (read or write) command from * information in the request structure. * @SCpnt: pointer to mid-level's per scsi command structure that @@ -434,68 +364,61 @@ static int sd_open(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; struct scsi_disk *sdkp = scsi_disk(disk); - struct scsi_device * sdp = sdkp->device; - int retval = -ENXIO; + struct scsi_device *sdev = sdkp->device; + int retval; SCSI_LOG_HLQUEUE(3, printk("sd_open: disk=%s\n", disk->disk_name)); - if (!sdkp) - return -ENXIO; /* No such device */ + retval = scsi_device_get(sdev); + if (retval) + return retval; /* * If the device is in error recovery, wait until it is done. * If the device is offline, then disallow any access to it. */ - if (!scsi_block_when_processing_errors(sdp)) - return -ENXIO; - /* - * The following code can sleep. - * Module unloading must be prevented - */ - if(!try_module_get(sdp->host->hostt->module)) - return -ENOMEM; - sdp->access_count++; + retval = -ENXIO; + if (!scsi_block_when_processing_errors(sdev)) + goto error_out; - if (sdp->removable) { + if (sdev->removable) { check_disk_change(inode->i_bdev); /* * If the drive is empty, just let the open fail. */ - if ((!sdkp->media_present) && !(filp->f_flags & O_NDELAY)) { - retval = -ENOMEDIUM; + retval = -ENOMEDIUM; + if ((!sdkp->media_present) && !(filp->f_flags & O_NDELAY)) goto error_out; - } /* * Similarly, if the device has the write protect tab set, * have the open fail if the user expects to be able to write * to the thing. */ - if ((sdkp->write_prot) && (filp->f_mode & FMODE_WRITE)) { - retval = -EROFS; + retval = -EROFS; + if ((sdkp->write_prot) && (filp->f_mode & FMODE_WRITE)) goto error_out; - } } + /* - * It is possible that the disk changing stuff resulted in the device - * being taken offline. If this is the case, report this to the user, - * and don't pretend that the open actually succeeded. + * It is possible that the disk changing stuff resulted in + * the device being taken offline. If this is the case, + * report this to the user, and don't pretend that the + * open actually succeeded. */ - if (!sdp->online) { + retval = -ENXIO; + if (!sdev->online) goto error_out; - } - if (sdp->removable) - if (sdp->access_count==1) - if (scsi_block_when_processing_errors(sdp)) - scsi_set_medium_removal(sdp, SCSI_REMOVAL_PREVENT); + if (sdev->removable && sdev->access_count == 1) + if (scsi_block_when_processing_errors(sdev)) + scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT); return 0; error_out: - sdp->access_count--; - module_put(sdp->host->hostt->module); + scsi_device_put(sdev); return retval; } @@ -513,36 +436,189 @@ error_out: static int sd_release(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct scsi_disk *sdkp = scsi_disk(disk); - struct scsi_device *sdp = sdkp->device; + struct scsi_device *sdev = scsi_disk(disk)->device; SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name)); - if (!sdp) - return -ENODEV; /* open uses ENXIO ?? */ - /* ... and what if there are packets in flight and this close() - * is followed by a "rmmod sd_mod" */ + if (sdev->removable && sdev->access_count == 1) + if (scsi_block_when_processing_errors(sdev)) + scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW); - sdp->access_count--; + /* + * XXX and what if there are packets in flight and this close() + * XXX is followed by a "rmmod sd_mod"? + */ + scsi_device_put(sdev); + return 0; +} - if (sdp->removable) { - if (!sdp->access_count) - if (scsi_block_when_processing_errors(sdp)) - scsi_set_medium_removal(sdp, SCSI_REMOVAL_ALLOW); - } - module_put(sdp->host->hostt->module); +static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry *loc) +{ + struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk); + struct scsi_device *sdp = sdkp->device; + struct Scsi_Host *host = sdp->host; + int diskinfo[4]; + /* default to most commonly used values */ + diskinfo[0] = 0x40; /* 1 << 6 */ + diskinfo[1] = 0x20; /* 1 << 5 */ + diskinfo[2] = sdkp->capacity >> 11; + + /* override with calculated, extended default, or driver values */ + if (host->hostt->bios_param) + host->hostt->bios_param(sdp, bdev, sdkp->capacity, diskinfo); + else + scsicam_bios_param(bdev, sdkp->capacity, diskinfo); + + if (put_user(diskinfo[0], &loc->heads)) + return -EFAULT; + if (put_user(diskinfo[1], &loc->sectors)) + return -EFAULT; + if (put_user(diskinfo[2], &loc->cylinders)) + return -EFAULT; + if (put_user((unsigned)get_start_sect(bdev), + (unsigned long *)&loc->start)) + return -EFAULT; return 0; } -static struct block_device_operations sd_fops = +/** + * sd_ioctl - process an ioctl + * @inode: only i_rdev/i_bdev members may be used + * @filp: only f_mode and f_flags may be used + * @cmd: ioctl command number + * @arg: this is third argument given to ioctl(2) system call. + * Often contains a pointer. + * + * Returns 0 if successful (some ioctls return postive numbers on + * success as well). Returns a negated errno value in case of error. + * + * Note: most ioctls are forward onto the block subsystem or further + * down in the scsi subsytem. + **/ +static int sd_ioctl(struct inode * inode, struct file * filp, + unsigned int cmd, unsigned long arg) +{ + struct block_device *bdev = inode->i_bdev; + struct gendisk *disk = bdev->bd_disk; + struct scsi_device *sdp = scsi_disk(disk)->device; + int error; + + SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n", + disk->disk_name, cmd)); + + /* + * If we are in the middle of error recovery, don't let anyone + * else try and use this device. Also, if error recovery fails, it + * may try and take the device offline, in which case all further + * access to the device is prohibited. + */ + if (!scsi_block_when_processing_errors(sdp)) + return -ENODEV; + + if (cmd == HDIO_GETGEO) { + if (!arg) + return -EINVAL; + return sd_hdio_getgeo(bdev, (struct hd_geometry *)arg); + } + + error = scsi_cmd_ioctl(bdev, cmd, arg); + if (error != -ENOTTY) + return error; + return scsi_ioctl(sdp, cmd, (void *)arg); +} + +static void set_media_not_present(struct scsi_disk *sdkp) +{ + sdkp->media_present = 0; + sdkp->capacity = 0; + sdkp->device->changed = 1; +} + +/** + * sd_media_changed - check if our medium changed + * @disk: kernel device descriptor + * + * Returns 0 if not applicable or no change; 1 if change + * + * Note: this function is invoked from the block subsystem. + **/ +static int sd_media_changed(struct gendisk *disk) { - .owner = THIS_MODULE, - .open = sd_open, - .release = sd_release, - .ioctl = sd_ioctl, - .media_changed = check_scsidisk_media_change, - .revalidate_disk= sd_revalidate + struct scsi_disk *sdkp = scsi_disk(disk); + struct scsi_device *sdp = sdkp->device; + int retval; + + SCSI_LOG_HLQUEUE(3, printk("sd_media_changed: disk=%s\n", + disk->disk_name)); + + if (!sdp->removable) + return 0; + + /* + * If the device is offline, don't send any commands - just pretend as + * if the command failed. If the device ever comes back online, we + * can deal with it then. It is only because of unrecoverable errors + * that we would ever take a device offline in the first place. + */ + if (!sdp->online) + goto not_present; + + /* + * Using TEST_UNIT_READY enables differentiation between drive with + * no cartridge loaded - NOT READY, drive with changed cartridge - + * UNIT ATTENTION, or with same cartridge - GOOD STATUS. + * + * Drives that auto spin down. eg iomega jaz 1G, will be started + * by sd_spinup_disk() from sd_init_onedisk(), which happens whenever + * sd_revalidate() is called. + */ + retval = -ENODEV; + if (scsi_block_when_processing_errors(sdp)) + retval = scsi_ioctl(sdp, SCSI_IOCTL_TEST_UNIT_READY, NULL); + + /* + * Unable to test, unit probably not ready. This usually + * means there is no disc in the drive. Mark as changed, + * and we will figure it out later once the drive is + * available again. + */ + if (retval) + goto not_present; + + /* + * For removable scsi disk we have to recognise the presence + * of a disk in the drive. This is kept in the struct scsi_disk + * struct and tested at open ! Daniel Roche (dan@lectra.fr) + */ + sdkp->media_present = 1; + + retval = sdp->changed; + sdp->changed = 0; + + return retval; + +not_present: + set_media_not_present(sdkp); + return 1; +} + +static int sd_revalidate_disk(struct gendisk *disk) +{ + struct scsi_disk *sdkp = scsi_disk(disk); + + sd_init_onedisk(sdkp, disk); + set_capacity(disk, sdkp->capacity); + return 0; +} + +static struct block_device_operations sd_fops = { + .owner = THIS_MODULE, + .open = sd_open, + .release = sd_release, + .ioctl = sd_ioctl, + .media_changed = sd_media_changed, + .revalidate_disk = sd_revalidate_disk, }; /** @@ -647,99 +723,20 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) scsi_io_completion(SCpnt, good_sectors, block_sectors); } -static void -sd_set_media_not_present(struct scsi_disk *sdkp) { - sdkp->media_present = 0; - sdkp->capacity = 0; - sdkp->device->changed = 1; -} - -/** - * check_scsidisk_media_change - self descriptive - * @full_dev: kernel device descriptor (kdev_t) - * - * Returns 0 if not applicable or no change; 1 if change - * - * Note: this function is invoked from the block subsystem. - **/ -static int check_scsidisk_media_change(struct gendisk *disk) +static int media_not_present(struct scsi_disk *sdkp, struct scsi_request *srp) { - struct scsi_disk *sdkp = scsi_disk(disk); - struct scsi_device *sdp = sdkp->device; - int retval; - int flag = 0; /* <<<< what is this for?? */ - - SCSI_LOG_HLQUEUE(3, printk("check_scsidisk_media_change: " - "disk=%s\n", disk->disk_name)); - if (!sdp) { - printk(KERN_ERR "check_scsidisk_media_change: disk=%s, " - "invalid device\n", disk->disk_name); + if (!srp->sr_result) return 0; - } - if (!sdp->removable) + if (!(driver_byte(srp->sr_result) & DRIVER_SENSE)) + return 0; + if (srp->sr_sense_buffer[2] != NOT_READY && + srp->sr_sense_buffer[2] != UNIT_ATTENTION) + return 0; + if (srp->sr_sense_buffer[12] != 0x3A) /* medium not present */ return 0; - /* - * If the device is offline, don't send any commands - just pretend as - * if the command failed. If the device ever comes back online, we - * can deal with it then. It is only because of unrecoverable errors - * that we would ever take a device offline in the first place. - */ - if (sdp->online == FALSE) { - sd_set_media_not_present(sdkp); - return 1; /* This will force a flush, if called from - * check_disk_change */ - } - - /* Using TEST_UNIT_READY enables differentiation between drive with - * no cartridge loaded - NOT READY, drive with changed cartridge - - * UNIT ATTENTION, or with same cartridge - GOOD STATUS. - * - * Drives that auto spin down. eg iomega jaz 1G, will be started - * by sd_spinup_disk() from sd_init_onedisk(), which happens whenever - * sd_revalidate() is called. - */ - retval = -ENODEV; - if (scsi_block_when_processing_errors(sdp)) - retval = scsi_ioctl(sdp, SCSI_IOCTL_TEST_UNIT_READY, NULL); - - if (retval) { /* Unable to test, unit probably not ready. - * This usually means there is no disc in the - * drive. Mark as changed, and we will figure - * it out later once the drive is available - * again. */ - - sd_set_media_not_present(sdkp); - return 1; /* This will force a flush, if called from - * check_disk_change */ - } - /* - * For removable scsi disk we have to recognise the presence - * of a disk in the drive. This is kept in the struct scsi_disk - * struct and tested at open ! Daniel Roche ( dan@lectra.fr ) - */ - - sdkp->media_present = 1; - - retval = sdp->changed; - if (!flag) - sdp->changed = 0; - return retval; -} - -static int -sd_media_not_present(struct scsi_disk *sdkp, struct scsi_request *SRpnt) { - int the_result = SRpnt->sr_result; - - if (the_result != 0 - && (driver_byte(the_result) & DRIVER_SENSE) != 0 - && (SRpnt->sr_sense_buffer[2] == NOT_READY || - SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION) - && SRpnt->sr_sense_buffer[12] == 0x3A /* medium not present */) { - sd_set_media_not_present(sdkp); - return 1; - } - return 0; + set_media_not_present(sdkp); + return 1; } /* @@ -783,7 +780,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname, * any media in it, don't bother with any of the rest of * this crap. */ - if (sd_media_not_present(sdkp, SRpnt)) + if (media_not_present(sdkp, SRpnt)) return; /* Look for devices that return NOT_READY. @@ -926,7 +923,7 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname, scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer, 8, SD_TIMEOUT, SD_MAX_RETRIES); - if (sd_media_not_present(sdkp, SRpnt)) + if (media_not_present(sdkp, SRpnt)) return; the_result = SRpnt->sr_result; @@ -1175,19 +1172,22 @@ sd_init_onedisk(struct scsi_disk * sdkp, struct gendisk *disk) **/ static int sd_attach(struct scsi_device * sdp) { - struct scsi_disk *sdkp = NULL; /* shut up lame gcc warning */ - int dsk_nr; + struct scsi_disk *sdkp; struct gendisk *gd; + u32 index; + int error; if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD)) - return 0; + return 1; SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n", sdp->host->host_no, sdp->channel, sdp->id, sdp->lun)); - if (scsi_slave_attach(sdp)) + error = scsi_slave_attach(sdp); + if (error) goto out; + error = -ENOMEM; sdkp = kmalloc(sizeof(*sdkp), GFP_KERNEL); if (!sdkp) goto out_detach; @@ -1196,28 +1196,33 @@ static int sd_attach(struct scsi_device * sdp) if (!gd) goto out_free; - /* - * XXX This doesn't make us better than the previous code in the - * XXX end (not worse either, though..). - * XXX To properly support hotplugging we should have a bitmap and - * XXX use find_first_zero_bit on it. This will happen at the - * XXX same time template->nr_* goes away. --hch - */ - dsk_nr = sd_nr_dev++; + spin_lock(&sd_index_lock); + index = find_first_zero_bit(sd_index_bits, SD_DISKS); + if (index == SD_DISKS) { + spin_unlock(&sd_index_lock); + error = -EBUSY; + goto out_put; + } + __set_bit(index, sd_index_bits); + spin_unlock(&sd_index_lock); sdkp->device = sdp; sdkp->driver = &sd_template; sdkp->disk = gd; + sdkp->index = index; gd->de = sdp->de; - gd->major = SD_MAJOR(dsk_nr>>4); - gd->first_minor = (dsk_nr & 15)<<4; + gd->major = sd_major(index >> 4); + gd->first_minor = (index & 15) << 4; gd->minors = 16; gd->fops = &sd_fops; - if (dsk_nr > 26) - sprintf(gd->disk_name, "sd%c%c",'a'+dsk_nr/26-1,'a'+dsk_nr%26); - else - sprintf(gd->disk_name, "sd%c",'a'+dsk_nr%26); + + if (index > 26) { + sprintf(gd->disk_name, "sd%c%c", + 'a' + index/26-1,'a' + index % 26); + } else { + sprintf(gd->disk_name, "sd%c", 'a' + index % 26); + } sd_init_onedisk(sdkp, gd); @@ -1239,24 +1244,14 @@ static int sd_attach(struct scsi_device * sdp) return 0; +out_put: + put_disk(gd); out_free: kfree(sdkp); out_detach: scsi_slave_detach(sdp); out: - return 1; -} - -static int sd_revalidate(struct gendisk *disk) -{ - struct scsi_disk *sdkp = scsi_disk(disk); - - if (!sdkp->device) - return -ENODEV; - - sd_init_onedisk(sdkp, disk); - set_capacity(disk, sdkp->capacity); - return 0; + return error; } /** @@ -1292,7 +1287,11 @@ static void sd_detach(struct scsi_device * sdp) sd_devlist_remove(sdkp); del_gendisk(sdkp->disk); scsi_slave_detach(sdp); - sd_nr_dev--; + + spin_lock(&sd_index_lock); + clear_bit(sdkp->index, sd_index_bits); + spin_unlock(&sd_index_lock); + put_disk(sdkp->disk); kfree(sdkp); } @@ -1310,10 +1309,10 @@ static int __init init_sd(void) SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n")); for (i = 0; i < SD_MAJORS; i++) { - if (register_blkdev(SD_MAJOR(i), "sd", &sd_fops)) + if (register_blkdev(sd_major(i), "sd", &sd_fops)) printk(KERN_NOTICE "Unable to get major %d for SCSI disk\n", - SD_MAJOR(i)); + sd_major(i)); else majors++; } @@ -1342,8 +1341,7 @@ static void __exit exit_sd(void) unregister_reboot_notifier(&sd_notifier_block); scsi_unregister_device(&sd_template); for (i = 0; i < SD_MAJORS; i++) - unregister_blkdev(SD_MAJOR(i), "sd"); - driver_unregister(&sd_template.scsi_driverfs_driver); + unregister_blkdev(sd_major(i), "sd"); } /* diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 0a0a6e9ade97..6445396e187f 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -122,10 +122,12 @@ static struct Scsi_Device_Template sg_template = { .module = THIS_MODULE, .list = LIST_HEAD_INIT(sg_template.list), .name = "generic", - .tag = "sg", .scsi_type = 0xff, .attach = sg_attach, - .detach = sg_detach + .detach = sg_detach, + .scsi_driverfs_driver = { + .name = "sg", + }, }; typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */ @@ -259,9 +261,9 @@ sg_open(struct inode *inode, struct file *filp) /* This driver's module count bumped by fops_get in <linux/fs.h> */ /* Prevent the device driver from vanishing while we sleep */ - if (!try_module_get(sdp->device->host->hostt->module)) - return -ENXIO; - sdp->device->access_count++; + retval = scsi_device_get(sdp->device); + if (retval) + return retval; if (!((flags & O_NONBLOCK) || scsi_block_when_processing_errors(sdp->device))) { @@ -314,8 +316,7 @@ sg_open(struct inode *inode, struct file *filp) return 0; error_out: - sdp->device->access_count--; - module_put(sdp->device->host->hostt->module); + scsi_device_put(sdp->device); return retval; } @@ -332,8 +333,7 @@ sg_release(struct inode *inode, struct file *filp) sg_fasync(-1, filp, 0); /* remove filp from async notification list */ if (0 == sg_remove_sfp(sdp, sfp)) { /* Returns 1 when sdp gone */ if (!sdp->detached) { - sdp->device->access_count--; - module_put(sdp->device->host->hostt->module); + scsi_device_put(sdp->device); } sdp->exclude = 0; wake_up_interruptible(&sdp->o_excl_wait); @@ -1296,8 +1296,7 @@ sg_cmd_done(Scsi_Cmnd * SCpnt) if (NULL == sfp->headrp) { SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n")); if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */ - sdp->device->access_count--; - module_put(sdp->device->host->hostt->module); + scsi_device_put(sdp->device); } sfp = NULL; } @@ -1372,15 +1371,19 @@ static DEVICE_ATTR(type,S_IRUGO,sg_device_type_read,NULL); static int sg_attach(Scsi_Device * scsidp) { - struct gendisk *disk = alloc_disk(1); + struct gendisk *disk; Sg_device *sdp = NULL; unsigned long iflags; - int k; + int k, error; + disk = alloc_disk(1); if (!disk) - return 1; - if (scsi_slave_attach(scsidp)) - return 1; + return -ENOMEM; + + error = scsi_slave_attach(scsidp); + if (error) + goto out_put; + write_lock_irqsave(&sg_dev_arr_lock, iflags); if (sg_nr_dev >= sg_dev_max) { /* try to resize */ Sg_device **tmp_da; @@ -1392,9 +1395,8 @@ sg_attach(Scsi_Device * scsidp) if (NULL == tmp_da) { printk(KERN_ERR "sg_attach: device array cannot be resized\n"); - put_disk(disk); - scsi_slave_detach(scsidp); - return 1; + error = -ENOMEM; + goto out_detach; } write_lock_irqsave(&sg_dev_arr_lock, iflags); memset(tmp_da, 0, tmp_dev_max * sizeof (Sg_device *)); @@ -1418,9 +1420,8 @@ find_empty_slot: scsidp->lun, scsidp->type, SG_MAX_DEVS_MASK); if (NULL != sdp) vfree((char *) sdp); - put_disk(disk); - scsi_slave_detach(scsidp); - return 1; + error = -ENODEV; + goto out_detach; } if (k < sg_dev_max) { if (NULL == sdp) { @@ -1435,9 +1436,8 @@ find_empty_slot: if (NULL == sdp) { write_unlock_irqrestore(&sg_dev_arr_lock, iflags); printk(KERN_ERR "sg_attach: Sg_device cannot be allocated\n"); - put_disk(disk); - scsi_slave_detach(scsidp); - return 1; + error = -ENOMEM; + goto out_detach; } SCSI_LOG_TIMEOUT(3, printk("sg_attach: dev=%d \n", k)); @@ -1462,7 +1462,7 @@ find_empty_slot: sprintf(sdp->sg_driverfs_dev.name, "%sgeneric", scsidp->sdev_driverfs_dev.name); sdp->sg_driverfs_dev.parent = &scsidp->sdev_driverfs_dev; - sdp->sg_driverfs_dev.bus = &scsi_driverfs_bus_type; + sdp->sg_driverfs_dev.bus = scsidp->sdev_driverfs_dev.bus; sg_nr_dev++; sg_dev_arr[k] = sdp; @@ -1490,6 +1490,12 @@ find_empty_slot: scsidp->lun, scsidp->type); } return 0; + +out_detach: + scsi_slave_detach(scsidp); +out_put: + put_disk(disk); + return error; } static void @@ -1521,8 +1527,7 @@ sg_detach(Scsi_Device * scsidp) sg_finish_rem_req(srp); } if (sfp->closed) { - sdp->device->access_count--; - module_put(sdp->device->host->hostt->module); + scsi_device_put(sdp->device); __sg_remove_sfp(sdp, sfp); } else { delay = 1; @@ -2510,8 +2515,7 @@ sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp) /* MOD_INC's to inhibit unloading sg and associated adapter driver */ /* only bump the access_count if we actually succeeded in * throwing another counter on the host module */ - if(try_module_get(sdp->device->host->hostt->module)) - sdp->device->access_count++; + scsi_device_get(sdp->device); /* XXX: retval ignored? */ sfp->closed = 1; /* flag dirty state on this fd */ SCSI_LOG_TIMEOUT(1, printk("sg_remove_sfp: worrisome, %d writes pending\n", dirty)); diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 63c011c53476..de5b0d5cb2d2 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -32,8 +32,6 @@ * check resource allocation in sr_init and some cleanups */ -#define MAJOR_NR SCSI_CDROM_MAJOR - #include <linux/module.h> #include <linux/fs.h> #include <linux/kernel.h> @@ -57,6 +55,9 @@ MODULE_PARM(xa_test, "i"); /* see sr_ioctl.c */ + +#define SR_DISKS (1 << KDEV_MINOR_BITS) + #define MAX_RETRIES 3 #define SR_TIMEOUT (30 * HZ) #define SR_CAPABILITIES \ @@ -73,18 +74,24 @@ static struct Scsi_Device_Template sr_template = { .module = THIS_MODULE, .list = LIST_HEAD_INIT(sr_template.list), .name = "cdrom", - .tag = "sr", .scsi_type = TYPE_ROM, .attach = sr_attach, .detach = sr_detach, - .init_command = sr_init_command + .init_command = sr_init_command, + .scsi_driverfs_driver = { + .name = "sr", + }, }; -static int sr_nr_dev; /* XXX(hch) bad hack, we want a bitmap instead */ static LIST_HEAD(sr_devlist); static spinlock_t sr_devlist_lock = SPIN_LOCK_UNLOCKED; +static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; +static spinlock_t sr_index_lock = SPIN_LOCK_UNLOCKED; + static int sr_open(struct cdrom_device_info *, int); +static void sr_release(struct cdrom_device_info *); + static void get_sectorsize(struct scsi_cd *); static void get_capabilities(struct scsi_cd *); @@ -122,16 +129,6 @@ static inline void sr_devlist_remove(Scsi_CD *cd) spin_unlock(&sr_devlist_lock); } -static void sr_release(struct cdrom_device_info *cdi) -{ - struct scsi_cd *cd = cdi->handle; - - if (cd->device->sector_size > 2048) - sr_set_blocklength(cd, 2048); - cd->device->access_count--; - module_put(cd->device->host->hostt->module); -} - static struct cdrom_device_ops sr_dops = { .open = sr_open, .release = sr_release, @@ -458,43 +455,59 @@ struct block_device_operations sr_bdops = static int sr_open(struct cdrom_device_info *cdi, int purpose) { struct scsi_cd *cd = cdi->handle; + struct scsi_device *sdev = cd->device; + int retval; - if (!cd->device) - return -ENXIO; /* No such device */ + retval = scsi_device_get(sdev); + if (retval) + return retval; + /* * If the device is in error recovery, wait until it is done. * If the device is offline, then disallow any access to it. */ - if (!scsi_block_when_processing_errors(cd->device)) { - return -ENXIO; - } - if(!try_module_get(cd->device->host->hostt->module)) - return -ENXIO; - cd->device->access_count++; + retval = -ENXIO; + if (!scsi_block_when_processing_errors(sdev)) + goto error_out; - /* If this device did not have media in the drive at boot time, then + /* + * If this device did not have media in the drive at boot time, then * we would have been unable to get the sector size. Check to see if * this is the case, and try again. */ - if (cd->needs_sector_size) get_sectorsize(cd); - return 0; + +error_out: + scsi_device_put(sdev); + return retval; +} + +static void sr_release(struct cdrom_device_info *cdi) +{ + struct scsi_cd *cd = cdi->handle; + + if (cd->device->sector_size > 2048) + sr_set_blocklength(cd, 2048); + + scsi_device_put(cd->device); } static int sr_attach(struct scsi_device *sdev) { struct gendisk *disk; struct scsi_cd *cd; - int minor; + int minor, error; if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM) return 1; - if (scsi_slave_attach(sdev)) - return 1; + error = scsi_slave_attach(sdev); + if (error) + return error; + error = -ENOMEM; cd = kmalloc(sizeof(*cd), GFP_KERNEL); if (!cd) goto fail; @@ -504,16 +517,17 @@ static int sr_attach(struct scsi_device *sdev) if (!disk) goto fail_free; - /* - * XXX This doesn't make us better than the previous code in the - * XXX end (not worse either, though..). - * XXX To properly support hotplugging we should have a bitmap and - * XXX use find_first_zero_bit on it. This will happen at the - * XXX same time template->nr_* goes away. --hch - */ - minor = sr_nr_dev++; + spin_lock(&sr_index_lock); + minor = find_first_zero_bit(sr_index_bits, SR_DISKS); + if (minor == SR_DISKS) { + spin_unlock(&sr_index_lock); + error = -EBUSY; + goto fail_put; + } + __set_bit(minor, sr_index_bits); + spin_unlock(&sr_index_lock); - disk->major = MAJOR_NR; + disk->major = SCSI_CDROM_MAJOR; disk->first_minor = minor; sprintf(disk->disk_name, "sr%d", minor); disk->fops = &sr_bdops; @@ -560,11 +574,13 @@ static int sr_attach(struct scsi_device *sdev) sdev->id, sdev->lun); return 0; +fail_put: + put_disk(disk); fail_free: kfree(cd); fail: scsi_slave_detach(sdev); - return 1; + return error; } @@ -792,13 +808,15 @@ static void sr_detach(struct scsi_device * SDp) return; sr_devlist_remove(cd); + scsi_slave_detach(SDp); del_gendisk(cd->disk); - put_disk(cd->disk); - unregister_cdrom(&cd->cdi); - scsi_slave_detach(SDp); - sr_nr_dev--; + spin_lock(&sr_index_lock); + clear_bit(cd->disk->first_minor, sr_index_bits); + spin_unlock(&sr_index_lock); + put_disk(cd->disk); + unregister_cdrom(&cd->cdi); kfree(cd); } @@ -806,7 +824,7 @@ static int __init init_sr(void) { int rc; - rc = register_blkdev(MAJOR_NR, "sr", &sr_bdops); + rc = register_blkdev(SCSI_CDROM_MAJOR, "sr", &sr_bdops); if (rc) return rc; return scsi_register_device(&sr_template); @@ -815,7 +833,7 @@ static int __init init_sr(void) static void __exit exit_sr(void) { scsi_unregister_device(&sr_template); - unregister_blkdev(MAJOR_NR, "sr"); + unregister_blkdev(SCSI_CDROM_MAJOR, "sr"); } module_init(init_sr); diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 2a74fb7d0595..a00fe0330698 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -176,10 +176,12 @@ static struct Scsi_Device_Template st_template = { .module = THIS_MODULE, .list = LIST_HEAD_INIT(st_template.list), .name = "tape", - .tag = "st", .scsi_type = TYPE_TAPE, .attach = st_attach, - .detach = st_detach + .detach = st_detach, + .scsi_driverfs_driver = { + .name = "st", + }, }; static int st_compression(Scsi_Tape *, int); @@ -991,9 +993,9 @@ static int st_open(struct inode *inode, struct file *filp) DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); ) return (-EBUSY); } - if(!try_module_get(STp->device->host->hostt->module)) + + if(!scsi_device_get(STp->device)) return (-ENXIO); - STp->device->access_count++; STp->in_use = 1; write_unlock(&st_dev_arr_lock); STp->rew_at_close = STp->autorew_dev = (minor(inode->i_rdev) & 0x80) == 0; @@ -1038,8 +1040,7 @@ static int st_open(struct inode *inode, struct file *filp) err_out: normalize_buffer(STp->buffer); STp->in_use = 0; - STp->device->access_count--; - module_put(STp->device->host->hostt->module); + scsi_device_put(STp->device); return retval; } @@ -1172,8 +1173,7 @@ static int st_release(struct inode *inode, struct file *filp) write_lock(&st_dev_arr_lock); STp->in_use = 0; write_unlock(&st_dev_arr_lock); - STp->device->access_count--; - module_put(STp->device->host->hostt->module); + scsi_device_put(STp->device); return result; } @@ -3826,7 +3826,7 @@ static int st_attach(Scsi_Device * SDp) sprintf(tpnt->driverfs_dev_r[mode].name, "%s%s", SDp->sdev_driverfs_dev.name, name); tpnt->driverfs_dev_r[mode].parent = &SDp->sdev_driverfs_dev; - tpnt->driverfs_dev_r[mode].bus = &scsi_driverfs_bus_type; + tpnt->driverfs_dev_r[mode].bus = SDp->sdev_driverfs_dev.bus; tpnt->driverfs_dev_r[mode].driver_data = (void *)(long)__mkdev(SCSI_TAPE_MAJOR, dev_num + (mode << 5)); device_register(&tpnt->driverfs_dev_r[mode]); @@ -3845,7 +3845,7 @@ static int st_attach(Scsi_Device * SDp) sprintf(tpnt->driverfs_dev_n[mode].name, "%s%s", SDp->sdev_driverfs_dev.name, name); tpnt->driverfs_dev_n[mode].parent= &SDp->sdev_driverfs_dev; - tpnt->driverfs_dev_n[mode].bus = &scsi_driverfs_bus_type; + tpnt->driverfs_dev_n[mode].bus = SDp->sdev_driverfs_dev.bus; tpnt->driverfs_dev_n[mode].driver_data = (void *)(long)__mkdev(SCSI_TAPE_MAJOR, dev_num + (mode << 5) + 128); device_register(&tpnt->driverfs_dev_n[mode]); diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 16951465bff1..a1f70113a338 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -517,7 +517,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) unsigned char save_lcr, save_mcr; unsigned long flags; - if (!up->port.iobase && !up->port.membase) + if (!up->port.iobase && !up->port.mapbase && !up->port.membase) return; DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%08lx): ", @@ -1031,7 +1031,7 @@ static int serial_link_irq_chain(struct uart_8250_port *up) ret = request_irq(up->port.irq, serial8250_interrupt, irq_flags, "serial", i); - if (ret) + if (ret < 0) serial_do_unlink(i, up); } @@ -1623,7 +1623,7 @@ static int serial8250_request_port(struct uart_port *port) if (up->port.flags & UPF_RESOURCES) { if (up->port.type == PORT_RSA) { ret = serial8250_request_rsa_resource(up, &res_rsa); - if (ret) + if (ret < 0) return ret; } @@ -1641,7 +1641,7 @@ static int serial8250_request_port(struct uart_port *port) ret = -ENOMEM; } - if (ret) { + if (ret < 0) { if (res_rsa) release_resource(res_rsa); if (res) @@ -1671,11 +1671,11 @@ static void serial8250_config_port(struct uart_port *port, int flags) */ if (up->port.flags & UPF_RESOURCES) { ret = serial8250_request_std_resource(up, &res_std); - if (ret) + if (ret < 0) return; ret = serial8250_request_rsa_resource(up, &res_rsa); - if (ret) + if (ret < 0) probeflags &= ~PROBE_RSA; } else { probeflags &= ~PROBE_RSA; @@ -1950,6 +1950,7 @@ static int __register_serial(struct serial_struct *req, int line) port.regshift = req->iomem_reg_shift; port.iotype = req->io_type; port.flags = req->flags | UPF_BOOT_AUTOCONF; + port.mapbase = req->iomap_base; port.line = line; if (share_irqs) @@ -2029,11 +2030,10 @@ static int __init serial8250_init(void) spin_lock_init(&irq_lists[i].lock); ret = uart_register_driver(&serial8250_reg); - if (ret) - return ret; + if (ret >= 0) + serial8250_register_ports(&serial8250_reg); - serial8250_register_ports(&serial8250_reg); - return 0; + return ret; } static void __exit serial8250_exit(void) diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 44b178e2d1e4..30fc603e1152 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -176,6 +176,7 @@ get_pci_port(struct pci_dev *dev, struct pci_board *board, return 0; } req->io_type = SERIAL_IO_MEM; + req->iomap_base = port; req->iomem_base = ioremap(port, board->uart_offset); if (req->iomem_base == NULL) return -ENOMEM; @@ -262,12 +263,14 @@ static int __devinit pci_plx9050_fn(struct pci_dev *dev, int enable) * interface chip and different configuration methods: * - 10x cards have control registers in IO and/or memory space; * - 20x cards have control registers in standard PCI configuration space. + * + * Note: some SIIG cards are probed by the parport_serial object. */ #define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc) #define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8) -static int __devinit pci_siig10x_fn(struct pci_dev *dev, int enable) +int pci_siig10x_fn(struct pci_dev *dev, int enable) { u16 data, *p; @@ -295,10 +298,12 @@ static int __devinit pci_siig10x_fn(struct pci_dev *dev, int enable) return 0; } +EXPORT_SYMBOL(pci_siig10x_fn); + #define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc) #define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc) -static int __devinit pci_siig20x_fn(struct pci_dev *dev, int enable) +int pci_siig20x_fn(struct pci_dev *dev, int enable) { u8 data; @@ -318,6 +323,8 @@ static int __devinit pci_siig20x_fn(struct pci_dev *dev, int enable) return 0; } +EXPORT_SYMBOL(pci_siig20x_fn); + /* Added for EKF Intel i960 serial boards */ static int __devinit pci_inteli960ni_fn(struct pci_dev *dev, int enable) { diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 2629e7620807..27a1da37eec1 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -4,7 +4,7 @@ # $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $ # -export-objs := core.o 8250.o suncore.o +export-objs := core.o 8250.o 8250_pci.o suncore.o serial-8250-y := serial-8250-$(CONFIG_GSC) += 8250_gsc.o diff --git a/drivers/serial/core.c b/drivers/serial/core.c index 2229e6d938c4..118e92152fd6 100644 --- a/drivers/serial/core.c +++ b/drivers/serial/core.c @@ -135,20 +135,6 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) #define uart_set_mctrl(port,set) uart_update_mctrl(port,set,0) #define uart_clear_mctrl(port,clear) uart_update_mctrl(port,0,clear) -static inline void uart_update_altspeed(struct uart_info *info) -{ - unsigned int flags = info->port->flags & UPF_SPD_MASK; - - if (flags == UPF_SPD_HI) - info->tty->alt_speed = 57600; - if (flags == UPF_SPD_VHI) - info->tty->alt_speed = 115200; - if (flags == UPF_SPD_SHI) - info->tty->alt_speed = 230400; - if (flags == UPF_SPD_WARP) - info->tty->alt_speed = 460800; -} - /* * Startup the port. This will be called once per open. All calls * will be serialised by the global port semaphore. @@ -167,10 +153,8 @@ static int uart_startup(struct uart_info *info, int init_hw) * once we have successfully opened the port. Also set * up the tty->alt_speed kludge */ - if (info->tty) { + if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); - uart_update_altspeed(info); - } if (port->type == PORT_UNKNOWN) return 0; @@ -276,43 +260,20 @@ static void uart_shutdown(struct uart_info *info) info->flags &= ~UIF_INITIALIZED; } -static inline -unsigned int uart_calculate_quot(struct uart_info *info, unsigned int baud) -{ - struct uart_port *port = info->port; - unsigned int quot; - - /* Special case: B0 rate */ - if (baud == 0) - baud = 9600; - - /* Old HI/VHI/custom speed handling */ - if (baud == 38400 && - ((port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)) - quot = info->state->custom_divisor; - else - quot = port->uartclk / (16 * baud); - - return quot; -} - -static void -uart_change_speed(struct uart_info *info, struct termios *old_termios) +/** + * uart_update_timeout - update per-port FIFO timeout. + * @port: uart_port structure describing the port. + * @cflag: termios cflag value + * @quot: uart clock divisor quotient + * + * Set the port FIFO timeout value. The @cflag value should + * reflect the actual hardware settings. + */ +void +uart_update_timeout(struct uart_port *port, unsigned int cflag, + unsigned int quot) { - struct uart_port *port = info->port; - unsigned int quot, cflag, bits, try; - - /* - * If we have no tty, termios, or the port does not exist, - * then we can't set the parameters for this port. - */ - if (!info->tty || !info->tty->termios || port->type == PORT_UNKNOWN) - return; - - /* - * Set flags based on termios cflag - */ - cflag = info->tty->termios->c_cflag; + unsigned int bits; /* byte size and parity */ switch (cflag & CSIZE) { @@ -335,12 +296,105 @@ uart_change_speed(struct uart_info *info, struct termios *old_termios) if (cflag & PARENB) bits++; + /* + * The total number of bits to be transmitted in the fifo. + */ + bits = bits * port->fifosize; + + /* + * Figure the timeout to send the above number of bits. + * Add .02 seconds of slop + */ + port->timeout = (HZ * bits) / (port->uartclk / (16 * quot)) + HZ/50; +} + +EXPORT_SYMBOL(uart_update_timeout); + +/** + * uart_get_baud_rate - return baud rate for a particular port + * @port: uart_port structure describing the port in question. + * @termios: desired termios settings. + * + * Decode the termios structure into a numeric baud rate, + * taking account of the magic 38400 baud rate (with spd_* + * flags), and mapping the %B0 rate to 9600 baud. + */ +unsigned int +uart_get_baud_rate(struct uart_port *port, struct termios *termios) +{ + unsigned int baud = tty_termios_baud_rate(termios); + + /* + * The spd_hi, spd_vhi, spd_shi, spd_warp kludge... + * Die! Die! Die! + */ + if (baud == 38400) { + unsigned int flags = port->flags & UPF_SPD_MASK; + + if (flags == UPF_SPD_HI) + baud = 57600; + if (flags == UPF_SPD_VHI) + baud = 115200; + if (flags == UPF_SPD_SHI) + baud = 230400; + if (flags == UPF_SPD_WARP) + baud = 460800; + } + + /* + * Special case: B0 rate. + */ + if (baud == 0) + baud = 9600; + + return baud; +} + +EXPORT_SYMBOL(uart_get_baud_rate); + +static inline unsigned int +uart_calculate_quot(struct uart_port *port, unsigned int baud) +{ + unsigned int quot; + + /* + * Old custom speed handling. + */ + if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) + quot = port->custom_divisor; + else + quot = port->uartclk / (16 * baud); + + return quot; +} + +/** + * uart_get_divisor - return uart clock divisor + * @port: uart_port structure describing the port. + * @termios: desired termios settings + * @old_termios: the original port settings, or NULL + * + * Calculate the uart clock divisor for the port. If the + * divisor is invalid, try the old termios setting. If + * the divisor is still invalid, we try 9600 baud. + * + * Update the @termios structure to reflect the baud rate + * we're actually going to be using. + * + * If 9600 baud fails, we return a zero divisor. + */ +unsigned int +uart_get_divisor(struct uart_port *port, struct termios *termios, + struct termios *old_termios) +{ + unsigned int quot, try; + for (try = 0; try < 3; try ++) { unsigned int baud; /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(info->tty); - quot = uart_calculate_quot(info, baud); + baud = uart_get_baud_rate(port, termios); + quot = uart_calculate_quot(port, baud); if (quot) break; @@ -348,10 +402,9 @@ uart_change_speed(struct uart_info *info, struct termios *old_termios) * Oops, the quotient was zero. Try again with * the old baud rate if possible. */ - info->tty->termios->c_cflag &= ~CBAUD; + termios->c_cflag &= ~CBAUD; if (old_termios) { - info->tty->termios->c_cflag |= - (old_termios->c_cflag & CBAUD); + termios->c_cflag |= old_termios->c_cflag & CBAUD; old_termios = NULL; continue; } @@ -360,30 +413,48 @@ uart_change_speed(struct uart_info *info, struct termios *old_termios) * As a last resort, if the quotient is zero, * default to 9600 bps */ - info->tty->termios->c_cflag |= B9600; + termios->c_cflag |= B9600; } + return quot; +} + +EXPORT_SYMBOL(uart_get_divisor); + +static void +uart_change_speed(struct uart_info *info, struct termios *old_termios) +{ + struct tty_struct *tty = info->tty; + struct uart_port *port = info->port; + struct termios *termios; + unsigned int quot; + /* - * The total number of bits to be transmitted in the fifo. + * If we have no tty, termios, or the port does not exist, + * then we can't set the parameters for this port. */ - bits = bits * port->fifosize; + if (!tty || !tty->termios || port->type == PORT_UNKNOWN) + return; + + termios = tty->termios; /* - * Figure the timeout to send the above number of bits. - * Add .02 seconds of slop + * Set flags based on termios cflag */ - port->timeout = (HZ * bits) / (port->uartclk / (16 * quot)) + HZ/50; - - if (cflag & CRTSCTS) + if (termios->c_cflag & CRTSCTS) info->flags |= UIF_CTS_FLOW; else info->flags &= ~UIF_CTS_FLOW; - if (cflag & CLOCAL) + + if (termios->c_cflag & CLOCAL) info->flags &= ~UIF_CHECK_CD; else info->flags |= UIF_CHECK_CD; - port->ops->change_speed(port, cflag, info->tty->termios->c_iflag, quot); + quot = uart_get_divisor(port, termios, old_termios); + uart_update_timeout(port, termios->c_cflag, quot); + + port->ops->change_speed(port, termios->c_cflag, termios->c_iflag, quot); } static inline void @@ -597,7 +668,7 @@ static int uart_get_info(struct uart_info *info, struct serial_struct *retinfo) tmp.baud_base = port->uartclk / 16; tmp.close_delay = state->close_delay; tmp.closing_wait = state->closing_wait; - tmp.custom_divisor = state->custom_divisor; + tmp.custom_divisor = port->custom_divisor; tmp.hub6 = port->hub6; tmp.io_type = port->iotype; tmp.iomem_reg_shift = port->regshift; @@ -652,7 +723,7 @@ uart_set_info(struct uart_info *info, struct serial_struct *newinfo) new_serial.type != port->type; old_flags = port->flags; - old_custom_divisor = state->custom_divisor; + old_custom_divisor = port->custom_divisor; if (!capable(CAP_SYS_ADMIN)) { retval = -EPERM; @@ -665,7 +736,7 @@ uart_set_info(struct uart_info *info, struct serial_struct *newinfo) goto exit; port->flags = ((port->flags & ~UPF_USR_MASK) | (new_serial.flags & UPF_USR_MASK)); - state->custom_divisor = new_serial.custom_divisor; + port->custom_divisor = new_serial.custom_divisor; goto check_and_exit; } @@ -757,7 +828,7 @@ uart_set_info(struct uart_info *info, struct serial_struct *newinfo) port->irq = new_serial.irq; port->uartclk = new_serial.baud_base * 16; port->flags = new_serial.flags & UPF_FLAGS; - state->custom_divisor = new_serial.custom_divisor; + port->custom_divisor = new_serial.custom_divisor; state->close_delay = new_serial.close_delay * HZ / 100; state->closing_wait = new_serial.closing_wait * HZ / 100; port->fifosize = new_serial.xmit_fifo_size; @@ -769,10 +840,8 @@ uart_set_info(struct uart_info *info, struct serial_struct *newinfo) goto exit; if (info->flags & UIF_INITIALIZED) { if (((old_flags ^ port->flags) & UPF_SPD_MASK) || - old_custom_divisor != state->custom_divisor) { - uart_update_altspeed(info); + old_custom_divisor != port->custom_divisor) uart_change_speed(info, NULL); - } } else retval = uart_startup(info, 1); exit: @@ -1540,8 +1609,9 @@ static int uart_open(struct tty_struct *tty, struct file *filp) * Any failures from here onwards should not touch the count. */ tty->driver_data = info; + tty->low_latency = (info->port->flags & UPF_LOW_LATENCY) ? 1 : 0; + tty->alt_speed = 0; info->tty = tty; - info->tty->low_latency = (info->port->flags & UPF_LOW_LATENCY) ? 1 : 0; /* * If the port is in the middle of closing, bail out now. @@ -2009,7 +2079,7 @@ __uart_register_port(struct uart_driver *drv, struct uart_state *state, /* * If there isn't a port here, don't do anything further. */ - if (!port->iobase && !port->mapbase) + if (!port->iobase && !port->mapbase && !port->membase) return; /* @@ -2405,17 +2475,23 @@ int uart_register_port(struct uart_driver *drv, struct uart_port *port) goto out; } - state->port->iobase = port->iobase; - state->port->membase = port->membase; - state->port->irq = port->irq; - state->port->uartclk = port->uartclk; - state->port->fifosize = port->fifosize; - state->port->regshift = port->regshift; - state->port->iotype = port->iotype; - state->port->flags = port->flags; - state->port->line = state - drv->state; - - __uart_register_port(drv, state, state->port); + /* + * If the port is already initialised, don't touch it. + */ + if (state->port->type == PORT_UNKNOWN) { + state->port->iobase = port->iobase; + state->port->membase = port->membase; + state->port->irq = port->irq; + state->port->uartclk = port->uartclk; + state->port->fifosize = port->fifosize; + state->port->regshift = port->regshift; + state->port->iotype = port->iotype; + state->port->flags = port->flags; + state->port->line = state - drv->state; + state->port->mapbase = port->mapbase; + + __uart_register_port(drv, state, state->port); + } ret = state->port->line; } else diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index ae682b076171..cdac597766c1 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -867,6 +867,13 @@ config FB_TX3912 Say Y here to enable kernel support for the on-board framebuffer. +config FB_68328 + bool "Motorola 68328 native frame buffer support" + depends on (M68328 || M68EZ328 || M68VZ328) + help + Say Y here if you want to support the built-in frame buffer of + the Motorola 68328 CPU family. + config FB_VIRTUAL tristate "Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)" depends on FB && EXPERIMENTAL diff --git a/fs/fat/inode.c b/fs/fat/inode.c index b852c46cdbb2..6ad055bba0b0 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -205,7 +205,7 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt) seq_printf(m, ",uid=%d", opts->fs_uid); if (opts->fs_gid != 0) seq_printf(m, ",gid=%d", opts->fs_gid); - seq_printf(m, ",umask=%04o", opts->fs_umask); + seq_printf(m, ",fmask=%04o", opts->fs_fmask); seq_printf(m, ",dmask=%04o", opts->fs_dmask); if (sbi->nls_disk) seq_printf(m, ",codepage=%s", sbi->nls_disk->charset); @@ -267,7 +267,7 @@ static int parse_options(char *options, int is_vfat, int *debug, opts->fs_uid = current->uid; opts->fs_gid = current->gid; - opts->fs_umask = opts->fs_dmask = current->fs->umask; + opts->fs_fmask = opts->fs_dmask = current->fs->umask; opts->codepage = 0; opts->iocharset = NULL; if (is_vfat) @@ -333,7 +333,15 @@ static int parse_options(char *options, int is_vfat, int *debug, else if (!strcmp(this_char,"umask")) { if (!value || !*value) ret = 0; else { - opts->fs_umask = simple_strtoul(value,&value,8); + opts->fs_fmask = opts->fs_dmask = + simple_strtoul(value,&value,8); + if (*value) ret = 0; + } + } + else if (!strcmp(this_char,"fmask")) { + if (!value || !*value) ret = 0; + else { + opts->fs_fmask = simple_strtoul(value,&value,8); if (*value) ret = 0; } } @@ -1119,7 +1127,7 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) ((sbi->options.showexec && !is_exec(de->ext)) ? S_IRUGO|S_IWUGO : S_IRWXUGO) - & ~sbi->options.fs_umask) | S_IFREG; + & ~sbi->options.fs_fmask) | S_IFREG; MSDOS_I(inode)->i_start = CF_LE_W(de->start); if (sbi->fat_bits == 32) { MSDOS_I(inode)->i_start |= @@ -1253,7 +1261,7 @@ int fat_notify_change(struct dentry * dentry, struct iattr * attr) if (S_ISDIR(inode->i_mode)) mask = sbi->options.fs_dmask; else - mask = sbi->options.fs_umask; + mask = sbi->options.fs_fmask; inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask); out: unlock_kernel(); diff --git a/fs/fcntl.c b/fs/fcntl.c index 041b84ffd0ce..fae2022ada19 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -75,8 +75,8 @@ static int expand_files(struct files_struct *files, int nr) /* * locate_fd finds a free file descriptor in the open_fds fdset, - * expanding the fd arrays if necessary. The files write lock will be - * held on exit to ensure that the fd can be entered atomically. + * expanding the fd arrays if necessary. Must be called with the + * file_lock held for write. */ static int locate_fd(struct files_struct *files, @@ -86,8 +86,6 @@ static int locate_fd(struct files_struct *files, int error; int start; - write_lock(&files->file_lock); - error = -EINVAL; if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur) goto out; @@ -131,30 +129,24 @@ out: return error; } -static inline void allocate_fd(struct files_struct *files, - struct file *file, int fd) -{ - FD_SET(fd, files->open_fds); - FD_CLR(fd, files->close_on_exec); - write_unlock(&files->file_lock); - fd_install(fd, file); -} - static int dupfd(struct file *file, int start) { struct files_struct * files = current->files; - int ret; + int fd; - ret = locate_fd(files, file, start); - if (ret < 0) - goto out_putf; - allocate_fd(files, file, ret); - return ret; + write_lock(&files->file_lock); + fd = locate_fd(files, file, start); + if (fd >= 0) { + FD_SET(fd, files->open_fds); + FD_CLR(fd, files->close_on_exec); + write_unlock(&files->file_lock); + fd_install(fd, file); + } else { + write_unlock(&files->file_lock); + fput(file); + } -out_putf: - write_unlock(&files->file_lock); - fput(file); - return ret; + return fd; } asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd) diff --git a/fs/locks.c b/fs/locks.c index 04600003a4a0..36dd6a6242e1 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1412,7 +1412,6 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock *l) inode = filp->f_dentry->d_inode; -#ifdef CONFIG_MMU /* Don't allow mandatory locks on files that may be memory mapped * and shared. */ @@ -1425,7 +1424,6 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock *l) goto out; } } -#endif error = flock_to_posix_lock(filp, file_lock, &flock); if (error) diff --git a/fs/namei.c b/fs/namei.c index 179732c79ece..4c01f3189047 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1648,7 +1648,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) error = -EBUSY; else { error = security_inode_unlink(dir, dentry); - if (error) + if (!error) error = dir->i_op->unlink(dir, dentry); } up(&dentry->d_inode->i_sem); diff --git a/fs/proc/generic.c b/fs/proc/generic.c index bab86d71ed00..bcc4fac3f1ff 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -488,7 +488,11 @@ struct proc_dir_entry *proc_symlink(const char *name, ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL); if (ent->data) { strcpy((char*)ent->data,dest); - proc_register(parent, ent); + if (proc_register(parent, ent) < 0) { + kfree(ent->data); + kfree(ent); + ent = NULL; + } } else { kfree(ent); ent = NULL; @@ -505,7 +509,10 @@ struct proc_dir_entry *proc_mknod(const char *name, mode_t mode, ent = proc_create(&parent,name,mode,1); if (ent) { ent->rdev = rdev; - proc_register(parent, ent); + if (proc_register(parent, ent) < 0) { + kfree(ent); + ent = NULL; + } } return ent; } @@ -520,7 +527,10 @@ struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *paren ent->proc_fops = &proc_dir_operations; ent->proc_iops = &proc_dir_inode_operations; - proc_register(parent, ent); + if (proc_register(parent, ent) < 0) { + kfree(ent); + ent = NULL; + } } return ent; } @@ -549,7 +559,10 @@ struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, ent->proc_fops = &proc_dir_operations; ent->proc_iops = &proc_dir_inode_operations; } - proc_register(parent, ent); + if (proc_register(parent, ent) < 0) { + kfree(ent); + ent = NULL; + } } return ent; } diff --git a/fs/umsdos/ioctl.c b/fs/umsdos/ioctl.c index 722581c1a53f..323c2dbcccd0 100644 --- a/fs/umsdos/ioctl.c +++ b/fs/umsdos/ioctl.c @@ -430,7 +430,9 @@ new_dentry->d_parent->d_name.name, new_dentry->d_name.name); */ dir->i_sb->u.msdos_sb.options.fs_uid = data.umsdos_dirent.uid; dir->i_sb->u.msdos_sb.options.fs_gid = data.umsdos_dirent.gid; - dir->i_sb->u.msdos_sb.options.fs_umask = data.umsdos_dirent.mode; + dir->i_sb->u.msdos_sb.options.fs_fmask = + dir->i_sb->u.msdos_sb.options.fs_dmask = + data.umsdos_dirent.mode; ret = 0; } out: diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h index 0aa149a0fdc1..6e38b86a466a 100644 --- a/include/asm-i386/bitops.h +++ b/include/asm-i386/bitops.h @@ -260,6 +260,8 @@ static __inline__ int variable_test_bit(int nr, const volatile unsigned long * a constant_test_bit((nr),(addr)) : \ variable_test_bit((nr),(addr))) +#undef ADDR + /** * find_first_zero_bit - find the first zero bit in a memory region * @addr: The address to start the search at diff --git a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h index 6fee20b0ef9f..6f3a009bad64 100644 --- a/include/asm-i386/mpspec.h +++ b/include/asm-i386/mpspec.h @@ -105,6 +105,7 @@ struct mpc_config_bus #define BUSTYPE_TC "TC" #define BUSTYPE_VME "VME" #define BUSTYPE_XPRESS "XPRESS" +#define BUSTYPE_NEC98 "NEC98" struct mpc_config_ioapic { @@ -195,7 +196,8 @@ enum mp_bustype { MP_BUS_ISA = 1, MP_BUS_EISA, MP_BUS_PCI, - MP_BUS_MCA + MP_BUS_MCA, + MP_BUS_NEC98 }; extern int mp_bus_id_to_type [MAX_MP_BUSSES]; extern int mp_bus_id_to_node [MAX_MP_BUSSES]; diff --git a/include/linux/ac97_codec.h b/include/linux/ac97_codec.h index 8701d6a01164..cb5bd2b5e6ae 100644 --- a/include/linux/ac97_codec.h +++ b/include/linux/ac97_codec.h @@ -32,7 +32,7 @@ #define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */ #define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */ #define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */ -#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR DAC Rate */ +#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR ADC Rate */ #define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */ #define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */ #define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */ @@ -143,6 +143,39 @@ #define AC97_PWR_PR6 0x4000 /* HP amp powerdown */ #define AC97_PWR_PR7 0x8000 /* Modem off - if supported */ +/* extended audio ID register bit defines */ +#define AC97_EXTID_VRA 0x0001 +#define AC97_EXTID_DRA 0x0002 +#define AC97_EXTID_SPDIF 0x0004 +#define AC97_EXTID_VRM 0x0008 +#define AC97_EXTID_DSA0 0x0010 +#define AC97_EXTID_DSA1 0x0020 +#define AC97_EXTID_CDAC 0x0040 +#define AC97_EXTID_SDAC 0x0080 +#define AC97_EXTID_LDAC 0x0100 +#define AC97_EXTID_AMAP 0x0200 +#define AC97_EXTID_REV0 0x0400 +#define AC97_EXTID_REV1 0x0800 +#define AC97_EXTID_ID0 0x4000 +#define AC97_EXTID_ID1 0x8000 + +/* extended status register bit defines */ +#define AC97_EXTSTAT_VRA 0x0001 +#define AC97_EXTSTAT_DRA 0x0002 +#define AC97_EXTSTAT_SPDIF 0x0004 +#define AC97_EXTSTAT_VRM 0x0008 +#define AC97_EXTSTAT_SPSA0 0x0010 +#define AC97_EXTSTAT_SPSA1 0x0020 +#define AC97_EXTSTAT_CDAC 0x0040 +#define AC97_EXTSTAT_SDAC 0x0080 +#define AC97_EXTSTAT_LDAC 0x0100 +#define AC97_EXTSTAT_MADC 0x0200 +#define AC97_EXTSTAT_SPCV 0x0400 +#define AC97_EXTSTAT_PRI 0x0800 +#define AC97_EXTSTAT_PRJ 0x1000 +#define AC97_EXTSTAT_PRK 0x2000 +#define AC97_EXTSTAT_PRL 0x4000 + /* useful power states */ #define AC97_PWR_D0 0x0000 /* everything on */ #define AC97_PWR_D1 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4 diff --git a/include/linux/init.h b/include/linux/init.h index 52db706d0ed0..e2bf29a635bf 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -125,14 +125,6 @@ extern struct kernel_param __setup_start, __setup_end; */ #define module_exit(x) __exitcall(x); -/** - * no_module_init - code needs no initialization. - * - * The equivalent of declaring an empty init function which returns 0. - * Every module must have exactly one module_init() or no_module_init - * invocation. */ -#define no_module_init - #else /* MODULE */ /* Don't use these in modules, but some people do... */ @@ -144,11 +136,6 @@ extern struct kernel_param __setup_start, __setup_end; #define device_initcall(fn) module_init(fn) #define late_initcall(fn) module_init(fn) -/* Each module knows its own name. */ -#define __DEFINE_MODULE_NAME \ - char __module_name[] __attribute__((section(".modulename"))) = \ - __stringify(KBUILD_MODNAME) - /* These macros create a dummy inline: gcc 2.9x does not count alias as usage, hence the `unused function' warning when __init functions are declared static. We use the dummy __*_module_inline functions @@ -157,13 +144,10 @@ extern struct kernel_param __setup_start, __setup_end; /* Each module must use one module_init(), or one no_module_init */ #define module_init(initfn) \ - __DEFINE_MODULE_NAME; \ static inline initcall_t __inittest(void) \ { return initfn; } \ int __initfn(void) __attribute__((alias(#initfn))); -#define no_module_init __DEFINE_MODULE_NAME - /* This is only required if you want to be unloadable. */ #define module_exit(exitfn) \ static inline exitcall_t __exittest(void) \ diff --git a/include/linux/major.h b/include/linux/major.h index 3679c040597d..1e889952a12c 100644 --- a/include/linux/major.h +++ b/include/linux/major.h @@ -94,6 +94,14 @@ #define SCSI_DISK6_MAJOR 70 #define SCSI_DISK7_MAJOR 71 +#define SCSI_DISK8_MAJOR 128 +#define SCSI_DISK9_MAJOR 129 +#define SCSI_DISK10_MAJOR 130 +#define SCSI_DISK11_MAJOR 131 +#define SCSI_DISK12_MAJOR 132 +#define SCSI_DISK13_MAJOR 133 +#define SCSI_DISK14_MAJOR 134 +#define SCSI_DISK15_MAJOR 135 #define COMPAQ_SMART2_MAJOR 72 #define COMPAQ_SMART2_MAJOR1 73 diff --git a/include/linux/module.h b/include/linux/module.h index 927341a26c0e..0362a206ccd9 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -15,6 +15,7 @@ #include <linux/cache.h> #include <linux/kmod.h> #include <linux/elf.h> +#include <linux/stringify.h> #include <asm/module.h> #include <asm/uaccess.h> /* For struct exception_table_entry */ @@ -31,6 +32,11 @@ #define MODULE_PARM_DESC(var,desc) #define print_modules() +/* v850 toolchain uses a `_' prefix for all user symbols */ +#ifndef MODULE_SYMBOL_PREFIX +#define MODULE_SYMBOL_PREFIX "" +#endif + #define MODULE_NAME_LEN (64 - sizeof(unsigned long)) struct kernel_symbol { @@ -40,11 +46,19 @@ struct kernel_symbol #ifdef MODULE -#define MODULE_GENERIC_TABLE(gtype,name) \ -static const unsigned long __module_##gtype##_size \ - __attribute__ ((unused)) = sizeof(struct gtype##_id); \ -static const struct gtype##_id * __module_##gtype##_table \ - __attribute__ ((unused)) = name +#ifdef KBUILD_MODNAME +static const char __module_name[MODULE_NAME_LEN] __attribute__((section(".gnu.linkonce.modname"))) = \ + __stringify(KBUILD_MODNAME); +#endif + +/* For replacement modutils, use an alias not a pointer. */ +#define MODULE_GENERIC_TABLE(gtype,name) \ +static const unsigned long __module_##gtype##_size \ + __attribute__ ((unused)) = sizeof(struct gtype##_id); \ +static const struct gtype##_id * __module_##gtype##_table \ + __attribute__ ((unused)) = name; \ +extern const struct gtype##_id __mod_##gtype##_table \ + __attribute__ ((unused, alias(__stringify(name)))) /* This is magically filled in by the linker, but THIS_MODULE must be a constant so it works in initializers. */ @@ -86,13 +100,13 @@ struct exception_table /* Get/put a kernel symbol (calls must be symmetric) */ void *__symbol_get(const char *symbol); void *__symbol_get_gpl(const char *symbol); -#define symbol_get(x) ((typeof(&x))(__symbol_get(#x))) +#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) /* For every exported symbol, place a struct in the __ksymtab section */ #define EXPORT_SYMBOL(sym) \ const struct kernel_symbol __ksymtab_##sym \ __attribute__((section("__ksymtab"))) \ - = { (unsigned long)&sym, #sym } + = { (unsigned long)&sym, MODULE_SYMBOL_PREFIX #sym } #define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym) #define EXPORT_SYMBOL_GPL(sym) EXPORT_SYMBOL(sym) @@ -166,7 +180,7 @@ struct module #ifdef CONFIG_MODULE_UNLOAD void __symbol_put(const char *symbol); -#define symbol_put(x) __symbol_put(#x) +#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) void symbol_put_addr(void *addr); /* We only need protection against local interrupts. */ @@ -306,12 +320,7 @@ extern int module_dummy_usage; /* Old-style "I'll just call it init_module and it'll be run at insert". Use module_init(myroutine) instead. */ #ifdef MODULE -/* Used as "int init_module(void) { ... }". Get funky to insert modname. */ -#define init_module(voidarg) \ - __initfn(void); \ - char __module_name[] __attribute__((section(".modulename"))) = \ - __stringify(KBUILD_MODNAME); \ - int __initfn(void) +#define init_module(voidarg) __initfn(void) #define cleanup_module(voidarg) __exitfn(void) #endif diff --git a/include/linux/msdos_fs_sb.h b/include/linux/msdos_fs_sb.h index 3b84157867e9..317a02cd7c88 100644 --- a/include/linux/msdos_fs_sb.h +++ b/include/linux/msdos_fs_sb.h @@ -8,7 +8,7 @@ struct fat_mount_options { uid_t fs_uid; gid_t fs_gid; - unsigned short fs_umask; + unsigned short fs_fmask; unsigned short fs_dmask; unsigned short codepage; /* Codepage for shortname conversions */ char *iocharset; /* Charset used for filename input/display */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 30c4a9dbc855..eede29dc50ad 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -65,9 +65,9 @@ #define PCI_HEADER_TYPE_CARDBUS 2 #define PCI_BIST 0x0f /* 8 bits */ -#define PCI_BIST_CODE_MASK 0x0f /* Return result */ -#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */ -#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */ +#define PCI_BIST_CODE_MASK 0x0f /* Return result */ +#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */ +#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */ /* * Base addresses specify locations in memory or I/O space. @@ -195,6 +195,7 @@ #define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */ #define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */ #define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ +#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ #define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ #define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ #define PCI_CAP_SIZEOF 4 @@ -251,6 +252,13 @@ #define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */ #define PCI_AGP_SIZEOF 12 +/* Vital Product Data */ + +#define PCI_VPD_ADDR 2 /* Address to access (15 bits!) */ +#define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */ +#define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */ +#define PCI_VPD_DATA 4 /* 32-bits of data returned here */ + /* Slot Identification */ #define PCI_SID_ESR 2 /* Expansion Slot Register */ @@ -271,6 +279,37 @@ #define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */ #define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ +/* CompactPCI Hotswap Register */ + +#define PCI_CHSWP_CSR 2 /* Control and Status Register */ +#define PCI_CHSWP_DHA 0x01 /* Device Hiding Arm */ +#define PCI_CHSWP_EIM 0x02 /* ENUM# Signal Mask */ +#define PCI_CHSWP_PIE 0x04 /* Pending Insert or Extract */ +#define PCI_CHSWP_LOO 0x08 /* LED On / Off */ +#define PCI_CHSWP_PI 0x30 /* Programming Interface */ +#define PCI_CHSWP_EXT 0x40 /* ENUM# status - extraction */ +#define PCI_CHSWP_INS 0x80 /* ENUM# status - insertion */ + +/* PCI-X registers */ + +#define PCI_X_CMD 2 /* Modes & Features */ +#define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */ +#define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */ +#define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */ +#define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */ +#define PCI_X_DEVFN 4 /* A copy of devfn. */ +#define PCI_X_BUSNR 5 /* Bus segment number */ +#define PCI_X_STATUS 6 /* PCI-X capabilities */ +#define PCI_X_STATUS_64BIT 0x0001 /* 64-bit device */ +#define PCI_X_STATUS_133MHZ 0x0002 /* 133 MHz capable */ +#define PCI_X_STATUS_SPL_DISC 0x0004 /* Split Completion Discarded */ +#define PCI_X_STATUS_UNX_SPL 0x0008 /* Unexpected Split Completion */ +#define PCI_X_STATUS_COMPLEX 0x0010 /* Device Complexity */ +#define PCI_X_STATUS_MAX_READ 0x0060 /* Designed Maximum Memory Read Count */ +#define PCI_X_STATUS_MAX_SPLIT 0x0380 /* Design Max Outstanding Split Trans */ +#define PCI_X_STATUS_MAX_CUM 0x1c00 /* Designed Max Cumulative Read Size */ +#define PCI_X_STATUS_SPL_ERR 0x2000 /* Rcvd Split Completion Error Msg */ + /* Include the ID list */ #include <linux/pci_ids.h> diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ad768f9b5d9c..9f0ec735c051 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -485,7 +485,6 @@ #define PCI_VENDOR_ID_FD 0x1036 #define PCI_DEVICE_ID_FD_36C70 0x0000 -#define PCI_VENDOR_ID_SIS 0x1039 #define PCI_VENDOR_ID_SI 0x1039 #define PCI_DEVICE_ID_SI_5591_AGP 0x0001 #define PCI_DEVICE_ID_SI_6202 0x0002 diff --git a/include/linux/serial.h b/include/linux/serial.h index d9d93ae8ad3b..b0469a236a13 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h @@ -48,6 +48,7 @@ struct serial_struct { unsigned char *iomem_base; unsigned short iomem_reg_shift; unsigned int port_high; + unsigned long iomap_base; /* cookie passed into ioremap */ int reserved[1]; }; diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index fe25d0fa6b94..84e021607be9 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -186,6 +186,7 @@ struct uart_port { unsigned int timeout; /* character-based timeout */ unsigned int type; /* port type */ struct uart_ops *ops; + unsigned int custom_divisor; unsigned int line; /* port index */ unsigned long mapbase; /* for ioremap */ unsigned char hub6; /* this should be in the 8250 driver */ @@ -204,8 +205,6 @@ struct uart_state { #define USF_CLOSING_WAIT_INF (0) #define USF_CLOSING_WAIT_NONE (65535) - unsigned int custom_divisor; - int count; struct uart_info *info; struct uart_port *port; diff --git a/include/linux/tty.h b/include/linux/tty.h index 81c8d745f708..11b82d2c98ae 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -397,6 +397,7 @@ extern void do_SAK(struct tty_struct *tty); extern void disassociate_ctty(int priv); extern void tty_flip_buffer_push(struct tty_struct *tty); extern int tty_get_baud_rate(struct tty_struct *tty); +extern int tty_termios_baud_rate(struct termios *termios); /* n_tty.c */ extern struct tty_ldisc tty_ldisc_N_TTY; diff --git a/include/net/irda/vlsi_ir.h b/include/net/irda/vlsi_ir.h index 3ce8cd6cd1e7..32d30cbc0920 100644 --- a/include/net/irda/vlsi_ir.h +++ b/include/net/irda/vlsi_ir.h @@ -27,6 +27,26 @@ #ifndef IRDA_VLSI_FIR_H #define IRDA_VLSI_FIR_H +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,4) +#ifdef CONFIG_PROC_FS +/* PDE() introduced in 2.5.4 */ +#define PDE(inode) ((inode)->u.generic_ip) +#endif +#endif + +/* + * #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,xx) + * + * missing pci-dma api call to give streaming dma buffer back to hw + * patch floating on lkml - probably present in 2.5.26 or later + * otherwise defining it as noop is ok, since the vlsi-ir is only + * used on two oldish x86-based notebooks which are cache-coherent + */ +#define pci_dma_prep_single(dev, addr, size, direction) /* nothing */ +/* + * #endif + */ + /* ================================================================ */ /* non-standard PCI registers */ diff --git a/init/do_mounts.c b/init/do_mounts.c index c5dfb8c691bb..be86a550b984 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -920,6 +920,7 @@ static unsigned insize; /* valid bytes in inbuf */ static unsigned inptr; /* index of next byte to be processed in inbuf */ static unsigned outcnt; /* bytes in output buffer */ static int exit_code; +static int unzip_error; static long bytes_out; static int crd_infd, crd_outfd; @@ -967,13 +968,17 @@ static void __init gzip_release(void **ptr) /* =========================================================================== * Fill the input buffer. This is called only when the buffer is empty * and at least one byte is really needed. + * Returning -1 does not guarantee that gunzip() will ever return. */ static int __init fill_inbuf(void) { if (exit_code) return -1; insize = read(crd_infd, inbuf, INBUFSIZ); - if (insize == 0) return -1; + if (insize == 0) { + error("RAMDISK: ran out of compressed data\n"); + return -1; + } inptr = 1; @@ -987,10 +992,15 @@ static int __init fill_inbuf(void) static void __init flush_window(void) { ulg c = crc; /* temporary variable */ - unsigned n; + unsigned n, written; uch *in, ch; - write(crd_outfd, window, outcnt); + written = write(crd_outfd, window, outcnt); + if (written != outcnt && unzip_error == 0) { + printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %d\n", + written, outcnt, bytes_out); + unzip_error = 1; + } in = window; for (n = 0; n < outcnt; n++) { ch = *in++; @@ -1005,6 +1015,7 @@ static void __init error(char *x) { printk(KERN_ERR "%s", x); exit_code = 1; + unzip_error = 1; } static int __init crd_load(int in_fd, int out_fd) @@ -1033,6 +1044,8 @@ static int __init crd_load(int in_fd, int out_fd) } makecrc(); result = gunzip(); + if (unzip_error) + result = 1; kfree(inbuf); kfree(window); return result; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 092018c75a66..98093272d3e8 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -353,13 +353,8 @@ EXPORT_SYMBOL(generic_file_writev); EXPORT_SYMBOL(iov_shorten); /* tty routines */ -EXPORT_SYMBOL(tty_hangup); EXPORT_SYMBOL(tty_wait_until_sent); -EXPORT_SYMBOL(tty_check_change); -EXPORT_SYMBOL(tty_hung_up_p); EXPORT_SYMBOL(tty_flip_buffer_push); -EXPORT_SYMBOL(tty_get_baud_rate); -EXPORT_SYMBOL(do_SAK); /* filesystem registration */ EXPORT_SYMBOL(register_filesystem); diff --git a/kernel/module.c b/kernel/module.c index f9ee37c95dbe..a30c32e38e23 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -37,6 +37,9 @@ #define DEBUGP(fmt , a...) #endif +#define symbol_is(literal, string) \ + (strcmp(MODULE_SYMBOL_PREFIX literal, (string)) == 0) + /* List of modules, protected by module_mutex */ static DECLARE_MUTEX(module_mutex); LIST_HEAD(modules); /* FIXME: Accessed w/o lock on oops by some archs */ @@ -630,10 +633,10 @@ static int grab_private_symbols(Elf_Shdr *sechdrs, unsigned int i; for (i = 1; i < sechdrs[symbolsec].sh_size/sizeof(*sym); i++) { - if (strcmp("__initfn", strtab + sym[i].st_name) == 0) + if (symbol_is("__initfn", strtab + sym[i].st_name)) mod->init = (void *)sym[i].st_value; #ifdef CONFIG_MODULE_UNLOAD - if (strcmp("__exitfn", strtab + sym[i].st_name) == 0) + if (symbol_is("__exitfn", strtab + sym[i].st_name)) mod->exit = (void *)sym[i].st_value; #endif } @@ -770,7 +773,7 @@ static void simplify_symbols(Elf_Shdr *sechdrs, mod, &ksg); /* We fake up "__this_module" */ - if (strcmp(strtab+sym[i].st_name, "__this_module")==0) + if (symbol_is("__this_module", strtab+sym[i].st_name)) sym[i].st_value = (unsigned long)mod; } } @@ -864,8 +867,8 @@ static struct module *load_module(void *umod, /* Internal symbols */ DEBUGP("Symbol table in section %u\n", i); symindex = i; - } else if (strcmp(secstrings+sechdrs[i].sh_name, ".modulename") - == 0) { + } else if (strcmp(secstrings+sechdrs[i].sh_name, + ".gnu.linkonce.modname") == 0) { /* This module's name */ DEBUGP("Module name in section %u\n", i); modnameindex = i; @@ -892,7 +895,7 @@ static struct module *load_module(void *umod, } #ifdef CONFIG_KALLSYMS /* symbol and string tables for decoding later. */ - if (sechdrs[i].sh_type == SHT_SYMTAB || i == hdr->e_shstrndx) + if (sechdrs[i].sh_type == SHT_SYMTAB || i == strindex) sechdrs[i].sh_flags |= SHF_ALLOC; #endif #ifndef CONFIG_MODULE_UNLOAD @@ -1165,7 +1168,14 @@ static const char *get_ksymbol(struct module *mod, unsigned long *size, unsigned long *offset) { - unsigned int i, next = 0, best = 0; + unsigned int i, best = 0; + unsigned long nextval; + + /* At worse, next value is at end of module */ + if (inside_core(mod, addr)) + nextval = (unsigned long)mod->module_core+mod->core_size; + else + nextval = (unsigned long)mod->module_init+mod->init_size; /* Scan for closest preceeding symbol, and next symbol. (ELF starts real symbols at 1). */ @@ -1177,22 +1187,14 @@ static const char *get_ksymbol(struct module *mod, && mod->symtab[i].st_value > mod->symtab[best].st_value) best = i; if (mod->symtab[i].st_value > addr - && mod->symtab[i].st_value < mod->symtab[next].st_value) - next = i; + && mod->symtab[i].st_value < nextval) + nextval = mod->symtab[i].st_value; } if (!best) return NULL; - if (!next) { - /* Last symbol? It ends at the end of the module then. */ - if (inside_core(mod, addr)) - *size = mod->module_core+mod->core_size - (void*)addr; - else - *size = mod->module_init+mod->init_size - (void*)addr; - } else - *size = mod->symtab[next].st_value - addr; - + *size = nextval - mod->symtab[best].st_value; *offset = addr - mod->symtab[best].st_value; return mod->strtab + mod->symtab[best].st_name; } diff --git a/lib/zlib_deflate/deflate_syms.c b/lib/zlib_deflate/deflate_syms.c index 080fa4166f28..5985b28c8e30 100644 --- a/lib/zlib_deflate/deflate_syms.c +++ b/lib/zlib_deflate/deflate_syms.c @@ -19,5 +19,3 @@ EXPORT_SYMBOL(zlib_deflateReset); EXPORT_SYMBOL(zlib_deflateCopy); EXPORT_SYMBOL(zlib_deflateParams); MODULE_LICENSE("GPL"); - -no_module_init; diff --git a/lib/zlib_inflate/inflate_syms.c b/lib/zlib_inflate/inflate_syms.c index 7b8f309350a2..aa1b08189121 100644 --- a/lib/zlib_inflate/inflate_syms.c +++ b/lib/zlib_inflate/inflate_syms.c @@ -20,5 +20,3 @@ EXPORT_SYMBOL(zlib_inflateReset); EXPORT_SYMBOL(zlib_inflateSyncPoint); EXPORT_SYMBOL(zlib_inflateIncomp); MODULE_LICENSE("GPL"); - -no_module_init; diff --git a/mm/Makefile b/mm/Makefile index 060e761a3864..10f362c888bb 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -4,12 +4,18 @@ export-objs := shmem.o filemap.o mempool.o page_alloc.o page-writeback.o -obj-y := memory.o mmap.o filemap.o fremap.o mprotect.o mlock.o mremap.o \ - vmalloc.o slab.o bootmem.o swap.o vmscan.o page_alloc.o \ - oom_kill.o shmem.o highmem.o mempool.o msync.o mincore.o \ - readahead.o pdflush.o page-writeback.o rmap.o madvise.o \ - vcache.o truncate.o +obj-y := bootmem.o filemap.o mempool.o oom_kill.o page_alloc.o \ + page-writeback.o pdflush.o readahead.o slab.o swap.o \ + truncate.o vcache.o vmscan.o + +obj-$(CONFIG_MMU) += fremap.o highmem.o madvise.o memory.o \ + mincore.o mlock.o mmap.o mprotect.o mremap.o \ + msync.o rmap.o shmem.o vmalloc.o obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o +ifneq ($(CONFIG_MMU),y) +obj-y += nommu.o +endif + include $(TOPDIR)/Rules.make diff --git a/mm/nommu.c b/mm/nommu.c new file mode 100644 index 000000000000..687f37fff425 --- /dev/null +++ b/mm/nommu.c @@ -0,0 +1,557 @@ +/* + * linux/mm/nommu.c + * + * Replacement code for mm functions to support CPU's that don't + * have any form of memory management unit (thus no virtual memory). + * + * Copyright (c) 2000-2002 David McCullough <davidm@snapgear.com> + * Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org> + * Copyright (c) 2002 Greg Ungerer <gerg@snapgear.com> + */ + +#include <linux/mm.h> +#include <linux/mman.h> +#include <linux/swap.h> +#include <linux/smp_lock.h> +#include <linux/highmem.h> +#include <linux/pagemap.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include <linux/blkdev.h> + +#include <asm/pgalloc.h> +#include <asm/uaccess.h> +#include <asm/tlb.h> +#include <asm/tlbflush.h> + +void *high_memory; +struct page *mem_map = NULL; +unsigned long max_mapnr; +unsigned long num_physpages; +unsigned long askedalloc, realalloc; +atomic_t vm_committed_space = ATOMIC_INIT(0); + +/* + * Handle all mappings that got truncated by a "truncate()" + * system call. + * + * NOTE! We have to be ready to update the memory sharing + * between the file and the memory map for a potential last + * incomplete page. Ugly, but necessary. + */ +int vmtruncate(struct inode *inode, loff_t offset) +{ + struct address_space *mapping = inode->i_mapping; + unsigned long limit; + + if (inode->i_size < offset) + goto do_expand; + inode->i_size = offset; + + truncate_inode_pages(mapping, offset); + goto out_truncate; + +do_expand: + limit = current->rlim[RLIMIT_FSIZE].rlim_cur; + if (limit != RLIM_INFINITY && offset > limit) + goto out_sig; + if (offset > inode->i_sb->s_maxbytes) + goto out; + inode->i_size = offset; + +out_truncate: + if (inode->i_op && inode->i_op->truncate) { + lock_kernel(); + inode->i_op->truncate(inode); + unlock_kernel(); + } + return 0; +out_sig: + send_sig(SIGXFSZ, current, 0); +out: + return -EFBIG; +} + +/* + * Return the total memory allocated for this pointer, not + * just what the caller asked for. + * + * Doesn't have to be accurate, i.e. may have races. + */ +unsigned int kobjsize(const void *objp) +{ + struct page *page; + + if (!objp || !((page = virt_to_page(objp)))) + return 0; + + if (PageSlab(page)) + return ksize(objp); + + BUG_ON(page->index < 0); + BUG_ON(page->index >= MAX_ORDER); + + return (PAGE_SIZE << page->index); +} + +/* + * The nommu dodgy version :-) + */ +int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, int len, int write, int force, + struct page **pages, struct vm_area_struct **vmas) +{ + int i; + + for (i = 0; i < len; i++) { + if (pages) { + pages[i] = virt_to_page(start); + if (pages[i]) + page_cache_get(pages[i]); + } + start += PAGE_SIZE; + } + return(i); +} + +rwlock_t vmlist_lock = RW_LOCK_UNLOCKED; +struct vm_struct *vmlist; + +void vfree(void *addr) +{ + kfree(addr); +} + +void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot) +{ + /* + * kmalloc doesn't like __GFP_HIGHMEM for some reason + */ + return kmalloc(size, gfp_mask & ~__GFP_HIGHMEM); +} + +long vread(char *buf, char *addr, unsigned long count) +{ + memcpy(buf, addr, count); + return count; +} + +long vwrite(char *buf, char *addr, unsigned long count) +{ + /* Don't allow overflow */ + if ((unsigned long) addr + count < count) + count = -(unsigned long) addr; + + memcpy(addr, buf, count); + return(count); +} + +/* + * vmalloc - allocate virtually continguos memory + * + * @size: allocation size + * + * Allocate enough pages to cover @size from the page level + * allocator and map them into continguos kernel virtual space. + * + * For tight cotrol over page level allocator and protection flags + * use __vmalloc() instead. + */ +void *vmalloc(unsigned long size) +{ + return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); +} + +/* + * vmalloc_32 - allocate virtually continguos memory (32bit addressable) + * + * @size: allocation size + * + * Allocate enough 32bit PA addressable pages to cover @size from the + * page level allocator and map them into continguos kernel virtual space. + */ +void *vmalloc_32(unsigned long size) +{ + return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL); +} + +void *vmap(struct page **pages, unsigned int count) +{ + BUG(); + return NULL; +} + +void vunmap(void *addr) +{ + BUG(); +} + +/* + * sys_brk() for the most part doesn't need the global kernel + * lock, except when an application is doing something nasty + * like trying to un-brk an area that has already been mapped + * to a regular file. in this case, the unmapping will need + * to invoke file system routines that need the global lock. + */ +asmlinkage unsigned long sys_brk(unsigned long brk) +{ + struct mm_struct *mm = current->mm; + + if (brk < mm->end_code || brk < mm->start_brk || brk > mm->context.end_brk) + return mm->brk; + + if (mm->brk == brk) + return mm->brk; + + /* + * Always allow shrinking brk + */ + if (brk <= mm->brk) { + mm->brk = brk; + return brk; + } + + /* + * Ok, looks good - let it rip. + */ + return mm->brk = brk; +} + +/* + * Combine the mmap "prot" and "flags" argument into one "vm_flags" used + * internally. Essentially, translate the "PROT_xxx" and "MAP_xxx" bits + * into "VM_xxx". + */ +static inline unsigned long calc_vm_flags(unsigned long prot, unsigned long flags) +{ +#define _trans(x,bit1,bit2) \ +((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0) + + unsigned long prot_bits, flag_bits; + prot_bits = + _trans(prot, PROT_READ, VM_READ) | + _trans(prot, PROT_WRITE, VM_WRITE) | + _trans(prot, PROT_EXEC, VM_EXEC); + flag_bits = + _trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) | + _trans(flags, MAP_DENYWRITE, VM_DENYWRITE) | + _trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE); + return prot_bits | flag_bits; +#undef _trans +} + +#ifdef DEBUG +static void show_process_blocks(void) +{ + struct mm_tblock_struct * tblock, *tmp; + + printk("Process blocks %d:", current->pid); + + tmp = current->mm->context.tblock; + while (tmp) { + printk(" %p: %p", tmp, tmp->rblock); + if (tmp->rblock) + printk(" (%d @%p #%d)", kobjsize(tmp->rblock->kblock), + tmp->rblock->kblock, tmp->rblock->refcount); + if (tmp->next) + printk(" ->"); + else + printk("."); + tmp = tmp->next; + } + printk("\n"); +} +#endif /* DEBUG */ + +unsigned long do_mmap_pgoff( + struct file * file, + unsigned long addr, + unsigned long len, + unsigned long prot, + unsigned long flags, + unsigned long pgoff) +{ + void * result; + struct mm_tblock_struct * tblock; + unsigned int vm_flags; + + /* + * Get the !CONFIG_MMU specific checks done first + */ + if ((flags & MAP_SHARED) && (prot & PROT_WRITE) && (file)) { + printk("MAP_SHARED not supported (cannot write mappings to disk)\n"); + return -EINVAL; + } + + if ((prot & PROT_WRITE) && (flags & MAP_PRIVATE)) { + printk("Private writable mappings not supported\n"); + return -EINVAL; + } + + /* + * now all the standard checks + */ + if (file && (!file->f_op || !file->f_op->mmap)) + return -ENODEV; + + if (PAGE_ALIGN(len) == 0) + return addr; + + if (len > TASK_SIZE) + return -EINVAL; + + /* offset overflow? */ + if ((pgoff + (len >> PAGE_SHIFT)) < pgoff) + return -EINVAL; + + /* Do simple checking here so the lower-level routines won't have + * to. we assume access permissions have been handled by the open + * of the memory object, so we don't do any here. + */ + vm_flags = calc_vm_flags(prot,flags) /* | mm->def_flags */ | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; + + /* + * determine the object being mapped and call the appropriate + * specific mapper. + */ + if (file) { + struct vm_area_struct vma; + int error; + + if (!file->f_op) + return -ENODEV; + + vma.vm_start = addr; + vma.vm_end = addr + len; + vma.vm_flags = vm_flags; + vma.vm_pgoff = pgoff; + +#ifdef MAGIC_ROM_PTR + /* First, try simpler routine designed to give us a ROM pointer. */ + + if (file->f_op->romptr && !(prot & PROT_WRITE)) { + error = file->f_op->romptr(file, &vma); +#ifdef DEBUG + printk("romptr mmap returned %d, start 0x%.8x\n", error, + vma.vm_start); +#endif + if (!error) + return vma.vm_start; + else if (error != -ENOSYS) + return error; + } else +#endif /* MAGIC_ROM_PTR */ + /* Then try full mmap routine, which might return a RAM pointer, + or do something truly complicated. */ + + if (file->f_op->mmap) { + error = file->f_op->mmap(file, &vma); + +#ifdef DEBUG + printk("mmap mmap returned %d /%x\n", error, vma.vm_start); +#endif + if (!error) + return vma.vm_start; + else if (error != -ENOSYS) + return error; + } else + return -ENODEV; /* No mapping operations defined */ + + /* An ENOSYS error indicates that mmap isn't possible (as opposed to + tried but failed) so we'll fall through to the copy. */ + } + + tblock = (struct mm_tblock_struct *) + kmalloc(sizeof(struct mm_tblock_struct), GFP_KERNEL); + if (!tblock) { + printk("Allocation of tblock for %lu byte allocation from process %d failed\n", len, current->pid); + show_free_areas(); + return -ENOMEM; + } + + tblock->rblock = (struct mm_rblock_struct *) + kmalloc(sizeof(struct mm_rblock_struct), GFP_KERNEL); + + if (!tblock->rblock) { + printk("Allocation of rblock for %lu byte allocation from process %d failed\n", len, current->pid); + show_free_areas(); + kfree(tblock); + return -ENOMEM; + } + + result = kmalloc(len, GFP_KERNEL); + if (!result) { + printk("Allocation of length %lu from process %d failed\n", len, + current->pid); + show_free_areas(); + kfree(tblock->rblock); + kfree(tblock); + return -ENOMEM; + } + + tblock->rblock->refcount = 1; + tblock->rblock->kblock = result; + tblock->rblock->size = len; + + realalloc += kobjsize(result); + askedalloc += len; + +#ifdef WARN_ON_SLACK + if ((len+WARN_ON_SLACK) <= kobjsize(result)) + printk("Allocation of %lu bytes from process %d has %lu bytes of slack\n", len, current->pid, kobjsize(result)-len); +#endif + + if (file) { + int error; + mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); + error = file->f_op->read(file, (char *) result, len, &file->f_pos); + set_fs(old_fs); + if (error < 0) { + kfree(result); + kfree(tblock->rblock); + kfree(tblock); + return error; + } + if (error < len) + memset(result+error, '\0', len-error); + } else { + memset(result, '\0', len); + } + + realalloc += kobjsize(tblock); + askedalloc += sizeof(struct mm_tblock_struct); + + realalloc += kobjsize(tblock->rblock); + askedalloc += sizeof(struct mm_rblock_struct); + + tblock->next = current->mm->context.tblock.next; + current->mm->context.tblock.next = tblock; + +#ifdef DEBUG + printk("do_mmap:\n"); + show_process_blocks(); +#endif + + return (unsigned long)result; +} + +int do_munmap(struct mm_struct * mm, unsigned long addr, size_t len) +{ + struct mm_tblock_struct * tblock, *tmp; + +#ifdef MAGIC_ROM_PTR + /* + * For efficiency's sake, if the pointer is obviously in ROM, + * don't bother walking the lists to free it. + */ + if (is_in_rom(addr)) + return 0; +#endif + +#ifdef DEBUG + printk("do_munmap:\n"); +#endif + + tmp = &mm->context.tblock; /* dummy head */ + while ((tblock=tmp->next) && tblock->rblock && + tblock->rblock->kblock != (void*)addr) + tmp = tblock; + + if (!tblock) { + printk("munmap of non-mmaped memory by process %d (%s): %p\n", + current->pid, current->comm, (void*)addr); + return -EINVAL; + } + if (tblock->rblock) { + if (!--tblock->rblock->refcount) { + if (tblock->rblock->kblock) { + realalloc -= kobjsize(tblock->rblock->kblock); + askedalloc -= tblock->rblock->size; + kfree(tblock->rblock->kblock); + } + + realalloc -= kobjsize(tblock->rblock); + askedalloc -= sizeof(struct mm_rblock_struct); + kfree(tblock->rblock); + } + } + tmp->next = tblock->next; + realalloc -= kobjsize(tblock); + askedalloc -= sizeof(struct mm_tblock_struct); + kfree(tblock); + +#ifdef DEBUG + show_process_blocks(); +#endif + + return -EINVAL; +} + +/* Release all mmaps. */ +void exit_mmap(struct mm_struct * mm) +{ + struct mm_tblock_struct *tmp; + + if (!mm) + return; + +#ifdef DEBUG + printk("Exit_mmap:\n"); +#endif + + while((tmp = mm->context.tblock.next)) { + if (tmp->rblock) { + if (!--tmp->rblock->refcount) { + if (tmp->rblock->kblock) { + realalloc -= kobjsize(tmp->rblock->kblock); + askedalloc -= tmp->rblock->size; + kfree(tmp->rblock->kblock); + } + realalloc -= kobjsize(tmp->rblock); + askedalloc -= sizeof(struct mm_rblock_struct); + kfree(tmp->rblock); + } + tmp->rblock = 0; + } + mm->context.tblock.next = tmp->next; + realalloc -= kobjsize(tmp); + askedalloc -= sizeof(struct mm_tblock_struct); + kfree(tmp); + } + +#ifdef DEBUG + show_process_blocks(); +#endif +} + +asmlinkage long sys_munmap(unsigned long addr, size_t len) +{ + int ret; + struct mm_struct *mm = current->mm; + + down_write(&mm->mmap_sem); + ret = do_munmap(mm, addr, len); + up_write(&mm->mmap_sem); + return ret; +} + +unsigned long do_brk(unsigned long addr, unsigned long len) +{ + return -ENOMEM; +} + +struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr) +{ + return NULL; +} + +unsigned long get_unmapped_area(struct file *file, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) +{ + return -ENOMEM; +} + +void pte_chain_init(void) +{ +} diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 467925d6d6f9..8a62ade3a725 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -49,20 +49,20 @@ * require us to fill additional fields. */ static struct net_device __fake_net_device = { - hard_header_len: ETH_HLEN + .hard_header_len = ETH_HLEN }; static struct rtable __fake_rtable = { - u: { - dst: { - __refcnt: ATOMIC_INIT(1), - dev: &__fake_net_device, - path: &__fake_rtable.u.dst, - metrics: {[RTAX_MTU] 1500}, + .u = { + .dst = { + .__refcnt = ATOMIC_INIT(1), + .dev = &__fake_net_device, + .path = &__fake_rtable.u.dst, + .metrics = {[RTAX_MTU] = 1500}, } }, - rt_flags: 0 + .rt_flags = 0 }; diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index a7c5a350e6c4..499a8c9a9c99 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -281,8 +281,8 @@ static int netlink_release(struct socket *sock) skb_queue_purge(&sk->write_queue); if (nlk->pid && !nlk->groups) { - struct netlink_notify n = { protocol:sk->protocol, - pid:nlk->pid }; + struct netlink_notify n = { .protocol = sk->protocol, + .pid = nlk->pid }; notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n); } diff --git a/net/rxrpc/connection.c b/net/rxrpc/connection.c index 341e9d0ff26a..a60412d9f7bf 100644 --- a/net/rxrpc/connection.c +++ b/net/rxrpc/connection.c @@ -39,7 +39,7 @@ static void __rxrpc_conn_timeout(rxrpc_timer_t *timer) } static const struct rxrpc_timer_ops rxrpc_conn_timer_ops = { - timed_out: __rxrpc_conn_timeout, + .timed_out = __rxrpc_conn_timeout, }; /*****************************************************************************/ diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 79356c109018..6c0509d01f28 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -383,22 +383,22 @@ static struct Qdisc_class_ops prio_class_ops = struct Qdisc_ops prio_qdisc_ops = { - next: NULL, - cl_ops: &prio_class_ops, - id: "prio", - priv_size: sizeof(struct prio_sched_data), - - enqueue: prio_enqueue, - dequeue: prio_dequeue, - requeue: prio_requeue, - drop: prio_drop, - - init: prio_init, - reset: prio_reset, - destroy: prio_destroy, - change: prio_tune, - - dump: prio_dump, + .next = NULL, + .cl_ops = &prio_class_ops, + .id = "prio", + .priv_size = sizeof(struct prio_sched_data), + + .enqueue = prio_enqueue, + .dequeue = prio_dequeue, + .requeue = prio_requeue, + .drop = prio_drop, + + .init = prio_init, + .reset = prio_reset, + .destroy = prio_destroy, + .change = prio_tune, + + .dump = prio_dump, }; #ifdef MODULE diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 95026d841a1c..c8e1528aae55 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -124,14 +124,14 @@ depfile = $(subst $(comma),_,$(@D)/.$(@F).d) # than one module. In that case KBUILD_MODNAME will be set to foo_bar, # where foo and bar are the name of the modules. basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -modname_flags = -DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname))) +modname_flags = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname)))) c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \ $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \ $(basename_flags) $(modname_flags) $(export_flags) # Finds the multi-part object the current object will be linked into -modname-multi = $(subst $(space),_,$(sort $(foreach m,$(multi-used),\ - $(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=))))) +modname-multi = $(sort $(foreach m,$(multi-used),\ + $(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=)))) # Shipped files # =========================================================================== diff --git a/scripts/kallsyms b/scripts/kallsyms index db057d0974dc..72a51e0dbdd7 100644 --- a/scripts/kallsyms +++ b/scripts/kallsyms @@ -31,7 +31,7 @@ encode_symbols() } # FIXME: Use System.map as input, and regenerate each time in Makefile. -$NM $1 | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > kallsyms.map +$NM -n $1 | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > kallsyms.map encode_symbols kallsyms.map > kallsyms.c $CC $CFLAGS -c -o $2 kallsyms.c diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c index 70565e1095e0..70ff03c4c1c2 100644 --- a/sound/arm/sa11xx-uda1341.c +++ b/sound/arm/sa11xx-uda1341.c @@ -555,11 +555,11 @@ static snd_pcm_hardware_t snd_sa11xx_uda1341_capture = SNDRV_PCM_RATE_KNOT), .rate_min = 8000, .rate_max = 48000, - .channels_min: = 2, - .channels_max: = 2, - .buffer_bytes_max: = 16380, - .period_bytes_min: = 64, - .period_bytes_max: = 8190, /* <= MAX_DMA_SIZE from ams/arch-sa1100/dma.h */ + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 16380, + .period_bytes_min = 64, + .period_bytes_max = 8190, /* <= MAX_DMA_SIZE from ams/arch-sa1100/dma.h */ .periods_min = 2, .periods_max = 255, .fifo_size = 0, diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c index d743c7787f06..62aa94ef6df2 100644 --- a/sound/oss/ac97_codec.c +++ b/sound/oss/ac97_codec.c @@ -52,6 +52,8 @@ #include <linux/ac97_codec.h> #include <asm/uaccess.h> +#define CODEC_ID_BUFSZ 14 + static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel); static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel, unsigned int left, unsigned int right); @@ -113,7 +115,7 @@ static const struct { {0x41445340, "Analog Devices AD1881", &null_ops}, {0x41445348, "Analog Devices AD1881A", &null_ops}, {0x41445360, "Analog Devices AD1885", &default_ops}, - {0x41445361, "Analog Devices AD1886", &default_ops}, + {0x41445361, "Analog Devices AD1886", &ad1886_ops}, {0x41445460, "Analog Devices AD1885", &default_ops}, {0x41445461, "Analog Devices AD1886", &ad1886_ops}, {0x414B4D00, "Asahi Kasei AK4540", &null_ops}, @@ -654,6 +656,29 @@ int ac97_read_proc (char *page, char **start, off_t off, } /** + * codec_id - Turn id1/id2 into a PnP string + * @id1: Vendor ID1 + * @id2: Vendor ID2 + * @buf: CODEC_ID_BUFSZ byte buffer + * + * Fills buf with a zero terminated PnP ident string for the id1/id2 + * pair. For convenience the return is the passed in buffer pointer. + */ + +static char *codec_id(u16 id1, u16 id2, char *buf) +{ + if(id1&0x8080) { + snprintf(buf, CODEC_ID_BUFSZ, "0x%04x:0x%04x", id1, id2); + } else { + buf[0] = (id1 >> 8); + buf[1] = (id1 & 0xFF); + buf[2] = (id2 >> 8); + snprintf(buf+3, CODEC_ID_BUFSZ - 3, "%d", id2&0xFF); + } + return buf; +} + +/** * ac97_probe_codec - Initialize and setup AC97-compatible codec * @codec: (in/out) Kernel info for a single AC97 codec * @@ -681,6 +706,7 @@ int ac97_probe_codec(struct ac97_codec *codec) u16 id1, id2; u16 audio, modem; int i; + char cidbuf[CODEC_ID_BUFSZ]; /* probing AC97 codec, AC97 2.0 says that bit 15 of register 0x00 (reset) should * be read zero. @@ -698,13 +724,16 @@ int ac97_probe_codec(struct ac97_codec *codec) if ((audio = codec->codec_read(codec, AC97_RESET)) & 0x8000) { printk(KERN_ERR "ac97_codec: %s ac97 codec not present\n", - codec->id ? "Secondary" : "Primary"); + (codec->id & 0x2) ? (codec->id&1 ? "4th" : "Tertiary") + : (codec->id&1 ? "Secondary": "Primary")); return 0; } /* probe for Modem Codec */ codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L); - modem = codec->codec_read(codec, AC97_EXTENDED_MODEM_ID); + modem = codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1; + modem |= (audio&2); + audio &= ~2; codec->name = NULL; codec->codec_ops = &null_ops; @@ -721,9 +750,9 @@ int ac97_probe_codec(struct ac97_codec *codec) } if (codec->name == NULL) codec->name = "Unknown"; - printk(KERN_INFO "ac97_codec: AC97 %s codec, id: 0x%04x:" - "0x%04x (%s)\n", audio ? "Audio" : (modem ? "Modem" : ""), - id1, id2, codec->name); + printk(KERN_INFO "ac97_codec: AC97 %s codec, id: %s (%s)\n", + modem ? "Modem" : (audio ? "Audio" : ""), + codec_id(id1, id2, cidbuf), codec->name); return ac97_init_mixer(codec); } @@ -746,10 +775,10 @@ static int ac97_init_mixer(struct ac97_codec *codec) /* detect bit resolution */ codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0x2020); - if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x1f1f) - codec->bit_resolution = 5; - else + if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x2020) codec->bit_resolution = 6; + else + codec->bit_resolution = 5; /* generic OSS to AC97 wrapper */ codec->read_mixer = ac97_read_mixer; @@ -917,7 +946,7 @@ static int tritech_maestro_init(struct ac97_codec * codec) /* * Presario700 workaround - * for Jack Sense/SPDIF Register misetting causing + * for Jack Sense/SPDIF Register mis-setting causing * no audible output * by Santiago Nullo 04/05/2002 */ diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c index 06686f1faeef..0302eb372914 100644 --- a/sound/oss/i810_audio.c +++ b/sound/oss/i810_audio.c @@ -65,29 +65,41 @@ * If you need to force a specific rate set the clocking= option * * This driver is cursed. (Ben LaHaise) + * + * + * ICH 4 caveats + * + * The ICH4 has the feature, that the codec ID doesn't have to be + * congruent with the IO connection. + * + * Therefore, from driver version 0.23 on, there is a "codec ID" <-> + * "IO register base offset" mapping (card->ac97_id_map) field. + * + * Juergen "George" Sawinski (jsaw) */ #include <linux/module.h> #include <linux/version.h> #include <linux/string.h> -#include <linux/interrupt.h> +#include <linux/ctype.h> #include <linux/ioport.h> -#include <linux/wait.h> +#include <linux/sched.h> #include <linux/delay.h> #include <linux/sound.h> #include <linux/slab.h> #include <linux/soundcard.h> #include <linux/pci.h> +#include <linux/interrupt.h> +#include <asm/io.h> +#include <asm/dma.h> #include <linux/init.h> #include <linux/poll.h> #include <linux/spinlock.h> #include <linux/smp_lock.h> #include <linux/ac97_codec.h> #include <linux/wrapper.h> - -#include <asm/io.h> -#include <asm/page.h> #include <asm/uaccess.h> +#include <asm/hardirq.h> #ifndef PCI_DEVICE_ID_INTEL_82801 #define PCI_DEVICE_ID_INTEL_82801 0x2415 @@ -113,9 +125,18 @@ #ifndef PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO #define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO 0x01b1 #endif +#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO +#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a +#endif +#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO +#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da +#endif #ifndef PCI_DEVICE_ID_AMD_768_AUDIO #define PCI_DEVICE_ID_AMD_768_AUDIO 0x7445 #endif +#ifndef PCI_DEVICE_ID_AMD_8111_AC97 +#define PCI_DEVICE_ID_AMD_8111_AC97 0x746d +#endif static int ftsodell=0; static int strict_clocking=0; @@ -126,6 +147,7 @@ static int spdif_locked=0; //#define DEBUG2 //#define DEBUG_INTERRUPTS //#define DEBUG_MMAP +//#define DEBUG_MMIO #define ADC_RUNNING 1 #define DAC_RUNNING 2 @@ -168,6 +190,11 @@ struct i810_channel * each dma engine has controlling registers. These goofy * names are from the datasheet, but make it easy to write * code while leafing through it. + * + * ICH4 has 6 dma engines, pcm in, pcm out, mic, pcm in 2, + * mic in 2, s/pdif. Of special interest is the fact that + * the upper 3 DMA engines on the ICH4 *must* be accessed + * via mmio access instead of pio access. */ #define ENUM_ENGINE(PRE,DIG) \ @@ -192,6 +219,14 @@ enum { CAS = 0x34 /* Codec Write Semaphore Register */ }; +ENUM_ENGINE(MC2,4); /* Mic In 2 */ +ENUM_ENGINE(PI2,5); /* PCM In 2 */ +ENUM_ENGINE(SP,6); /* S/PDIF */ + +enum { + SDM = 0x80 /* SDATA_IN Map Register */ +}; + /* interrupts for a dma engine */ #define DMA_INT_FIFO (1<<4) /* fifo under/over flow */ #define DMA_INT_COMPLETE (1<<3) /* buffer read/write complete and ioc set */ @@ -211,8 +246,7 @@ enum { #define INT_GPI (1<<0) #define INT_MASK (INT_SEC|INT_PRI|INT_MC|INT_PO|INT_PI|INT_MO|INT_NI|INT_GPI) - -#define DRIVER_VERSION "0.21" +#define DRIVER_VERSION "0.24" /* magic numbers to protect our data structures */ #define I810_CARD_MAGIC 0x5072696E /* "Prin" */ @@ -221,7 +255,7 @@ enum { #define NR_HW_CH 3 /* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */ -#define NR_AC97 2 +#define NR_AC97 4 /* Please note that an 8bit mono stream is not valid on this card, you must have a 16bit */ /* stream at a minimum for this card to be happy */ @@ -256,6 +290,25 @@ static char * card_names[] = { "AMD-8111 IOHub" }; +/* These are capabilities (and bugs) the chipsets _can_ have */ +static struct { + int16_t nr_ac97; +#define CAP_MMIO 0x0001 +#define CAP_20BIT_AUDIO_SUPPORT 0x0002 + u_int16_t flags; +} card_cap[] = { + { 1, 0x0000 }, /* ICH82801AA */ + { 1, 0x0000 }, /* ICH82901AB */ + { 1, 0x0000 }, /* INTEL440MX */ + { 1, 0x0000 }, /* INTELICH2 */ + { 2, 0x0000 }, /* INTELICH3 */ + { 3, 0x0003 }, /* INTELICH4 */ + /*@FIXME to be verified*/ { 2, 0x0000 }, /* SI7012 */ + /*@FIXME to be verified*/ { 2, 0x0000 }, /* NVIDIA_NFORCE */ + /*@FIXME to be verified*/ { 2, 0x0000 }, /* AMD768 */ + /*@FIXME to be verified*/ { 3, 0x0001 }, /* AMD8111 */ +}; + static struct pci_device_id i810_pci_tbl [] __initdata = { {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ICH82801AA}, @@ -273,9 +326,13 @@ static struct pci_device_id i810_pci_tbl [] __initdata = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, SI7012}, {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE}, + {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE}, + {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE}, {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_768_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD768}, - {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_AUDIO, + {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_AC97, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD8111}, {0,} }; @@ -365,6 +422,7 @@ struct i810_card { /* PCI device stuff */ struct pci_dev * pci_dev; u16 pci_id; + u16 pci_id_internal; /* used to access card_cap[] */ #ifdef CONFIG_PM u16 pm_suspended; u32 pm_save_state[64/sizeof(u32)]; @@ -374,6 +432,7 @@ struct i810_card { int dev_audio; /* structures for abstraction of hardware facilities, codecs, banks and channels*/ + u16 ac97_id_map[NR_AC97]; struct ac97_codec *ac97_codec[NR_AC97]; struct i810_state *states[NR_HW_CH]; struct i810_channel *channel; /* 1:1 to states[] but diff. lifetime */ @@ -384,9 +443,16 @@ struct i810_card { u16 channels; /* hardware resources */ - unsigned long iobase; unsigned long ac97base; + unsigned long iobase; u32 irq; + + unsigned long ac97base_mmio_phys; + unsigned long iobase_mmio_phys; + u_int8_t *ac97base_mmio; + u_int8_t *iobase_mmio; + + int use_mmio; /* Function support */ struct i810_channel *(*alloc_pcm_channel)(struct i810_card *); @@ -399,6 +465,12 @@ struct i810_card { int initializing; }; +/* extract register offset from codec struct */ +#define IO_REG_OFF(codec) (((struct i810_card *) codec->private_data)->ac97_id_map[codec->id]) + +/* set LVI from CIV */ +#define CIV_TO_LVI(port, off) outb((inb(port+OFF_CIV)+off) & 31, port+OFF_LVI) + static struct i810_card *devs = NULL; static int i810_open_mixdev(struct inode *inode, struct file *file); @@ -406,6 +478,10 @@ static int i810_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static u16 i810_ac97_get(struct ac97_codec *dev, u8 reg); static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data); +static u16 i810_ac97_get_mmio(struct ac97_codec *dev, u8 reg); +static void i810_ac97_set_mmio(struct ac97_codec *dev, u8 reg, u16 data); +static u16 i810_ac97_get_io(struct ac97_codec *dev, u8 reg); +static void i810_ac97_set_io(struct ac97_codec *dev, u8 reg, u16 data); static struct i810_channel *i810_alloc_pcm_channel(struct i810_card *card) { @@ -757,7 +833,8 @@ static inline void __start_adc(struct i810_state *state) if (dmabuf->count < dmabuf->dmasize && dmabuf->ready && !dmabuf->enable && (dmabuf->trigger & PCM_ENABLE_INPUT)) { dmabuf->enable |= ADC_RUNNING; - outb((1<<4) | (1<<2) | 1, state->card->iobase + PI_CR); + // Interrupt enable, LVI enable, DMA enable + outb(0x10 | 0x04 | 0x01, state->card->iobase + PI_CR); } } @@ -806,7 +883,8 @@ static inline void __start_dac(struct i810_state *state) if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable && (dmabuf->trigger & PCM_ENABLE_OUTPUT)) { dmabuf->enable |= DAC_RUNNING; - outb((1<<4) | (1<<2) | 1, state->card->iobase + PO_CR); + // Interrupt enable, LVI enable, DMA enable + outb(0x10 | 0x04 | 0x01, state->card->iobase + PO_CR); } } static void start_dac(struct i810_state *state) @@ -973,11 +1051,11 @@ static int prog_dmabuf(struct i810_state *state, unsigned rec) } spin_lock_irqsave(&state->card->lock, flags); outb(2, state->card->iobase+c->port+OFF_CR); /* reset DMA machine */ + while( inb(state->card->iobase+c->port+OFF_CR) & 0x02 ) ; outl((u32)state->card->chandma + c->num*sizeof(struct i810_channel), state->card->iobase+c->port+OFF_BDBAR); - outb(0, state->card->iobase+c->port+OFF_CIV); - outb(0, state->card->iobase+c->port+OFF_LVI); + CIV_TO_LVI(state->card->iobase+c->port, 0); spin_unlock_irqrestore(&state->card->lock, flags); @@ -1023,13 +1101,13 @@ static void __i810_update_lvi(struct i810_state *state, int rec) if(rec && dmabuf->count < dmabuf->dmasize && (dmabuf->trigger & PCM_ENABLE_INPUT)) { - outb((inb(port+OFF_CIV)+1)&31, port+OFF_LVI); + CIV_TO_LVI(port, 1); __start_adc(state); while( !(inb(port + OFF_CR) & ((1<<4) | (1<<2))) ) ; } else if (!rec && dmabuf->count && (dmabuf->trigger & PCM_ENABLE_OUTPUT)) { - outb((inb(port+OFF_CIV)+1)&31, port+OFF_LVI); + CIV_TO_LVI(port, 1); __start_dac(state); while( !(inb(port + OFF_CR) & ((1<<4) | (1<<2))) ) ; } @@ -1297,7 +1375,6 @@ static void i810_channel_interrupt(struct i810_card *card) if (dmabuf->enable & ADC_RUNNING) __stop_adc(state); dmabuf->enable = 0; - wake_up(&dmabuf->wait); #ifdef DEBUG_INTERRUPTS printk(" STOP "); #endif @@ -1743,11 +1820,12 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } if (c != NULL) { outb(2, state->card->iobase+c->port+OFF_CR); /* reset DMA machine */ + while ( inb(state->card->iobase+c->port+OFF_CR) & 2 ) + cpu_relax(); outl((u32)state->card->chandma + c->num*sizeof(struct i810_channel), state->card->iobase+c->port+OFF_BDBAR); - outb(0, state->card->iobase+c->port+OFF_CIV); - outb(0, state->card->iobase+c->port+OFF_LVI); + CIV_TO_LVI(state->card->iobase+c->port, 0); } spin_unlock_irqrestore(&state->card->lock, flags); @@ -1868,7 +1946,8 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } /* ICH and ICH0 only support 2 channels */ - if ( state->card->pci_id == 0x2415 || state->card->pci_id == 0x2425 ) + if ( state->card->pci_id == PCI_DEVICE_ID_INTEL_82801 + || state->card->pci_id == PCI_DEVICE_ID_INTEL_82901) return put_user(2, (int *)arg); /* Multi-channel support was added with ICH2. Bits in */ @@ -1887,12 +1966,14 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, switch ( val ) { case 2: /* 2 channels is always supported */ - outl(state->card->iobase + GLOB_CNT, (i_glob_cnt & 0xcfffff)); + outl(i_glob_cnt & 0xffcfffff, + state->card->iobase + GLOB_CNT); /* Do we need to change mixer settings???? */ break; case 4: /* Supported on some chipsets, better check first */ if ( state->card->channels >= 4 ) { - outl(state->card->iobase + GLOB_CNT, ((i_glob_cnt & 0xcfffff) | 0x0100000)); + outl((i_glob_cnt & 0xffcfffff) | 0x100000, + state->card->iobase + GLOB_CNT); /* Do we need to change mixer settings??? */ } else { val = ret; @@ -1900,7 +1981,8 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, break; case 6: /* Supported on some chipsets, better check first */ if ( state->card->channels >= 6 ) { - outl(state->card->iobase + GLOB_CNT, ((i_glob_cnt & 0xcfffff) | 0x0200000)); + outl((i_glob_cnt & 0xffcfffff) | 0x200000, + state->card->iobase + GLOB_CNT); /* Do we need to change mixer settings??? */ } else { val = ret; @@ -2037,9 +2119,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes, cinfo.blocks, cinfo.ptr, dmabuf->count); #endif - if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo))) - return -EFAULT; - return 0; + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETISPACE: if (!(file->f_mode & FMODE_READ)) @@ -2078,9 +2158,8 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes, cinfo.blocks, cinfo.ptr, dmabuf->count); #endif - if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo))) - return -EFAULT; - return 0; + return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; + case SNDCTL_DSP_NONBLOCK: #ifdef DEBUG printk("SNDCTL_DSP_NONBLOCK\n"); @@ -2421,6 +2500,9 @@ found_virt: i810_set_spdif_output(state, AC97_EA_SPSA_3_4, spdif_locked); } else { i810_set_dac_rate(state, 8000); + /* Put the ACLink in 2 channel mode by default */ + i = inl(card->iobase + GLOB_CNT); + outl(i & 0xffcfffff, card->iobase + GLOB_CNT); } } @@ -2485,27 +2567,86 @@ static /*const*/ struct file_operations i810_audio_fops = { /* Write AC97 codec registers */ -static u16 i810_ac97_get(struct ac97_codec *dev, u8 reg) +static u16 i810_ac97_get_mmio(struct ac97_codec *dev, u8 reg) { struct i810_card *card = dev->private_data; int count = 100; - u8 reg_set = ((dev->id)?((reg&0x7f)|0x80):(reg&0x7f)); + u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f); + + while(count-- && (readb(card->iobase_mmio + CAS) & 1)) + udelay(1); + +#ifdef DEBUG_MMIO + { + u16 ans = readw(card->ac97base_mmio + reg_set); + printk(KERN_DEBUG "i810_audio: ac97_get_mmio(%d) -> 0x%04X\n", ((int) reg_set) & 0xffff, (u32) ans); + return ans; + } +#else + return readw(card->ac97base_mmio + reg_set); +#endif +} +static u16 i810_ac97_get_io(struct ac97_codec *dev, u8 reg) +{ + struct i810_card *card = dev->private_data; + int count = 100; + u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f); + while(count-- && (inb(card->iobase + CAS) & 1)) udelay(1); return inw(card->ac97base + reg_set); } -static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data) +static void i810_ac97_set_mmio(struct ac97_codec *dev, u8 reg, u16 data) { struct i810_card *card = dev->private_data; int count = 100; - u8 reg_set = ((dev->id)?((reg&0x7f)|0x80):(reg&0x7f)); + u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f); + + while(count-- && (readb(card->iobase_mmio + CAS) & 1)) + udelay(1); + + writew(data, card->ac97base_mmio + reg_set); +#ifdef DEBUG_MMIO + printk(KERN_DEBUG "i810_audio: ac97_set_mmio(0x%04X, %d)\n", (u32) data, ((int) reg_set) & 0xffff); +#endif +} + +static void i810_ac97_set_io(struct ac97_codec *dev, u8 reg, u16 data) +{ + struct i810_card *card = dev->private_data; + int count = 100; + u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f); + while(count-- && (inb(card->iobase + CAS) & 1)) udelay(1); - outw(data, card->ac97base + reg_set); + + outw(data, card->ac97base + reg_set); +} + +static u16 i810_ac97_get(struct ac97_codec *dev, u8 reg) +{ + struct i810_card *card = dev->private_data; + if (card->use_mmio) { + return i810_ac97_get_mmio(dev, reg); + } + else { + return i810_ac97_get_io(dev, reg); + } +} + +static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data) +{ + struct i810_card *card = dev->private_data; + if (card->use_mmio) { + i810_ac97_set_mmio(dev, reg, data); + } + else { + i810_ac97_set_io(dev, reg, data); + } } @@ -2514,7 +2655,7 @@ static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data) static int i810_open_mixdev(struct inode *inode, struct file *file) { int i; - unsigned int minor = minor(inode->i_rdev); + int minor = minor(inode->i_rdev); struct i810_card *card = devs; for (card = devs; card != NULL; card = card->next) { @@ -2530,7 +2671,7 @@ static int i810_open_mixdev(struct inode *inode, struct file *file) set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/20); } - for (i = 0; i < NR_AC97 && card && !card->initializing; i++) + for (i = 0; i < NR_AC97 && card && !card->initializing; i++) if (card->ac97_codec[i] != NULL && card->ac97_codec[i]->dev_mixer == minor) { file->private_data = card->ac97_codec[i]; @@ -2558,10 +2699,18 @@ static /*const*/ struct file_operations i810_mixer_fops = { /* AC97 codec initialisation. These small functions exist so we don't duplicate code between module init and apm resume */ -static inline int i810_ac97_exists(struct i810_card *card,int ac97_number) +static inline int i810_ac97_exists(struct i810_card *card, int ac97_number) { u32 reg = inl(card->iobase + GLOB_STA); - return (reg & (0x100 << ac97_number)); + switch (ac97_number) { + case 0: + return reg & (1<<8); + case 1: + return reg & (1<<9); + case 2: + return reg & (1<<28); + } + return 0; } static inline int i810_ac97_enable_variable_rate(struct ac97_codec *codec) @@ -2584,10 +2733,9 @@ static int i810_ac97_probe_and_powerup(struct i810_card *card,struct ac97_codec /* power it all up */ i810_ac97_set(codec, AC97_POWER_CONTROL, i810_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00); + /* wait for analog ready */ - for (i=10; - i && ((i810_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); - i--) + for (i=10; i && ((i810_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); i--) { set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/20); @@ -2595,11 +2743,18 @@ static int i810_ac97_probe_and_powerup(struct i810_card *card,struct ac97_codec return i; } -/* if I knew what this did, I'd give it a better name */ -static int i810_ac97_random_init_stuff(struct i810_card *card) +/** + * i810_ac97_power_up_bus - bring up AC97 link + * @card : ICH audio device to power up + * + * Bring up the ACLink AC97 codec bus + */ + +static int i810_ac97_power_up_bus(struct i810_card *card) { u32 reg = inl(card->iobase + GLOB_CNT); int i; + int primary_codec_id = 0; if((reg&2)==0) /* Cold required */ reg|=2; @@ -2607,8 +2762,13 @@ static int i810_ac97_random_init_stuff(struct i810_card *card) reg|=4; /* Warm */ reg&=~8; /* ACLink on */ - outl(reg , card->iobase + GLOB_CNT); + /* At this point we deassert AC_RESET # */ + outl(reg , card->iobase + GLOB_CNT); + + /* We must now allow time for the Codec initialisation. + 600mS is the specified time */ + for(i=0;i<10;i++) { if((inl(card->iobase+GLOB_CNT)&4)==0) @@ -2625,7 +2785,31 @@ static int i810_ac97_random_init_stuff(struct i810_card *card) set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/2); - reg = inl(card->iobase + GLOB_STA); + + /* + * See if the primary codec comes ready. This must happen + * before we start doing DMA stuff + */ + /* see i810_ac97_init for the next 7 lines (jsaw) */ + inw(card->ac97base); + if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4) + && (card->use_mmio)) { + primary_codec_id = (int) readl(card->iobase_mmio + SDM) & 0x3; + printk(KERN_INFO "i810_audio: Primary codec has ID %d\n", + primary_codec_id); + } + + if(! i810_ac97_exists(card, primary_codec_id)) + { + printk(KERN_INFO "i810_audio: Codec not ready.. wait.. "); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); /* actually 600mS by the spec */ + + if(i810_ac97_exists(card, primary_codec_id)) + printk("OK\n"); + else + printk("no response.\n"); + } inw(card->ac97base); return 1; } @@ -2633,12 +2817,14 @@ static int i810_ac97_random_init_stuff(struct i810_card *card) static int __init i810_ac97_init(struct i810_card *card) { int num_ac97 = 0; + int ac97_id; int total_channels = 0; + int nr_ac97_max = card_cap[card->pci_id_internal].nr_ac97; struct ac97_codec *codec; u16 eid; u32 reg; - if(!i810_ac97_random_init_stuff(card)) return 0; + if(!i810_ac97_power_up_bus(card)) return 0; /* Number of channels supported */ /* What about the codec? Just because the ICH supports */ @@ -2654,26 +2840,47 @@ static int __init i810_ac97_init(struct i810_card *card) card->channels = 6; else if ( reg & 0x0100000 ) card->channels = 4; - printk("i810_audio: Audio Controller supports %d channels.\n", card->channels); + printk(KERN_INFO "i810_audio: Audio Controller supports %d channels.\n", card->channels); + printk(KERN_INFO "i810_audio: Defaulting to base 2 channel mode.\n"); + reg = inl(card->iobase + GLOB_CNT); + outl(reg & 0xffcfffff, card->iobase + GLOB_CNT); - inw(card->ac97base); + for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) + card->ac97_codec[num_ac97] = NULL; - for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) { + /*@FIXME I don't know, if I'm playing to safe here... (jsaw) */ + if ((nr_ac97_max > 2) && !card->use_mmio) nr_ac97_max = 2; - /* Assume codec isn't available until we go through the - * gauntlet below */ - card->ac97_codec[num_ac97] = NULL; + for (num_ac97 = 0; num_ac97 < nr_ac97_max; num_ac97++) { + /* codec reset */ + printk(KERN_INFO "i810_audio: Resetting connection %d\n", num_ac97); + if (card->use_mmio) readw(card->ac97base_mmio + 0x80*num_ac97); + else inw(card->ac97base + 0x80*num_ac97); + + /* If we have the SDATA_IN Map Register, as on ICH4, we + do not loop thru all possible codec IDs but thru all + possible IO channels. Bit 0:1 of SDM then holds the + last codec ID spoken to. + */ + if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4) + && (card->use_mmio)) { + ac97_id = (int) readl(card->iobase_mmio + SDM) & 0x3; + printk(KERN_INFO "i810_audio: Connection %d with codec id %d\n", + num_ac97, ac97_id); + } + else { + ac97_id = num_ac97; + } /* The ICH programmer's reference says you should */ /* check the ready status before probing. So we chk */ /* What do we do if it's not ready? Wait and try */ /* again, or abort? */ - if (!i810_ac97_exists(card,num_ac97)) { + if (!i810_ac97_exists(card, ac97_id)) { if(num_ac97 == 0) printk(KERN_ERR "i810_audio: Primary codec not ready.\n"); - break; /* I think this works, if not ready stop */ } - + if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL) return -ENOMEM; memset(codec, 0, sizeof(struct ac97_codec)); @@ -2681,13 +2888,20 @@ static int __init i810_ac97_init(struct i810_card *card) /* initialize some basic codec information, other fields will be filled in ac97_probe_codec */ codec->private_data = card; - codec->id = num_ac97; + codec->id = ac97_id; + card->ac97_id_map[ac97_id] = num_ac97 * 0x80; - codec->codec_read = i810_ac97_get; - codec->codec_write = i810_ac97_set; + if (card->use_mmio) { + codec->codec_read = i810_ac97_get_mmio; + codec->codec_write = i810_ac97_set_mmio; + } + else { + codec->codec_read = i810_ac97_get_io; + codec->codec_write = i810_ac97_set_io; + } if(!i810_ac97_probe_and_powerup(card,codec)) { - printk("i810_audio: timed out waiting for codec %d analog ready.\n", num_ac97); + printk(KERN_ERR "i810_audio: timed out waiting for codec %d analog ready.\n", ac97_id); kfree(codec); break; /* it didn't work */ } @@ -2696,7 +2910,7 @@ static int __init i810_ac97_init(struct i810_card *card) /* Don't attempt to get eid until powerup is complete */ eid = i810_ac97_get(codec, AC97_EXTENDED_ID); - + if(eid==0xFFFFFF) { printk(KERN_WARNING "i810_audio: no codec attached ?\n"); @@ -2704,16 +2918,27 @@ static int __init i810_ac97_init(struct i810_card *card) break; } + /* Check for an AC97 1.0 soft modem (ID1) */ + + if(codec->codec_read(codec, AC97_RESET) & 2) + { + printk(KERN_WARNING "i810_audio: codec %d is an AC97 1.0 softmodem - skipping.\n", ac97_id); + kfree(codec); + continue; + } + + /* Check for an AC97 2.x soft modem */ + codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L); - if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID)) + if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1) { - printk(KERN_WARNING "i810_audio: codec %d is a softmodem - skipping.\n", num_ac97); + printk(KERN_WARNING "i810_audio: codec %d is an AC97 2.x softmodem - skipping.\n", ac97_id); kfree(codec); continue; } card->ac97_features = eid; - + /* Now check the codec for useful features to make up for the dumbness of the 810 hardware engine */ @@ -2727,6 +2952,11 @@ static int __init i810_ac97_init(struct i810_card *card) } } + /* Turn on the amplifier */ + + codec->codec_write(codec, AC97_POWER_CONTROL, + codec->codec_read(codec, AC97_POWER_CONTROL) & ~0x8000); + /* Determine how many channels the codec(s) support */ /* - The primary codec always supports 2 */ /* - If the codec supports AMAP, surround DACs will */ @@ -2752,7 +2982,7 @@ static int __init i810_ac97_init(struct i810_card *card) total_channels += 2; if (eid & 0x0140) /* LFE and Center channels */ total_channels += 2; - printk("i810_audio: AC'97 codec %d supports AMAP, total channels = %d\n", num_ac97, total_channels); + printk("i810_audio: AC'97 codec %d supports AMAP, total channels = %d\n", ac97_id, total_channels); } else if (eid & 0x0400) { /* this only works on 2.2 compliant codecs */ eid &= 0xffcf; if((eid & 0xc000) != 0) { @@ -2774,14 +3004,14 @@ static int __init i810_ac97_init(struct i810_card *card) } i810_ac97_set(codec, AC97_EXTENDED_ID, eid); eid = i810_ac97_get(codec, AC97_EXTENDED_ID); - printk("i810_audio: AC'97 codec %d, new EID value = 0x%04x\n", num_ac97, eid); + printk("i810_audio: AC'97 codec %d, new EID value = 0x%04x\n", ac97_id, eid); if (eid & 0x0080) /* L/R Surround channels */ total_channels += 2; if (eid & 0x0140) /* LFE and Center channels */ total_channels += 2; - printk("i810_audio: AC'97 codec %d, DAC map configured, total channels = %d\n", num_ac97, total_channels); + printk("i810_audio: AC'97 codec %d, DAC map configured, total channels = %d\n", ac97_id, total_channels); } else { - printk("i810_audio: AC'97 codec %d Unable to map surround DAC's (or DAC's not present), total channels = %d\n", num_ac97, total_channels); + printk("i810_audio: AC'97 codec %d Unable to map surround DAC's (or DAC's not present), total channels = %d\n", ac97_id, total_channels); } if ((codec->dev_mixer = register_sound_mixer(&i810_mixer_fops, -1)) < 0) { @@ -2830,6 +3060,8 @@ static void __init i810_configure_clocking (void) init_MUTEX(&state->open_sem); dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT; dmabuf->trigger = PCM_ENABLE_OUTPUT; + i810_set_spdif_output(state, -1, 0); + i810_set_dac_channels(state, 2); i810_set_dac_rate(state, 48000); if(prog_dmabuf(state, 0) != 0) { goto config_out_nodmabuf; @@ -2838,17 +3070,16 @@ static void __init i810_configure_clocking (void) goto config_out; } dmabuf->count = dmabuf->dmasize; - outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI); + CIV_TO_LVI(card->iobase+dmabuf->write_channel->port, 31); local_irq_save(flags); start_dac(state); offset = i810_get_dma_addr(state, 0); mdelay(50); new_offset = i810_get_dma_addr(state, 0); stop_dac(state); - outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR); local_irq_restore(flags); i = new_offset - offset; -#ifdef DEBUG +#ifdef DEBUG_INTERRUPTS printk("i810_audio: %d bytes in 50 milliseconds\n", i); #endif if(i == 0) @@ -2890,10 +3121,25 @@ static int __init i810_probe(struct pci_dev *pci_dev, const struct pci_device_id memset(card, 0, sizeof(*card)); card->initializing = 1; - card->iobase = pci_resource_start (pci_dev, 1); - card->ac97base = pci_resource_start (pci_dev, 0); card->pci_dev = pci_dev; card->pci_id = pci_id->device; + card->ac97base = pci_resource_start (pci_dev, 0); + card->iobase = pci_resource_start (pci_dev, 1); + + /* if chipset could have mmio capability, check it */ + if (card_cap[pci_id->driver_data].flags & CAP_MMIO) { + card->ac97base_mmio_phys = pci_resource_start (pci_dev, 2); + card->iobase_mmio_phys = pci_resource_start (pci_dev, 3); + + if ((card->ac97base_mmio_phys) && (card->iobase_mmio_phys)) { + card->use_mmio = 1; + } + else { + card->ac97base_mmio_phys = 0; + card->iobase_mmio_phys = 0; + } + } + card->irq = pci_dev->irq; card->next = devs; card->magic = I810_CARD_MAGIC; @@ -2905,8 +3151,11 @@ static int __init i810_probe(struct pci_dev *pci_dev, const struct pci_device_id pci_set_master(pci_dev); - printk(KERN_INFO "i810: %s found at IO 0x%04lx and 0x%04lx, IRQ %d\n", - card_names[pci_id->driver_data], card->iobase, card->ac97base, + printk(KERN_INFO "i810: %s found at IO 0x%04lx and 0x%04lx, " + "MEM 0x%04lx and 0x%04lx, IRQ %d\n", + card_names[pci_id->driver_data], + card->iobase, card->ac97base, + card->ac97base_mmio_phys, card->iobase_mmio_phys, card->irq); card->alloc_pcm_channel = i810_alloc_pcm_channel; @@ -2941,17 +3190,42 @@ static int __init i810_probe(struct pci_dev *pci_dev, const struct pci_device_id if (request_irq(card->irq, &i810_interrupt, SA_SHIRQ, card_names[pci_id->driver_data], card)) { printk(KERN_ERR "i810_audio: unable to allocate irq %d\n", card->irq); - release_region(card->iobase, 64); - release_region(card->ac97base, 256); - goto out_chan; + goto out_pio; + } + + if (card->use_mmio) { + if (request_mem_region(card->ac97base_mmio_phys, 512, "ich_audio MMBAR")) { + if ((card->ac97base_mmio = ioremap(card->ac97base_mmio_phys, 512))) { /*@FIXME can ioremap fail? don't know (jsaw) */ + if (request_mem_region(card->iobase_mmio_phys, 256, "ich_audio MBBAR")) { + if ((card->iobase_mmio = ioremap(card->iobase_mmio_phys, 256))) { + printk(KERN_INFO "i810: %s mmio at 0x%04lx and 0x%04lx\n", + card_names[pci_id->driver_data], + (unsigned long) card->ac97base_mmio, + (unsigned long) card->iobase_mmio); + } + else { + iounmap(card->ac97base_mmio); + release_mem_region(card->ac97base_mmio_phys, 512); + release_mem_region(card->iobase_mmio_phys, 512); + card->use_mmio = 0; + } + } + else { + iounmap(card->ac97base_mmio); + release_mem_region(card->ac97base_mmio_phys, 512); + card->use_mmio = 0; + } + } + } + else { + card->use_mmio = 0; + } } /* initialize AC97 codec and register /dev/mixer */ if (i810_ac97_init(card) <= 0) { - release_region(card->iobase, 64); - release_region(card->ac97base, 256); free_irq(card->irq, card); - goto out_chan; + goto out_iospace; } pci_set_drvdata(pci_dev, card); @@ -2964,23 +3238,31 @@ static int __init i810_probe(struct pci_dev *pci_dev, const struct pci_device_id if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) { int i; printk(KERN_ERR "i810_audio: couldn't register DSP device!\n"); - release_region(card->iobase, 64); - release_region(card->ac97base, 256); free_irq(card->irq, card); for (i = 0; i < NR_AC97; i++) if (card->ac97_codec[i] != NULL) { unregister_sound_mixer(card->ac97_codec[i]->dev_mixer); kfree (card->ac97_codec[i]); } - goto out_chan; + goto out_iospace; } + card->initializing = 0; return 0; - out_chan: +out_iospace: + if (card->use_mmio) { + iounmap(card->ac97base_mmio); + iounmap(card->iobase_mmio); + release_mem_region(card->ac97base_mmio_phys, 512); + release_mem_region(card->iobase_mmio_phys, 256); + } +out_pio: + release_region(card->iobase, 64); + release_region(card->ac97base, 256); pci_free_consistent(pci_dev, sizeof(struct i810_channel)*NR_HW_CH, card->channel, card->chandma); - out_mem: +out_mem: kfree(card); return -ENODEV; } @@ -2993,6 +3275,12 @@ static void __devexit i810_remove(struct pci_dev *pci_dev) free_irq(card->irq, devs); release_region(card->iobase, 64); release_region(card->ac97base, 256); + if (card->use_mmio) { + iounmap(card->ac97base_mmio); + iounmap(card->iobase_mmio); + release_mem_region(card->ac97base_mmio_phys, 512); + release_mem_region(card->iobase_mmio_phys, 256); + } /* unregister audio devices */ for (i = 0; i < NR_AC97; i++) @@ -3075,7 +3363,7 @@ static int i810_pm_resume(struct pci_dev *dev) hardware has to be more or less completely reinitialized from scratch after an apm suspend. Works For Me. -dan */ - i810_ac97_random_init_stuff(card); + i810_ac97_power_up_bus(card); for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) { struct ac97_codec *codec = card->ac97_codec[num_ac97]; @@ -3160,7 +3448,6 @@ static int __init i810_init_module (void) printk(KERN_INFO "Intel 810 + AC97 Audio, version " DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n"); - printk(KERN_WARNING "This driver is deprecated, please use the ALSA drivers.\n"); if (!pci_register_driver(&i810_pci_driver)) { pci_unregister_driver(&i810_pci_driver); diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 36fa14706146..ee9b28117ac2 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -314,9 +314,8 @@ static unsigned int rates[14] = { }; static snd_pcm_hw_constraint_list_t hw_constraints_rates = { - count: 14, - list: rates, - mask: 0, + .count = 14, + .list = rates, }; static int snd_cs4231_xrate(snd_pcm_runtime_t *runtime) @@ -1418,44 +1417,42 @@ static int snd_cs4231_probe(cs4231_t *chip) static snd_pcm_hardware_t snd_cs4231_playback = { - info: (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START), - formats: (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | + .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE), - rates: SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, - rate_min: 5510, - rate_max: 48000, - channels_min: 1, - channels_max: 2, - buffer_bytes_max: (32*1024), - period_bytes_min: 4096, - period_bytes_max: (32*1024), - periods_min: 1, - periods_max: 1024, - fifo_size: 0, + .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, + .rate_min = 5510, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = (32*1024), + .period_bytes_min = 4096, + .period_bytes_max = (32*1024), + .periods_min = 1, + .periods_max = 1024, }; static snd_pcm_hardware_t snd_cs4231_capture = { - info: (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START), - formats: (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | + .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE), - rates: SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, - rate_min: 5510, - rate_max: 48000, - channels_min: 1, - channels_max: 2, - buffer_bytes_max: (32*1024), - period_bytes_min: 4096, - period_bytes_max: (32*1024), - periods_min: 1, - periods_max: 1024, - fifo_size: 0, + .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, + .rate_min = 5510, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = (32*1024), + .period_bytes_min = 4096, + .period_bytes_max = (32*1024), + .periods_min = 1, + .periods_max = 1024, }; static int snd_cs4231_playback_open(snd_pcm_substream_t *substream) @@ -1821,16 +1818,16 @@ int snd_cs4231_put_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontr #define CS4231_CONTROLS (sizeof(snd_cs4231_controls)/sizeof(snd_kcontrol_new_t)) #define CS4231_SINGLE(xname, xindex, reg, shift, mask, invert) \ -{ iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: xname, index: xindex, \ - info: snd_cs4231_info_single, \ - get: snd_cs4231_get_single, put: snd_cs4231_put_single, \ - private_value: reg | (shift << 8) | (mask << 16) | (invert << 24) } +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ + .info = snd_cs4231_info_single, \ + .get = snd_cs4231_get_single, .put = snd_cs4231_put_single, \ + .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } #define CS4231_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ -{ iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: xname, index: xindex, \ - info: snd_cs4231_info_double, \ - get: snd_cs4231_get_double, put: snd_cs4231_put_double, \ - private_value: left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ + .info = snd_cs4231_info_double, \ + .get = snd_cs4231_get_double, .put = snd_cs4231_put_double, \ + .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } static snd_kcontrol_new_t snd_cs4231_controls[] = { CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), @@ -1847,11 +1844,11 @@ CS4231_SINGLE("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, 6, 1, 1), CS4231_SINGLE("Mono Output Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0), CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), { - iface: SNDRV_CTL_ELEM_IFACE_MIXER, - name: "Capture Source", - info: snd_cs4231_info_mux, - get: snd_cs4231_get_mux, - put: snd_cs4231_put_mux, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = snd_cs4231_info_mux, + .get = snd_cs4231_get_mux, + .put = snd_cs4231_put_mux, }, CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0), |
