+++ /dev/null
-Most (all) Intel-MP compliant SMP boards have the so-called 'IO-APIC',
-which is an enhanced interrupt controller, it enables us to route
-hardware interrupts to multiple CPUs, or to CPU groups.
-
-Linux supports all variants of compliant SMP boards, including ones with
-multiple IO-APICs. (multiple IO-APICs are used in high-end servers to
-distribute IRQ load further).
-
-There are (a few) known breakages in certain older boards, which bugs are
-usually worked around by the kernel. If your MP-compliant SMP board does
-not boot Linux, then consult the linux-smp mailing list archives first.
-
-If your box boots fine with enabled IO-APIC IRQs, then your
-/proc/interrupts will look like this one:
-
- ---------------------------->
- hell:~> cat /proc/interrupts
- CPU0
- 0: 1360293 IO-APIC-edge timer
- 1: 4 IO-APIC-edge keyboard
- 2: 0 XT-PIC cascade
- 13: 1 XT-PIC fpu
- 14: 1448 IO-APIC-edge ide0
- 16: 28232 IO-APIC-level Intel EtherExpress Pro 10/100 Ethernet
- 17: 51304 IO-APIC-level eth0
- NMI: 0
- ERR: 0
- hell:~>
- <----------------------------
-
-some interrupts are still listed as 'XT PIC', but this is not a problem,
-none of those IRQ sources is performance-critical.
-
-
-in the unlikely case that your board does not create a working mp-table,
-you can use the pirq= boot parameter to 'hand-construct' IRQ entries. This
-is nontrivial though and cannot be automated. One sample /etc/lilo.conf
-entry:
-
- append="pirq=15,11,10"
-
-the actual numbers depend on your system, on your PCI cards and on their
-PCI slot position. Usually PCI slots are 'daisy chained' before they are
-connected to the PCI chipset IRQ routing facility (the incoming PIRQ1-4
-lines):
-
- ,-. ,-. ,-. ,-. ,-.
- PIRQ4 ----| |-. ,-| |-. ,-| |-. ,-| |--------| |
- |S| \ / |S| \ / |S| \ / |S| |S|
- PIRQ3 ----|l|-. `/---|l|-. `/---|l|-. `/---|l|--------|l|
- |o| \/ |o| \/ |o| \/ |o| |o|
- PIRQ2 ----|t|-./`----|t|-./`----|t|-./`----|t|--------|t|
- |1| /\ |2| /\ |3| /\ |4| |5|
- PIRQ1 ----| |- `----| |- `----| |- `----| |--------| |
- `-' `-' `-' `-' `-'
-
-every PCI card emits a PCI IRQ, which can be INTA,INTB,INTC,INTD:
-
- ,-.
- INTD--| |
- |S|
- INTC--|l|
- |o|
- INTB--|t|
- |x|
- INTA--| |
- `-'
-
-These INTA-D PCI IRQs are always 'local to the card', their real meaning
-depends on which slot they are in. If you look at the daisy chaining diagram,
-a card in slot4, issuing INTA IRQ, it will end up as a signal on PIRQ2 of
-the PCI chipset. Most cards issue INTA, this creates optimal distribution
-between the PIRQ lines. (distributing IRQ sources properly is not a
-necessity, PCI IRQs can be shared at will, but it's a good for performance
-to have non shared interrupts). Slot5 should be used for videocards, they
-do not use interrupts normally, thus they are not daisy chained either.
-
-so if you have your SCSI card (IRQ11) in Slot1, Tulip card (IRQ9) in
-Slot2, then you'll have to specify this pirq= line:
-
- append="pirq=11,9"
-
-the following script tries to figure out such a default pirq= line from
-your PCI configuration:
-
- echo -n pirq=; echo `scanpci | grep T_L | cut -c56-` | sed 's/ /,/g'
-
-note that this script wont work if you have skipped a few slots or if your
-board does not do default daisy-chaining. (or the IO-APIC has the PIRQ pins
-connected in some strange way). E.g. if in the above case you have your SCSI
-card (IRQ11) in Slot3, and have Slot1 empty:
-
- append="pirq=0,9,11"
-
-[value '0' is a generic 'placeholder', reserved for empty (or non-IRQ emitting)
-slots.]
-
-generally, it's always possible to find out the correct pirq= settings, just
-permute all IRQ numbers properly ... it will take some time though. An
-'incorrect' pirq line will cause the booting process to hang, or a device
-won't function properly (if it's inserted as eg. a module).
-
-If you have 2 PCI buses, then you can use up to 8 pirq values. Although such
-boards tend to have a good configuration.
-
-Be prepared that it might happen that you need some strange pirq line:
-
- append="pirq=0,0,0,0,0,0,9,11"
-
-use smart try-and-err techniques to find out the correct pirq line ...
-
-good luck and mail to linux-smp@vger.rutgers.edu or
-linux-kernel@vger.rutgers.edu if you have any problems that are not covered
-by this document.
-
--- mingo
-
--- /dev/null
+Most (all) Intel-MP compliant SMP boards have the so-called 'IO-APIC',
+which is an enhanced interrupt controller, it enables us to route
+hardware interrupts to multiple CPUs, or to CPU groups.
+
+Linux supports all variants of compliant SMP boards, including ones with
+multiple IO-APICs. (multiple IO-APICs are used in high-end servers to
+distribute IRQ load further).
+
+There are (a few) known breakages in certain older boards, which bugs are
+usually worked around by the kernel. If your MP-compliant SMP board does
+not boot Linux, then consult the linux-smp mailing list archives first.
+
+If your box boots fine with enabled IO-APIC IRQs, then your
+/proc/interrupts will look like this one:
+
+ ---------------------------->
+ hell:~> cat /proc/interrupts
+ CPU0
+ 0: 1360293 IO-APIC-edge timer
+ 1: 4 IO-APIC-edge keyboard
+ 2: 0 XT-PIC cascade
+ 13: 1 XT-PIC fpu
+ 14: 1448 IO-APIC-edge ide0
+ 16: 28232 IO-APIC-level Intel EtherExpress Pro 10/100 Ethernet
+ 17: 51304 IO-APIC-level eth0
+ NMI: 0
+ ERR: 0
+ hell:~>
+ <----------------------------
+
+some interrupts are still listed as 'XT PIC', but this is not a problem,
+none of those IRQ sources is performance-critical.
+
+
+in the unlikely case that your board does not create a working mp-table,
+you can use the pirq= boot parameter to 'hand-construct' IRQ entries. This
+is nontrivial though and cannot be automated. One sample /etc/lilo.conf
+entry:
+
+ append="pirq=15,11,10"
+
+the actual numbers depend on your system, on your PCI cards and on their
+PCI slot position. Usually PCI slots are 'daisy chained' before they are
+connected to the PCI chipset IRQ routing facility (the incoming PIRQ1-4
+lines):
+
+ ,-. ,-. ,-. ,-. ,-.
+ PIRQ4 ----| |-. ,-| |-. ,-| |-. ,-| |--------| |
+ |S| \ / |S| \ / |S| \ / |S| |S|
+ PIRQ3 ----|l|-. `/---|l|-. `/---|l|-. `/---|l|--------|l|
+ |o| \/ |o| \/ |o| \/ |o| |o|
+ PIRQ2 ----|t|-./`----|t|-./`----|t|-./`----|t|--------|t|
+ |1| /\ |2| /\ |3| /\ |4| |5|
+ PIRQ1 ----| |- `----| |- `----| |- `----| |--------| |
+ `-' `-' `-' `-' `-'
+
+every PCI card emits a PCI IRQ, which can be INTA,INTB,INTC,INTD:
+
+ ,-.
+ INTD--| |
+ |S|
+ INTC--|l|
+ |o|
+ INTB--|t|
+ |x|
+ INTA--| |
+ `-'
+
+These INTA-D PCI IRQs are always 'local to the card', their real meaning
+depends on which slot they are in. If you look at the daisy chaining diagram,
+a card in slot4, issuing INTA IRQ, it will end up as a signal on PIRQ2 of
+the PCI chipset. Most cards issue INTA, this creates optimal distribution
+between the PIRQ lines. (distributing IRQ sources properly is not a
+necessity, PCI IRQs can be shared at will, but it's a good for performance
+to have non shared interrupts). Slot5 should be used for videocards, they
+do not use interrupts normally, thus they are not daisy chained either.
+
+so if you have your SCSI card (IRQ11) in Slot1, Tulip card (IRQ9) in
+Slot2, then you'll have to specify this pirq= line:
+
+ append="pirq=11,9"
+
+the following script tries to figure out such a default pirq= line from
+your PCI configuration:
+
+ echo -n pirq=; echo `scanpci | grep T_L | cut -c56-` | sed 's/ /,/g'
+
+note that this script wont work if you have skipped a few slots or if your
+board does not do default daisy-chaining. (or the IO-APIC has the PIRQ pins
+connected in some strange way). E.g. if in the above case you have your SCSI
+card (IRQ11) in Slot3, and have Slot1 empty:
+
+ append="pirq=0,9,11"
+
+[value '0' is a generic 'placeholder', reserved for empty (or non-IRQ emitting)
+slots.]
+
+generally, it's always possible to find out the correct pirq= settings, just
+permute all IRQ numbers properly ... it will take some time though. An
+'incorrect' pirq line will cause the booting process to hang, or a device
+won't function properly (if it's inserted as eg. a module).
+
+If you have 2 PCI buses, then you can use up to 8 pirq values. Although such
+boards tend to have a good configuration.
+
+Be prepared that it might happen that you need some strange pirq line:
+
+ append="pirq=0,0,0,0,0,0,9,11"
+
+use smart try-and-err techniques to find out the correct pirq line ...
+
+good luck and mail to linux-smp@vger.rutgers.edu or
+linux-kernel@vger.rutgers.edu if you have any problems that are not covered
+by this document.
+
+-- mingo
+
deregistration of the driver or when it's manually pulled
out of a hot-pluggable slot). This function can be called
from interrupt context.
- suspend, Power management hooks (currently used only for CardBus
- resume cards) -- called when the device goes to sleep or is
- resumed.
+ suspend, Power management hooks -- called when the device goes to
+ resume sleep or is resumed.
The ID table is an array of struct pci_device_id ending with a all-zero entry.
Each entry consists of:
CONFIGURATION
- Currently the driver can handle up to 16 different serial interfaces at
- one time. Once more of the drivers become stable, this number will be
- increased to the full 256.
+ Currently the driver can handle up to 256 different serial interfaces at
+ one time.
- The major number that the driver uses is 188 so to use the driver,
- create the following nodes:
+ If you are not using devfs:
+ The major number that the driver uses is 188 so to use the driver,
+ create the following nodes:
mknod /dev/ttyUSB0 c 188 0
mknod /dev/ttyUSB1 c 188 1
mknod /dev/ttyUSB2 c 188 2
mknod /dev/ttyUSB3 c 188 3
- mknod /dev/ttyUSB4 c 188 4
- mknod /dev/ttyUSB5 c 188 5
- mknod /dev/ttyUSB6 c 188 6
- mknod /dev/ttyUSB7 c 188 7
- mknod /dev/ttyUSB8 c 188 8
- mknod /dev/ttyUSB9 c 188 9
- mknod /dev/ttyUSB10 c 188 10
- mknod /dev/ttyUSB11 c 188 11
- mknod /dev/ttyUSB12 c 188 12
- mknod /dev/ttyUSB13 c 188 13
- mknod /dev/ttyUSB14 c 188 14
- mknod /dev/ttyUSB15 c 188 15
- mknod /dev/ttyUSB16 c 188 16
-
+ .
+ .
+ .
+ mknod /dev/ttyUSB254 c 188 254
+ mknod /dev/ttyUSB255 c 188 255
+
+ If you are using devfs:
+ The devices supported by this driver will show up as
+ /dev/usb/tts/{0,1,...}
+
+ When the device is connected and recognized by the driver, the driver
+ will print to the system log, which node(s) the device has been bound
+ to.
+
SPECIFIC DEVICES SUPPORTED
being fully supported.
Current status:
- The device's firmware is downloaded on connection, but the use of a
- special Anchor Chips extension is currently giving me problems.
+ The device's firmware is downloaded on connection, the new firmware
+ runs properly and all four ports are successfuly recognized and connected.
+ Now data flow needs to be implemented properly.
This driver is not fully operational.
When the device is connected, try talking to it on the second port
(this is usually /dev/ttyUSB1 if you do not have any other usb-serial
- devices in the system.)
+ devices in the system.) The system log should tell you which port is
+ the port to use for the HotSync transfer. The "Generic" port can be used
+ for other device communication, such as a PPP link.
There is a webpage and mailing lists for this portion of the driver at:
http://usbvisor.sourceforge.net/
O_NONBLOCK, select()
+FTDI Single Port Serial Driver
+
+ This is a single port DB-25 serial adapter. More information about this
+ device and the Linux driver can be found at:
+ http://reality.sgi.com/bryder_wellington/ftdi_sio/
+
+
+ZyXEL omni.net lcd plus ISDN TA
+
+ This is an ISDN TA. Please report both successes and troubles to the
+ author at omninet@kroah.com
+
+
Generic Serial driver
If your device is not one of the above listed devices, compatible with
{
struct task_struct *child;
struct user * dummy = NULL;
- unsigned long flags;
int i, ret;
lock_kernel();
ret = -ESRCH;
read_lock(&tasklist_lock);
child = find_task_by_pid(pid);
- read_unlock(&tasklist_lock); /* FIXME!!! */
+ if (child)
+ get_task_struct(child);
+ read_unlock(&tasklist_lock);
if (!child)
goto out;
+
ret = -EPERM;
if (pid == 1) /* you may not mess with init */
- goto out;
+ goto out_tsk;
+
if (request == PTRACE_ATTACH) {
if (child == current)
- goto out;
+ goto out_tsk;
if ((!child->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
- goto out;
+ goto out_tsk;
/* the same process cannot be attached many times */
if (child->flags & PF_PTRACED)
- goto out;
+ goto out_tsk;
child->flags |= PF_PTRACED;
- write_lock_irqsave(&tasklist_lock, flags);
+ write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
- write_unlock_irqrestore(&tasklist_lock, flags);
+ write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
- goto out;
+ goto out_tsk;
}
ret = -ESRCH;
if (!(child->flags & PF_PTRACED))
- goto out;
+ goto out_tsk;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
- goto out;
+ goto out_tsk;
}
if (child->p_pptr != current)
- goto out;
-
+ goto out_tsk;
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
data &= ~DR_CONTROL_RESERVED;
for(i=0; i<4; i++)
if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
- goto out;
+ goto out_tsk;
}
addr -= (long) &dummy->u_debugreg;
break;
child->flags &= ~(PF_PTRACED|PF_TRACESYS);
child->exit_code = data;
- write_lock_irqsave(&tasklist_lock, flags);
+ write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
- write_unlock_irqrestore(&tasklist_lock, flags);
+ write_unlock_irq(&tasklist_lock);
/* make sure the single step bit is not set. */
tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
put_stack_long(child, EFL_OFFSET, tmp);
ret = -EIO;
break;
}
+out_tsk:
+ free_task_struct(child);
out:
unlock_kernel();
return ret;
/* A keyboard int may have come in before we disabled the irq, so
* double-check whether rep_scancode is still != 0 */
if (rep_scancode) {
+ init_timer(&atakeyb_rep_timer);
atakeyb_rep_timer.expires = jiffies + key_repeat_rate;
- atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL;
add_timer( &atakeyb_rep_timer );
handle_scancode(rep_scancode, 1);
del_timer( &atakeyb_rep_timer );
rep_scancode = scancode;
atakeyb_rep_timer.expires = jiffies + key_repeat_delay;
- atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL;
add_timer( &atakeyb_rep_timer );
}
-/* $Id: ultra.S,v 1.41 2000/03/27 10:38:51 davem Exp $
+/* $Id: ultra.S,v 1.42 2000/05/05 18:47:41 davem Exp $
* ultra.S: Don't expand these all over the place...
*
* Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
*/
#define TLB_MAGIC 207 /* Students, do you know how I calculated this? -DaveM */
/*IC3*/ cmp %o5, %o4
- be,pt %xcc, __flush_tlb_page
+ bleu,pt %xcc, __flush_tlb_page
srlx %o5, 13, %g5
cmp %g5, TLB_MAGIC
bgeu,pn %icc, __flush_tlb_range_constant_time
static IADEV *ia_dev[8] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
static struct atm_dev *_ia_dev[8] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
static int iadev_count = 0;
-static struct timer_list ia_timer;
+static void ia_led_timer(unsigned long arg);
+static struct timer_list ia_timer = { function: ia_led_timer };
struct atm_vcc *vcc_close_que[100];
static int IA_TX_BUF = DFL_TX_BUFFERS, IA_TX_BUF_SZ = DFL_TX_BUF_SZ;
static int IA_RX_BUF = DFL_RX_BUFFERS, IA_RX_BUF_SZ = DFL_RX_BUF_SZ;
{
static u8 first = 1;
if (first) {
- ia_timer.next = NULL;
- ia_timer.prev = NULL;
ia_timer.expires = jiffies + 3*HZ;
- ia_timer.data = 0UL;
- ia_timer.function = ia_led_timer;
add_timer(&ia_timer);
first = 0;
}
return -ENXIO;
}
// MOD_INC_USE_COUNT;
- init_timer(&ia_timer);
ia_timer.expires = jiffies + 3*HZ;
- ia_timer.data = 0UL;
- ia_timer.function = ia_led_timer;
add_timer(&ia_timer);
return 0;
}
#endif
-
+
poll_timer.function = suni_hz;
poll_timer.data = 1;
#if 0
-printk(KERN_DEBUG "[u] p=0x%lx,n=0x%lx\n",(unsigned long) poll_timer.prev,
- (unsigned long) poll_timer.next);
+printk(KERN_DEBUG "[u] p=0x%lx,n=0x%lx\n",(unsigned long) poll_timer.list.prev,
+ (unsigned long) poll_timer.list.next);
#endif
add_timer(&poll_timer);
}
}
/* initialize variables */
- motor_on_timer.next = NULL;
- motor_on_timer.prev = NULL;
+ init_timer(&motor_on_timer);
motor_on_timer.expires = 0;
motor_on_timer.data = 0;
motor_on_timer.function = motor_on_callback;
for (i = 0; i < FD_MAX_UNITS; i++) {
- motor_off_timer[i].next = NULL;
- motor_off_timer[i].prev = NULL;
+ init_timer(&motor_off_timer[i]);
motor_off_timer[i].expires = 0;
motor_off_timer[i].data = i|0x80000000;
motor_off_timer[i].function = fd_motor_off;
- flush_track_timer[i].next = NULL;
- flush_track_timer[i].prev = NULL;
+ init_timer(&flush_track_timer[i]);
flush_track_timer[i].expires = 0;
flush_track_timer[i].data = i;
flush_track_timer[i].function = flush_track_callback;
unit[i].track = -1;
}
- post_write_timer.next = NULL;
- post_write_timer.prev = NULL;
+ init_timer(&post_write_timer);
post_write_timer.expires = 0;
post_write_timer.data = 0;
post_write_timer.function = post_write;
reset_status = 0;
reset_start = jiffies;
while (!reset_status) {
- esdi_timer.expires = HZ;
+ init_timer(&esdi_timer);
+ esdi_timer.expires = jiffies + HZ;
esdi_timer.data = 0;
- esdi_timer.next = esdi_timer.prev = NULL;
add_timer(&esdi_timer);
sleep_on(&ps2esdi_int);
}
#ifdef MODULE
module_init(rd_init);
-module_exit(rd_cleanup);
#endif
+module_exit(rd_cleanup);
/* loadable module support */
MODULE_PARM (rd_size, "1i");
/* Timed waiting for status or data */
static int sleep_timeout; /* max # of ticks to sleep */
static DECLARE_WAIT_QUEUE_HEAD(waitq);
-static struct timer_list delay_timer = {NULL, NULL, 0, 0, NULL};
-
-#define SET_TIMER(func, jifs) \
- delay_timer.expires = jiffies+(jifs); \
- delay_timer.function = (void *) (func); \
- add_timer(&delay_timer);
-#define CLEAR_TIMER del_timer(&delay_timer)
+static void sleep_timer(unsigned long data);
+static struct timer_list delay_timer = {function: sleep_timer};
/* Timer routine: wake up when desired flag goes low,
or when timeout expires. */
-static void sleep_timer(void)
+static void sleep_timer(unsigned long data)
{
int flags = inb(STATUS_PORT) & FL_STDT;
if (flags == FL_STDT && --sleep_timeout > 0) {
- SET_TIMER(sleep_timer, HZ/100); /* multi-statement macro */
+ mod_timer(&delay_timer, jiffies + HZ/100); /* multi-statement macro */
} else
wake_up(&waitq);
}
sleep_timeout = timeout;
flag_high = inb(STATUS_PORT) & flag;
if (flag_high && sleep_timeout > 0) {
- SET_TIMER(sleep_timer, HZ/100);
+ mod_timer(&delay_timer, jiffies + HZ/100);
sleep_on(&waitq);
flag_high = inb(STATUS_PORT) & flag;
}
static int tries; /* ibid?? */
static int timeout = 0;
-static struct timer_list req_timer = {NULL, NULL, 0, 0, NULL};
+static void poll(unsigned long data);
+static struct timer_list req_timer = {function: poll};
-#define SET_REQ_TIMER(func, jifs) \
- req_timer.expires = jiffies+(jifs); \
- req_timer.function = (void *) (func); \
- add_timer(&req_timer);
-#define CLEAR_REQ_TIMER del_timer(&req_timer)
-static void poll(void)
+static void poll(unsigned long data)
{
static volatile int read_count = 1;
int flags;
}
}
- SET_REQ_TIMER(poll, HZ/100);
+ mod_timer(&req_timer, jiffies + HZ/100);
}
timeout = READ_TIMEOUT;
tries = 5;
/* %% why not start right away?? */
- SET_REQ_TIMER(poll, HZ/100);
+ mod_timer(&req_timer, jiffies + HZ/100);
}
break;
}
status = exec_cmd(COMOPEN);
DEBUG((DEBUG_VFS, "exec_cmd COMOPEN: %02x", -status));
}
- CLEAR_TIMER;
- CLEAR_REQ_TIMER;
+ del_timer(&delay_timer);
+ del_timer(&req_timer);
}
MOD_DEC_USE_COUNT;
return 0;
/*
* Timer.
*/
-static struct timer_list sjcd_delay_timer = { NULL, NULL, 0, 0, NULL };
+static struct timer_list sjcd_delay_timer = { function: NULL };
#define SJCD_SET_TIMER( func, tmout ) \
( sjcd_delay_timer.expires = jiffies+tmout, \
int len, int *eof, void *private)
{
struct miscdevice *p;
+ int written;
- len=0;
- for (p = misc_list.next; p != &misc_list && len < 4000; p = p->next)
- len += sprintf(buf+len, "%3i %s\n",p->minor, p->name ?: "");
+ written=0;
+ for (p = misc_list.next; p != &misc_list && written < len; p = p->next) {
+ written += sprintf(buf+written, "%3i %s\n",p->minor, p->name ?: "");
+ if (written < offset) {
+ offset -= written;
+ written = 0;
+ }
+ }
*start = buf + offset;
- return len > offset ? len - offset : 0;
+ written -= offset;
+ if(written > len) {
+ *eof = 0;
+ return len;
+ }
+ *eof = 1;
+ return (written<0) ? 0 : written;
}
msp3400c_mixer_open(struct inode *inode, struct file *file)
{
int minor = MINOR(inode->i_rdev);
- struct i2c_client *client;
+ struct i2c_client *client = NULL;
struct msp3400c *msp;
int i;
if (msp->mixer_num == minor) {
client = msps[i];
file->private_data = client;
- break;
+ goto match;
}
}
- if (MSP3400_MAX == i)
- return -ENODEV;
+ return -ENODEV;
+match:
/* lock bttv in memory while the mixer is in use */
if (client->adapter->inc_use)
client->adapter->inc_use(client->adapter);
{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C104, MXSER_BOARD_C104_PCI},
};
-typedef struct _moxa_pci_info {
- unsigned short busNum;
- unsigned short devNum;
-} moxa_pci_info;
-
static int ioaddr[MXSER_BOARDS] = {0, 0, 0, 0};
static int ttymajor = MXSERMAJOR;
static int calloutmajor = MXSERCUMAJOR;
int uart_type;
int ioaddr[MXSER_PORTS_PER_BOARD];
int baud_base[MXSER_PORTS_PER_BOARD];
- moxa_pci_info pciInfo;
+ struct pci_dev *pdev;
};
struct mxser_struct {
static void mxser_getcfg(int board, struct mxser_hwconf *hwconf);
int mxser_init(void);
static int mxser_get_ISA_conf(int, struct mxser_hwconf *);
-static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *);
+static int mxser_get_PCI_conf(struct pci_dev *, int, struct mxser_hwconf *);
static void mxser_do_softint(void *);
static int mxser_open(struct tty_struct *, struct file *);
static void mxser_close(struct tty_struct *, struct file *);
mxsercfg[board] = *hwconf;
}
-static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxser_hwconf *hwconf)
+static int mxser_get_PCI_conf(struct pci_dev *pdev, int board_type, struct mxser_hwconf *hwconf)
{
int i;
- unsigned int val, ioaddress;
+ unsigned int ioaddress;
hwconf->board_type = board_type;
hwconf->ports = mxser_numports[board_type - 1];
- pcibios_read_config_dword(busnum, devnum, PCI_BASE_ADDRESS_2, &val);
- if (val == 0xffffffff)
- return (MXSER_ERR_IOADDR);
- else
- ioaddress = val & 0xffffffc;
+ ioaddress = pci_resource_start (pdev, 2);
for (i = 0; i < hwconf->ports; i++)
hwconf->ioaddr[i] = ioaddress + 8 * i;
- pcibios_read_config_dword(busnum, devnum, PCI_BASE_ADDRESS_3, &val);
- if (val == 0xffffffff)
- return (MXSER_ERR_VECTOR);
- else
- ioaddress = val & 0xffffffc;
+ ioaddress = pci_resource_start (pdev, 3);
hwconf->vector = ioaddress;
- pcibios_read_config_dword(busnum, devnum, PCI_INTERRUPT_LINE, &val);
- if (val == 0xffffffff)
- return (MXSER_ERR_IRQ);
- else
- hwconf->irq = val & 0xff;
+ hwconf->irq = pdev->irq;
hwconf->uart_type = PORT_16550A;
hwconf->vector_mask = 0;
int i, m, retval, b;
int n, index;
int ret1, ret2;
- unsigned char busnum, devnum;
struct mxser_hwconf hwconf;
printk("MOXA Smartio family driver version %s\n", MXSER_VERSION);
continue;
}
- hwconf.pciInfo.busNum = 0;
- hwconf.pciInfo.devNum = 0;
+ hwconf.pdev = NULL;
if (mxser_initbrd(m, &hwconf) < 0)
continue;
continue;
}
- hwconf.pciInfo.busNum = 0;
- hwconf.pciInfo.devNum = 0;
+ hwconf.pdev = NULL;
if (mxser_initbrd(m, &hwconf) < 0)
continue;
/* start finding PCI board here */
#ifdef CONFIG_PCI
- if (pci_present())
{
+ struct pci_dev *pdev = NULL;
+
n = sizeof(mxser_pcibrds) / sizeof(mxser_pciinfo);
index = 0;
b = 0;
while (b < n) {
- if (pcibios_find_device(mxser_pcibrds[b].vendor_id,
- mxser_pcibrds[b].device_id,
- index,
- &busnum,
- &devnum) != 0) {
- b++;
- index = 0;
- continue;
- }
- hwconf.pciInfo.busNum = busnum;
- hwconf.pciInfo.devNum = devnum;
- printk("Found MOXA %s board(BusNo=%d,DevNo=%d)\n", mxser_brdname[mxser_pcibrds[b].board_type - 1], busnum, devnum >> 3);
- index++;
+ pdev = pci_find_device(mxser_pcibrds[b].vendor_id,
+ mxser_pcibrds[b].device_id, pdev);
+ if (!pdev)
+ break;
+ b++;
+ hwconf.pdev = pdev;
+ printk("Found MOXA %s board(BusNo=%d,DevNo=%d)\n",
+ mxser_brdname[mxser_pcibrds[b].board_type - 1],
+ pdev->bus->number, PCI_SLOT(pdev->devfn >> 3));
if (m >= MXSER_BOARDS) {
printk("Too many Smartio family boards find (maximum %d),board not configured\n", MXSER_BOARDS);
} else {
- retval = mxser_get_PCI_conf(busnum, devnum,
+ retval = mxser_get_PCI_conf(pdev,
mxser_pcibrds[b].board_type, &hwconf);
if (retval < 0) {
if (retval == MXSER_ERR_IRQ)
return node;
err_out_unregister:
- unregister_serial(0x40 + line);
+ unregister_serial(line);
err_out:
MOD_DEC_USE_COUNT;
return NULL;
char device_name[25]; /* device instance name */
unsigned int bus_type; /* expansion bus type (ISA,EISA,PCI) */
- unsigned char bus; /* expansion bus number (zero based) */
- unsigned char function; /* PCI device number */
+ struct pci_dev *pdev; /* pointer to PCI device info */
unsigned int io_base; /* base I/O address of adapter */
unsigned int io_addr_size; /* size of the I/O address range */
#ifdef CONFIG_PCI
/* Auto detect PCI adapters */
- if ( pcibios_present() ) {
- unsigned char bus;
- unsigned char func;
+ {
unsigned int shared_mem_base;
unsigned int lcr_mem_base;
unsigned int io_base;
unsigned char irq_line;
+ struct pci_dev *pdev = NULL;
- for(i=0;;i++){
- if ( PCIBIOS_SUCCESSFUL == pcibios_find_device(
- MICROGATE_VENDOR_ID, SYNCLINK_DEVICE_ID, i, &bus, &func) ) {
+ while ((pdev = pci_find_device(
+ MICROGATE_VENDOR_ID, SYNCLINK_DEVICE_ID, pdev))) {
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
- struct pci_dev *pdev = pci_find_slot(bus,func);
irq_line = pdev->irq;
-#else
- if (pcibios_read_config_byte(bus,func,
- PCI_INTERRUPT_LINE,&irq_line) ) {
- printk( "%s(%d):USC I/O addr not set.\n",
- __FILE__,__LINE__);
- continue;
- }
-#endif
- if (pcibios_read_config_dword(bus,func,
- PCI_BASE_ADDRESS_3,&shared_mem_base) ) {
- printk( "%s(%d):Shared mem addr not set.\n",
- __FILE__,__LINE__);
- continue;
- }
-
- if (pcibios_read_config_dword(bus,func,
- PCI_BASE_ADDRESS_0,&lcr_mem_base) ) {
- printk( "%s(%d):LCR mem addr not set.\n",
- __FILE__,__LINE__);
- continue;
- }
-
- if (pcibios_read_config_dword(bus,func,
- PCI_BASE_ADDRESS_2,&io_base) ) {
- printk( "%s(%d):USC I/O addr not set.\n",
- __FILE__,__LINE__);
+ shared_mem_base = pci_resource_start (pdev, 3);
+ lcr_mem_base = pci_resource_start (pdev, 0);
+ io_base = pci_resource_start (pdev, 2);
+
+ if (pci_enable_device (pdev))
continue;
- }
info = mgsl_allocate_device();
if ( !info ) {
/* Copy user configuration info to device instance data */
- info->io_base = io_base & PCI_BASE_ADDRESS_IO_MASK;
+ info->io_base = io_base;
info->irq_level = (unsigned int)irq_line;
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
info->irq_level = irq_cannonicalize(info->irq_level);
-#else
- if (info->irq_level == 2)
- info->irq_level = 9;
-#endif
- info->phys_memory_base = shared_mem_base & PCI_BASE_ADDRESS_MEM_MASK;
+ info->phys_memory_base = shared_mem_base;
/* Because veremap only works on page boundaries we must map
* a larger area than is actually implemented for the LCR
* memory range. We map a full page starting at the page boundary.
*/
- info->phys_lcr_base = lcr_mem_base & PCI_BASE_ADDRESS_MEM_MASK;
+ info->phys_lcr_base = lcr_mem_base;
info->lcr_offset = info->phys_lcr_base & (PAGE_SIZE-1);
info->phys_lcr_base &= ~(PAGE_SIZE-1);
info->bus_type = MGSL_BUS_TYPE_PCI;
info->io_addr_size = 8;
info->irq_flags = SA_SHIRQ;
- info->bus = bus;
- info->function = func;
+ info->pdev = pdev;
/* override default max frame size if arg available */
if ( num_devices < MAX_TOTAL_DEVICES &&
/* add new device to device list */
mgsl_add_device( info );
- } else {
- break;
- }
}
}
#endif
#ifdef CONFIG_FDDI
case I2O_LAN_FDDI:
{
- int size = sizeof(struct net_device) + sizeof(struct i2o_lan_local)
- + sizeof("fddi%d ");
+ int size = sizeof(struct net_device) + sizeof(struct i2o_lan_local);
dev = (struct net_device *) kmalloc(size, GFP_KERNEL);
if (dev == NULL)
return NULL;
memset((char *)dev, 0, size);
dev->priv = (void *)(dev + 1);
- dev->name = (char *)(dev + 1) + sizeof(struct i2o_lan_local);
if (dev_alloc_name(dev, "fddi%d") < 0) {
printk(KERN_WARNING "i2o_lan: Too many FDDI devices.\n");
MBDBG("mediabay%d: powering up\n", which);
} else {
feature_clear(mb->dev_node, FEATURE_Mediabay_floppy_enable);
- feature_clear(mb->dev_node, FEATURE_Mediabay_IDE_enable);
+ feature_clear(mb->dev_node, FEATURE_IDE1_enable);
feature_clear(mb->dev_node, FEATURE_Mediabay_PCI_enable);
feature_clear(mb->dev_node, FEATURE_SWIM3_enable);
feature_clear(mb->dev_node, FEATURE_Mediabay_power);
switch (id) {
case MB_CD:
- feature_set(bay->dev_node, FEATURE_Mediabay_IDE_enable);
+ feature_set(bay->dev_node, FEATURE_IDE1_enable);
udelay(10);
- feature_set(bay->dev_node, FEATURE_Mediabay_IDE_reset);
+ feature_set(bay->dev_node, FEATURE_IDE1_reset);
printk(KERN_INFO "media bay %d contains a CD-ROM drive\n", which);
break;
case MB_FD:
}
#ifdef CONFIG_BLK_DEV_IDE
MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id);
- feature_clear(bay->dev_node, FEATURE_Mediabay_IDE_reset);
+ feature_clear(bay->dev_node, FEATURE_IDE1_reset);
bay->timer = MS_TO_HZ(MB_IDE_WAIT);
bay->state = mb_ide_resetting;
#else
#include <linux/delay.h>
-static char *version __devinitdata =
+static char version[] __devinitdata =
"3c59x.c:v0.99L+LK1.1.5 30 Apr 2000 Donald Becker and others http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html " "$Revision: 1.78 $\n";
MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
}
/* wake up and enable device */
- if ((retval = pci_enable_device(pdev))) {
- printk (KERN_ERR "%s: Cannot enable device, aborting\n", dev->name);
+ if (pci_enable_device (pdev)) {
+ retval = -EIO;
goto free_region;
}
{
int rc;
- MOD_INC_USE_COUNT;
-
rc = pci_module_init (&vortex_driver);
if (rc < 0)
goto out;
vortex_have_eisa = 1;
out:
- MOD_DEC_USE_COUNT;
return rc;
}
if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
tristate ' 3c501 "EtherLink" support' CONFIG_EL1
tristate ' 3c503 "EtherLink II" support' CONFIG_EL2
- tristate ' 3c505 "Etherlink Plus" support' CONFIG_ELPLUS
+ tristate ' 3c505 "EtherLink Plus" support' CONFIG_ELPLUS
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate ' 3c507 support (EXPERIMENTAL)' CONFIG_EL16
fi
- tristate ' 3c509/3c529 (MCA)/3c579 "Etherlink III" support' CONFIG_EL3
+ tristate ' 3c509/3c529 (MCA)/3c579 "EtherLink III" support' CONFIG_EL3
tristate ' 3c515 ISA Fast EtherLink' CONFIG_3C515
if [ "$CONFIG_MCA" = "y" ]; then
- tristate ' 3c523 support' CONFIG_ELMC
+ tristate ' 3c523 EtherLinkMC support' CONFIG_ELMC
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate ' 3c527 support (EXPERIMENTAL)' CONFIG_ELMC_II
+ tristate ' 3c527 EtherLink/MC 32 support (EXPERIMENTAL)' CONFIG_ELMC_II
fi
fi
tristate ' 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
+#include <linux/spinlock.h>
#include <asm/bitops.h>
#include <asm/io.h>
-#include <asm/spinlock.h>
/* These identify the driver base version and may not be removed. */
-static const char version[] __devinitdata =
+static char version[] __devinitdata =
"epic100.c:v1.09+LK1.1.2 4/28/2000 Written by Donald Becker <becker@scyld.com>\n";
-static const char version2[] __devinitdata =
+static char version2[] __devinitdata =
" http://www.scyld.com/network/epic100.html\n";
#define EPIC100_MODULE_NAME "epic100"
cli();
{
struct tok_info *ti = (struct tok_info *)dev->priv;
- if (ti->tr_timer.next) del_timer(&(ti->tr_timer));
+ if (timer_pending(&ti->tr_timer)) del_timer(&ti->tr_timer);
}
if (link->state & DEV_RELEASE_PENDING) {
del_timer(&link->release);
dev->do_ioctl = &netwave_ioctl;
ether_setup(dev);
- strcpy(dev->name, priv->node.dev_name)
+ strcpy(dev->name, priv->node.dev_name);
dev->init = &netwave_init;
dev->open = &netwave_open;
dev->stop = &netwave_close;
#include <asm/io.h>
/* These identify the driver base version and may not be removed. */
-static const char version1[] __devinitdata =
+static char version1[] __devinitdata =
"starfire.c:v0.15+LK1.1.2 4/28/2000 Written by Donald Becker <becker@scyld.com>\n";
-static const char version2[] __devinitdata =
+static char version2[] __devinitdata =
" Undates and info at http://www.scyld.com/network/starfire.html\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
#include <asm/io.h>
/* These identify the driver base version and may not be removed. */
-static const char version1[] __devinitdata =
+static char version1[] __devinitdata =
"via-rhine.c:v1.05-LK1.1.5 5/2/2000 Written by Donald Becker\n";
-static const char version2[] __devinitdata =
+static char version2[] __devinitdata =
" http://www.scyld.com/network/via-rhine.html\n";
void vfc_i2c_delay_no_busy(struct vfc_dev *dev, unsigned long usecs)
{
- dev->poll_timer.next = NULL;
- dev->poll_timer.prev = NULL;
+ init_timer(&dev->poll_timer);
dev->poll_timer.expires = jiffies +
((unsigned long)usecs*(HZ))/1000000;
dev->poll_timer.data=(unsigned long)dev;
+++ /dev/null
-/*********************************************************/
-/* This file was written by someone, somewhere, sometime */
-/* And is released into the Public Domain */
-/*********************************************************/
-
-#ifndef _AWACS_DEFS_H_
-#define _AWACS_DEFS_H_
-
-/*******************************/
-/* AWACs Audio Register Layout */
-/*******************************/
-
-struct awacs_regs {
- unsigned control; /* Audio control register */
- unsigned pad0[3];
- unsigned codec_ctrl; /* Codec control register */
- unsigned pad1[3];
- unsigned codec_stat; /* Codec status register */
- unsigned pad2[3];
- unsigned clip_count; /* Clipping count register */
- unsigned pad3[3];
- unsigned byteswap; /* Data is little-endian if 1 */
-};
-
-/*******************/
-/* Audio Bit Masks */
-/*******************/
-
-/* Audio Control Reg Bit Masks */
-/* ----- ------- --- --- ----- */
-#define MASK_ISFSEL (0xf) /* Input SubFrame Select */
-#define MASK_OSFSEL (0xf << 4) /* Output SubFrame Select */
-#define MASK_RATE (0x7 << 8) /* Sound Rate */
-#define MASK_CNTLERR (0x1 << 11) /* Error */
-#define MASK_PORTCHG (0x1 << 12) /* Port Change */
-#define MASK_IEE (0x1 << 13) /* Enable Interrupt on Error */
-#define MASK_IEPC (0x1 << 14) /* Enable Interrupt on Port Change */
-#define MASK_SSFSEL (0x3 << 15) /* Status SubFrame Select */
-
-/* Audio Codec Control Reg Bit Masks */
-/* ----- ----- ------- --- --- ----- */
-#define MASK_NEWECMD (0x1 << 24) /* Lock: don't write to reg when 1 */
-#define MASK_EMODESEL (0x3 << 22) /* Send info out on which frame? */
-#define MASK_EXMODEADDR (0x3ff << 12) /* Extended Mode Address -- 10 bits */
-#define MASK_EXMODEDATA (0xfff) /* Extended Mode Data -- 12 bits */
-
-/* Audio Codec Control Address Values / Masks */
-/* ----- ----- ------- ------- ------ - ----- */
-#define MASK_ADDR0 (0x0 << 12) /* Expanded Data Mode Address 0 */
-#define MASK_ADDR_MUX MASK_ADDR0 /* Mux Control */
-#define MASK_ADDR_GAIN MASK_ADDR0
-
-#define MASK_ADDR1 (0x1 << 12) /* Expanded Data Mode Address 1 */
-#define MASK_ADDR_MUTE MASK_ADDR1
-#define MASK_ADDR_RATE MASK_ADDR1
-
-#define MASK_ADDR2 (0x2 << 12) /* Expanded Data Mode Address 2 */
-#define MASK_ADDR_VOLA MASK_ADDR2 /* Volume Control A -- Headphones */
-#define MASK_ADDR_VOLHD MASK_ADDR2
-
-#define MASK_ADDR4 (0x4 << 12) /* Expanded Data Mode Address 4 */
-#define MASK_ADDR_VOLC MASK_ADDR4 /* Volume Control C -- Speaker */
-#define MASK_ADDR_VOLSPK MASK_ADDR4
-
-/* Address 0 Bit Masks & Macros */
-/* ------- - --- ----- - ------ */
-#define MASK_GAINRIGHT (0xf) /* Gain Right Mask */
-#define MASK_GAINLEFT (0xf << 4) /* Gain Left Mask */
-#define MASK_GAINLINE (0x1 << 8) /* Change Gain for Line??? */
-#define MASK_GAINMIC (0x0 << 8) /* Change Gain for Mic??? */
-
-#define MASK_MUX_CD (0x1 << 9) /* Select CD in MUX */
-#define MASK_MUX_AUDIN (0x1 << 10) /* Select Audio In in MUX */
-#define MASK_MUX_MIC (0x1 << 11) /* Select Mic in MUX */
-#define MASK_MUX_LINE MASK_MUX_AUDIN
-
-#define GAINRIGHT(x) ((x) & MASK_GAINRIGHT)
-#define GAINLEFT(x) (((x) << 4) & MASK_GAINLEFT)
-
-/* Address 1 Bit Masks */
-/* ------- - --- ----- */
-#define MASK_ADDR1RES1 (0x3) /* Reserved */
-#define MASK_RECALIBRATE (0x1 << 2) /* Recalibrate */
-#define MASK_SAMPLERATE (0x7 << 3) /* Sample Rate: */
-#define MASK_LOOPTHRU (0x1 << 6) /* Loopthrough Enable */
-#define MASK_CMUTE (0x1 << 7) /* Output C (Speaker) Mute when 1 */
-#define MASK_SPKMUTE MASK_CMUTE
-#define MASK_ADDR1RES2 (0x1 << 8) /* Reserved */
-#define MASK_AMUTE (0x1 << 9) /* Output A (Headphone) Mute when 1 */
-#define MASK_HDMUTE MASK_AMUTE
-#define MASK_PAROUT (0x3 << 10) /* Parallel Out (???) */
-
-#define SAMPLERATE_48000 (0x0 << 3) /* 48 or 44.1 kHz */
-#define SAMPLERATE_32000 (0x1 << 3) /* 32 or 29.4 kHz */
-#define SAMPLERATE_24000 (0x2 << 3) /* 24 or 22.05 kHz */
-#define SAMPLERATE_19200 (0x3 << 3) /* 19.2 or 17.64 kHz */
-#define SAMPLERATE_16000 (0x4 << 3) /* 16 or 14.7 kHz */
-#define SAMPLERATE_12000 (0x5 << 3) /* 12 or 11.025 kHz */
-#define SAMPLERATE_9600 (0x6 << 3) /* 9.6 or 8.82 kHz */
-#define SAMPLERATE_8000 (0x7 << 3) /* 8 or 7.35 kHz */
-
-/* Address 2 & 4 Bit Masks & Macros */
-/* ------- - - - --- ----- - ------ */
-#define MASK_OUTVOLRIGHT (0xf) /* Output Right Volume */
-#define MASK_ADDR2RES1 (0x2 << 4) /* Reserved */
-#define MASK_ADDR4RES1 MASK_ADDR2RES1
-#define MASK_OUTVOLLEFT (0xf << 6) /* Output Left Volume */
-#define MASK_ADDR2RES2 (0x2 << 10) /* Reserved */
-#define MASK_ADDR4RES2 MASK_ADDR2RES2
-
-#define VOLRIGHT(x) (((~(x)) & MASK_OUTVOLRIGHT))
-#define VOLLEFT(x) (((~(x)) << 6) & MASK_OUTVOLLEFT)
-
-/* Audio Codec Status Reg Bit Masks */
-/* ----- ----- ------ --- --- ----- */
-#define MASK_EXTEND (0x1 << 23) /* Extend */
-#define MASK_VALID (0x1 << 22) /* Valid Data? */
-#define MASK_OFLEFT (0x1 << 21) /* Overflow Left */
-#define MASK_OFRIGHT (0x1 << 20) /* Overflow Right */
-#define MASK_ERRCODE (0xf << 16) /* Error Code */
-#define MASK_REVISION (0xf << 12) /* Revision Number */
-#define MASK_MFGID (0xf << 8) /* Mfg. ID */
-#define MASK_CODSTATRES (0xf << 4) /* bits 4 - 7 reserved */
-#define MASK_INPPORT (0xf) /* Input Port */
-#define MASK_HDPCONN 8 /* headphone plugged in */
-
-/* Clipping Count Reg Bit Masks */
-/* -------- ----- --- --- ----- */
-#define MASK_CLIPLEFT (0xff << 7) /* Clipping Count, Left Channel */
-#define MASK_CLIPRIGHT (0xff) /* Clipping Count, Right Channel */
-
-/* DBDMA ChannelStatus Bit Masks */
-/* ----- ------------- --- ----- */
-#define MASK_CSERR (0x1 << 7) /* Error */
-#define MASK_EOI (0x1 << 6) /* End of Input -- only for Input Channel */
-#define MASK_CSUNUSED (0x1f << 1) /* bits 1-5 not used */
-#define MASK_WAIT (0x1) /* Wait */
-
-/* Various Rates */
-/* ------- ----- */
-#define RATE_48000 (0x0 << 8) /* 48 kHz */
-#define RATE_44100 (0x0 << 8) /* 44.1 kHz */
-#define RATE_32000 (0x1 << 8) /* 32 kHz */
-#define RATE_29400 (0x1 << 8) /* 29.4 kHz */
-#define RATE_24000 (0x2 << 8) /* 24 kHz */
-#define RATE_22050 (0x2 << 8) /* 22.05 kHz */
-#define RATE_19200 (0x3 << 8) /* 19.2 kHz */
-#define RATE_17640 (0x3 << 8) /* 17.64 kHz */
-#define RATE_16000 (0x4 << 8) /* 16 kHz */
-#define RATE_14700 (0x4 << 8) /* 14.7 kHz */
-#define RATE_12000 (0x5 << 8) /* 12 kHz */
-#define RATE_11025 (0x5 << 8) /* 11.025 kHz */
-#define RATE_9600 (0x6 << 8) /* 9.6 kHz */
-#define RATE_8820 (0x6 << 8) /* 8.82 kHz */
-#define RATE_8000 (0x7 << 8) /* 8 kHz */
-#define RATE_7350 (0x7 << 8) /* 7.35 kHz */
-
-#define RATE_LOW 1 /* HIGH = 48kHz, etc; LOW = 44.1kHz, etc. */
-
-
-/* Burgundy values */
-
-#define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12)
-#define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12)
-
-#define MASK_ADDR_BURGUNDY_GAINCH1 (0x13 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH2 (0x14 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH3 (0x15 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH4 (0x16 << 12)
-
-#define MASK_ADDR_BURGUNDY_VOLCH1 (0x20 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH2 (0x21 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH3 (0x22 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH4 (0x23 << 12)
-
-#define MASK_ADDR_BURGUNDY_OUTPUTSELECTS (0x2B << 12)
-#define MASK_ADDR_BURGUNDY_OUTPUTENABLES (0x2F << 12)
-
-#define MASK_ADDR_BURGUNDY_MASTER_VOLUME (0x30 << 12)
-
-#define MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES (0x60 << 12)
-
-#define MASK_ADDR_BURGUNDY_ATTENSPEAKER (0x62 << 12)
-#define MASK_ADDR_BURGUNDY_ATTENLINEOUT (0x63 << 12)
-#define MASK_ADDR_BURGUNDY_ATTENHP (0x64 << 12)
-
-#define MASK_ADDR_BURGUNDY_VOLCD (MASK_ADDR_BURGUNDY_VOLCH1)
-#define MASK_ADDR_BURGUNDY_VOLLINE (MASK_ADDR_BURGUNDY_VOLCH2)
-#define MASK_ADDR_BURGUNDY_VOLMIC (MASK_ADDR_BURGUNDY_VOLCH3)
-#define MASK_ADDR_BURGUNDY_VOLMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
-
-#define MASK_ADDR_BURGUNDY_GAINCD (MASK_ADDR_BURGUNDY_GAINCH1)
-#define MASK_ADDR_BURGUNDY_GAINLINE (MASK_ADDR_BURGUNDY_GAINCH2)
-#define MASK_ADDR_BURGUNDY_GAINMIC (MASK_ADDR_BURGUNDY_GAINCH3)
-#define MASK_ADDR_BURGUNDY_GAINMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
-
-
-/* These are all default values for the burgundy */
-#define DEF_BURGUNDY_INPSEL21 (0xAA)
-#define DEF_BURGUNDY_INPSEL3 (0x0A)
-
-#define DEF_BURGUNDY_GAINCD (0x33)
-#define DEF_BURGUNDY_GAINLINE (0x44)
-#define DEF_BURGUNDY_GAINMIC (0x44)
-#define DEF_BURGUNDY_GAINMODEM (0x06)
-
-/* Remember: lowest volume here is 0x9b */
-#define DEF_BURGUNDY_VOLCD (0xCCCCCCCC)
-#define DEF_BURGUNDY_VOLLINE (0x00000000)
-#define DEF_BURGUNDY_VOLMIC (0x00000000)
-#define DEF_BURGUNDY_VOLMODEM (0xCCCCCCCC)
-
-#define DEF_BURGUNDY_OUTPUTSELECTS (0x010f010f)
-#define DEF_BURGUNDY_OUTPUTENABLES (0x0A)
-
-#define DEF_BURGUNDY_MASTER_VOLUME (0xFFFFFFFF)
-
-#define DEF_BURGUNDY_MORE_OUTPUTENABLES (0x7E)
-
-#define DEF_BURGUNDY_ATTENSPEAKER (0x44)
-#define DEF_BURGUNDY_ATTENLINEOUT (0xCC)
-#define DEF_BURGUNDY_ATTENHP (0xCC)
-
-#endif /* _AWACS_DEFS_H_ */
--- /dev/null
+/*********************************************************/
+/* This file was written by someone, somewhere, sometime */
+/* And is released into the Public Domain */
+/*********************************************************/
+
+#ifndef _AWACS_DEFS_H_
+#define _AWACS_DEFS_H_
+
+/*******************************/
+/* AWACs Audio Register Layout */
+/*******************************/
+
+struct awacs_regs {
+ unsigned control; /* Audio control register */
+ unsigned pad0[3];
+ unsigned codec_ctrl; /* Codec control register */
+ unsigned pad1[3];
+ unsigned codec_stat; /* Codec status register */
+ unsigned pad2[3];
+ unsigned clip_count; /* Clipping count register */
+ unsigned pad3[3];
+ unsigned byteswap; /* Data is little-endian if 1 */
+};
+
+/*******************/
+/* Audio Bit Masks */
+/*******************/
+
+/* Audio Control Reg Bit Masks */
+/* ----- ------- --- --- ----- */
+#define MASK_ISFSEL (0xf) /* Input SubFrame Select */
+#define MASK_OSFSEL (0xf << 4) /* Output SubFrame Select */
+#define MASK_RATE (0x7 << 8) /* Sound Rate */
+#define MASK_CNTLERR (0x1 << 11) /* Error */
+#define MASK_PORTCHG (0x1 << 12) /* Port Change */
+#define MASK_IEE (0x1 << 13) /* Enable Interrupt on Error */
+#define MASK_IEPC (0x1 << 14) /* Enable Interrupt on Port Change */
+#define MASK_SSFSEL (0x3 << 15) /* Status SubFrame Select */
+
+/* Audio Codec Control Reg Bit Masks */
+/* ----- ----- ------- --- --- ----- */
+#define MASK_NEWECMD (0x1 << 24) /* Lock: don't write to reg when 1 */
+#define MASK_EMODESEL (0x3 << 22) /* Send info out on which frame? */
+#define MASK_EXMODEADDR (0x3ff << 12) /* Extended Mode Address -- 10 bits */
+#define MASK_EXMODEDATA (0xfff) /* Extended Mode Data -- 12 bits */
+
+/* Audio Codec Control Address Values / Masks */
+/* ----- ----- ------- ------- ------ - ----- */
+#define MASK_ADDR0 (0x0 << 12) /* Expanded Data Mode Address 0 */
+#define MASK_ADDR_MUX MASK_ADDR0 /* Mux Control */
+#define MASK_ADDR_GAIN MASK_ADDR0
+
+#define MASK_ADDR1 (0x1 << 12) /* Expanded Data Mode Address 1 */
+#define MASK_ADDR_MUTE MASK_ADDR1
+#define MASK_ADDR_RATE MASK_ADDR1
+
+#define MASK_ADDR2 (0x2 << 12) /* Expanded Data Mode Address 2 */
+#define MASK_ADDR_VOLA MASK_ADDR2 /* Volume Control A -- Headphones */
+#define MASK_ADDR_VOLHD MASK_ADDR2
+
+#define MASK_ADDR4 (0x4 << 12) /* Expanded Data Mode Address 4 */
+#define MASK_ADDR_VOLC MASK_ADDR4 /* Volume Control C -- Speaker */
+#define MASK_ADDR_VOLSPK MASK_ADDR4
+
+/* Address 0 Bit Masks & Macros */
+/* ------- - --- ----- - ------ */
+#define MASK_GAINRIGHT (0xf) /* Gain Right Mask */
+#define MASK_GAINLEFT (0xf << 4) /* Gain Left Mask */
+#define MASK_GAINLINE (0x1 << 8) /* Change Gain for Line??? */
+#define MASK_GAINMIC (0x0 << 8) /* Change Gain for Mic??? */
+
+#define MASK_MUX_CD (0x1 << 9) /* Select CD in MUX */
+#define MASK_MUX_AUDIN (0x1 << 10) /* Select Audio In in MUX */
+#define MASK_MUX_MIC (0x1 << 11) /* Select Mic in MUX */
+#define MASK_MUX_LINE MASK_MUX_AUDIN
+
+#define GAINRIGHT(x) ((x) & MASK_GAINRIGHT)
+#define GAINLEFT(x) (((x) << 4) & MASK_GAINLEFT)
+
+/* Address 1 Bit Masks */
+/* ------- - --- ----- */
+#define MASK_ADDR1RES1 (0x3) /* Reserved */
+#define MASK_RECALIBRATE (0x1 << 2) /* Recalibrate */
+#define MASK_SAMPLERATE (0x7 << 3) /* Sample Rate: */
+#define MASK_LOOPTHRU (0x1 << 6) /* Loopthrough Enable */
+#define MASK_CMUTE (0x1 << 7) /* Output C (Speaker) Mute when 1 */
+#define MASK_SPKMUTE MASK_CMUTE
+#define MASK_ADDR1RES2 (0x1 << 8) /* Reserved */
+#define MASK_AMUTE (0x1 << 9) /* Output A (Headphone) Mute when 1 */
+#define MASK_HDMUTE MASK_AMUTE
+#define MASK_PAROUT (0x3 << 10) /* Parallel Out (???) */
+
+#define SAMPLERATE_48000 (0x0 << 3) /* 48 or 44.1 kHz */
+#define SAMPLERATE_32000 (0x1 << 3) /* 32 or 29.4 kHz */
+#define SAMPLERATE_24000 (0x2 << 3) /* 24 or 22.05 kHz */
+#define SAMPLERATE_19200 (0x3 << 3) /* 19.2 or 17.64 kHz */
+#define SAMPLERATE_16000 (0x4 << 3) /* 16 or 14.7 kHz */
+#define SAMPLERATE_12000 (0x5 << 3) /* 12 or 11.025 kHz */
+#define SAMPLERATE_9600 (0x6 << 3) /* 9.6 or 8.82 kHz */
+#define SAMPLERATE_8000 (0x7 << 3) /* 8 or 7.35 kHz */
+
+/* Address 2 & 4 Bit Masks & Macros */
+/* ------- - - - --- ----- - ------ */
+#define MASK_OUTVOLRIGHT (0xf) /* Output Right Volume */
+#define MASK_ADDR2RES1 (0x2 << 4) /* Reserved */
+#define MASK_ADDR4RES1 MASK_ADDR2RES1
+#define MASK_OUTVOLLEFT (0xf << 6) /* Output Left Volume */
+#define MASK_ADDR2RES2 (0x2 << 10) /* Reserved */
+#define MASK_ADDR4RES2 MASK_ADDR2RES2
+
+#define VOLRIGHT(x) (((~(x)) & MASK_OUTVOLRIGHT))
+#define VOLLEFT(x) (((~(x)) << 6) & MASK_OUTVOLLEFT)
+
+/* Audio Codec Status Reg Bit Masks */
+/* ----- ----- ------ --- --- ----- */
+#define MASK_EXTEND (0x1 << 23) /* Extend */
+#define MASK_VALID (0x1 << 22) /* Valid Data? */
+#define MASK_OFLEFT (0x1 << 21) /* Overflow Left */
+#define MASK_OFRIGHT (0x1 << 20) /* Overflow Right */
+#define MASK_ERRCODE (0xf << 16) /* Error Code */
+#define MASK_REVISION (0xf << 12) /* Revision Number */
+#define MASK_MFGID (0xf << 8) /* Mfg. ID */
+#define MASK_CODSTATRES (0xf << 4) /* bits 4 - 7 reserved */
+#define MASK_INPPORT (0xf) /* Input Port */
+#define MASK_HDPCONN 8 /* headphone plugged in */
+
+/* Clipping Count Reg Bit Masks */
+/* -------- ----- --- --- ----- */
+#define MASK_CLIPLEFT (0xff << 7) /* Clipping Count, Left Channel */
+#define MASK_CLIPRIGHT (0xff) /* Clipping Count, Right Channel */
+
+/* DBDMA ChannelStatus Bit Masks */
+/* ----- ------------- --- ----- */
+#define MASK_CSERR (0x1 << 7) /* Error */
+#define MASK_EOI (0x1 << 6) /* End of Input -- only for Input Channel */
+#define MASK_CSUNUSED (0x1f << 1) /* bits 1-5 not used */
+#define MASK_WAIT (0x1) /* Wait */
+
+/* Various Rates */
+/* ------- ----- */
+#define RATE_48000 (0x0 << 8) /* 48 kHz */
+#define RATE_44100 (0x0 << 8) /* 44.1 kHz */
+#define RATE_32000 (0x1 << 8) /* 32 kHz */
+#define RATE_29400 (0x1 << 8) /* 29.4 kHz */
+#define RATE_24000 (0x2 << 8) /* 24 kHz */
+#define RATE_22050 (0x2 << 8) /* 22.05 kHz */
+#define RATE_19200 (0x3 << 8) /* 19.2 kHz */
+#define RATE_17640 (0x3 << 8) /* 17.64 kHz */
+#define RATE_16000 (0x4 << 8) /* 16 kHz */
+#define RATE_14700 (0x4 << 8) /* 14.7 kHz */
+#define RATE_12000 (0x5 << 8) /* 12 kHz */
+#define RATE_11025 (0x5 << 8) /* 11.025 kHz */
+#define RATE_9600 (0x6 << 8) /* 9.6 kHz */
+#define RATE_8820 (0x6 << 8) /* 8.82 kHz */
+#define RATE_8000 (0x7 << 8) /* 8 kHz */
+#define RATE_7350 (0x7 << 8) /* 7.35 kHz */
+
+#define RATE_LOW 1 /* HIGH = 48kHz, etc; LOW = 44.1kHz, etc. */
+
+
+/* Burgundy values */
+
+#define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12)
+#define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12)
+
+#define MASK_ADDR_BURGUNDY_GAINCH1 (0x13 << 12)
+#define MASK_ADDR_BURGUNDY_GAINCH2 (0x14 << 12)
+#define MASK_ADDR_BURGUNDY_GAINCH3 (0x15 << 12)
+#define MASK_ADDR_BURGUNDY_GAINCH4 (0x16 << 12)
+
+#define MASK_ADDR_BURGUNDY_VOLCH1 (0x20 << 12)
+#define MASK_ADDR_BURGUNDY_VOLCH2 (0x21 << 12)
+#define MASK_ADDR_BURGUNDY_VOLCH3 (0x22 << 12)
+#define MASK_ADDR_BURGUNDY_VOLCH4 (0x23 << 12)
+
+#define MASK_ADDR_BURGUNDY_OUTPUTSELECTS (0x2B << 12)
+#define MASK_ADDR_BURGUNDY_OUTPUTENABLES (0x2F << 12)
+
+#define MASK_ADDR_BURGUNDY_MASTER_VOLUME (0x30 << 12)
+
+#define MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES (0x60 << 12)
+
+#define MASK_ADDR_BURGUNDY_ATTENSPEAKER (0x62 << 12)
+#define MASK_ADDR_BURGUNDY_ATTENLINEOUT (0x63 << 12)
+#define MASK_ADDR_BURGUNDY_ATTENHP (0x64 << 12)
+
+#define MASK_ADDR_BURGUNDY_VOLCD (MASK_ADDR_BURGUNDY_VOLCH1)
+#define MASK_ADDR_BURGUNDY_VOLLINE (MASK_ADDR_BURGUNDY_VOLCH2)
+#define MASK_ADDR_BURGUNDY_VOLMIC (MASK_ADDR_BURGUNDY_VOLCH3)
+#define MASK_ADDR_BURGUNDY_VOLMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
+
+#define MASK_ADDR_BURGUNDY_GAINCD (MASK_ADDR_BURGUNDY_GAINCH1)
+#define MASK_ADDR_BURGUNDY_GAINLINE (MASK_ADDR_BURGUNDY_GAINCH2)
+#define MASK_ADDR_BURGUNDY_GAINMIC (MASK_ADDR_BURGUNDY_GAINCH3)
+#define MASK_ADDR_BURGUNDY_GAINMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
+
+
+/* These are all default values for the burgundy */
+#define DEF_BURGUNDY_INPSEL21 (0xAA)
+#define DEF_BURGUNDY_INPSEL3 (0x0A)
+
+#define DEF_BURGUNDY_GAINCD (0x33)
+#define DEF_BURGUNDY_GAINLINE (0x44)
+#define DEF_BURGUNDY_GAINMIC (0x44)
+#define DEF_BURGUNDY_GAINMODEM (0x06)
+
+/* Remember: lowest volume here is 0x9b */
+#define DEF_BURGUNDY_VOLCD (0xCCCCCCCC)
+#define DEF_BURGUNDY_VOLLINE (0x00000000)
+#define DEF_BURGUNDY_VOLMIC (0x00000000)
+#define DEF_BURGUNDY_VOLMODEM (0xCCCCCCCC)
+
+#define DEF_BURGUNDY_OUTPUTSELECTS (0x010f010f)
+#define DEF_BURGUNDY_OUTPUTENABLES (0x0A)
+
+#define DEF_BURGUNDY_MASTER_VOLUME (0xFFFFFFFF)
+
+#define DEF_BURGUNDY_MORE_OUTPUTENABLES (0x7E)
+
+#define DEF_BURGUNDY_ATTENSPEAKER (0x44)
+#define DEF_BURGUNDY_ATTENLINEOUT (0xCC)
+#define DEF_BURGUNDY_ATTENHP (0xCC)
+
+#endif /* _AWACS_DEFS_H_ */
# ':' <len> <addr> <type> <len-data> <crc> '\r'
# len, type, crc are 2-char hex, addr is 4-char hex. type is 00 for
# normal records, 01 for EOF
- my($lenstring, $addrstring, $typestring, $reststring) =
- /^:(\w\w)(\w\w\w\w)(\w\w)(\w+)$/;
+ my($lenstring, $addrstring, $typestring, $reststring, $doscrap) =
+ /^:(\w\w)(\w\w\w\w)(\w\w)(\w+)(\r?)$/;
die "malformed line: $_" unless $reststring;
last if $typestring eq '01';
my($len) = hex($lenstring);
/*
* USB FTDI SIO driver
*
- * (C) Copyright (C) 1999, 2000
+ * Copyright (C) 1999, 2000
* Greg Kroah-Hartman (greg@kroah.com)
* Bill Ryder (bryder@sgi.com)
*
/*
* USB Keyspan PDA Converter driver
*
- * (C) Copyright (C) 1999, 2000
+ * Copyright (C) 1999, 2000
* Greg Kroah-Hartman (greg@kroah.com)
*
* This program is free software; you can redistribute it and/or modify
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
+ * Please report both successes and troubles to the author at omninet@kroah.com
+ *
*/
#include <linux/config.h>
/*
* USB Serial Converter driver
*
- * (C) Copyright (C) 1999, 2000
+ * Copyright (C) 1999, 2000
* Greg Kroah-Hartman (greg@kroah.com)
*
* This program is free software; you can redistribute it and/or modify
#include <linux/config.h>
#define SERIAL_TTY_MAJOR 188 /* Nice legal number now */
-#define SERIAL_TTY_MINORS 16 /* Actually we are allowed 255, but this is good for now */
+#define SERIAL_TTY_MINORS 255 /* loads of devices :) */
#define MAX_NUM_PORTS 8 /* The maximum number of ports one device can grab at once */
/*
* USB Serial Converter driver
*
- * (C) Copyright (C) 1999, 2000
+ * Copyright (C) 1999, 2000
* Greg Kroah-Hartman (greg@kroah.com)
*
* This program is free software; you can redistribute it and/or modify
*
* (05/03/2000) gkh
* Added the Digi Acceleport driver from Al Borchers and Peter Berger.
+ *
+ * (05/02/2000) gkh
+ * Changed devfs and tty register code to work properly now. This was based on
+ * the ACM driver changes by Vojtech Pavlik.
*
* (04/27/2000) Ryan VanderBijl
* Put calls to *_paranoia_checks into one function.
};
-/* variables needed for the tty_driver structure */
-static char *driver_name = "usb";
-static char *tty_driver_name = "usb/tty/%d";
-
-
/* local function prototypes */
static int serial_open (struct tty_struct *tty, struct file * filp);
static void serial_close (struct tty_struct *tty, struct file * filp);
};
static int serial_refcount;
+static struct tty_driver serial_tty_driver;
static struct tty_struct * serial_tty[SERIAL_TTY_MINORS];
static struct termios * serial_termios[SERIAL_TTY_MINORS];
static struct termios * serial_termios_locked[SERIAL_TTY_MINORS];
}
-static struct tty_driver * usb_serial_tty_driver_init (struct usb_serial *serial)
-{
- struct tty_driver *serial_tty_driver;
-
- if (!(serial_tty_driver = kmalloc(sizeof(struct tty_driver), GFP_KERNEL))) {
- err("Out of memory");
- return NULL;
- }
-
- memset (serial_tty_driver, 0x00, sizeof(struct tty_driver));
-
- /* initialize the entries that we don't want to be NULL */
- serial_tty_driver->magic = TTY_DRIVER_MAGIC;
- serial_tty_driver->driver_name = driver_name;
- serial_tty_driver->name = tty_driver_name;
- serial_tty_driver->major = SERIAL_TTY_MAJOR;
- serial_tty_driver->minor_start = serial->minor;
- serial_tty_driver->num = serial->num_ports;
- serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
- serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
- serial_tty_driver->flags = TTY_DRIVER_REAL_RAW;
- serial_tty_driver->refcount = &serial_refcount;
- serial_tty_driver->table = serial_tty;
- serial_tty_driver->termios = serial_termios;
- serial_tty_driver->termios_locked = serial_termios_locked;
- serial_tty_driver->open = serial_open;
- serial_tty_driver->close = serial_close;
- serial_tty_driver->write = serial_write;
- serial_tty_driver->write_room = serial_write_room;
- serial_tty_driver->ioctl = serial_ioctl;
- serial_tty_driver->set_termios = serial_set_termios;
- serial_tty_driver->throttle = serial_throttle;
- serial_tty_driver->unthrottle = serial_unthrottle;
- serial_tty_driver->break_ctl = serial_break;
- serial_tty_driver->chars_in_buffer = serial_chars_in_buffer;
- serial_tty_driver->init_termios = tty_std_termios;
- serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-
- return serial_tty_driver;
-}
-
-
static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
{
struct usb_serial *serial = NULL;
serial->num_bulk_out = num_bulk_out;
serial->num_interrupt_in = num_interrupt_in;
- /* initialize a tty_driver for this device */
- serial->tty_driver = usb_serial_tty_driver_init (serial);
- if (serial->tty_driver == NULL) {
- err("Can't create a tty_serial_driver");
- goto probe_error;
- }
-
- if (tty_register_driver (serial->tty_driver)) {
- err("failed to register tty driver");
- goto probe_error;
- }
-
/* if this device type has a startup function, call it */
if (type->startup) {
if (type->startup (serial)) {
max_endpoints = MAX(max_endpoints, num_interrupt_in);
for (i = 0; i < max_endpoints; ++i) {
port = &serial->port[i];
- port->number = i;
+ port->number = i + serial->minor;
port->serial = serial;
port->magic = USB_SERIAL_PORT_MAGIC;
}
+ /* initialize the devfs nodes for this device and let the user know what ports we are bound to */
for (i = 0; i < serial->num_ports; ++i) {
- info("%s converter now attached to ttyUSB%d",
- type->name, serial->minor + i);
+ tty_register_devfs (&serial_tty_driver, 0, serial->port[i].number);
+ info("%s converter now attached to ttyUSB%d (or usb/tts/%d for devfs)",
+ type->name, serial->port[i].number, serial->port[i].number);
}
return serial; /* success */
/* return the minor range that this device had */
return_serial (serial);
- /* if this device has a tty_driver, then unregister it and free it */
- if (serial->tty_driver) {
- tty_unregister_driver (serial->tty_driver);
- kfree (serial->tty_driver);
- serial->tty_driver = NULL;
- }
-
/* free up any memory that we allocated */
kfree (serial);
MOD_DEC_USE_COUNT;
}
for (i = 0; i < serial->num_ports; ++i) {
- info("%s converter now disconnected from ttyUSB%d", serial->type->name, serial->minor + i);
+ tty_unregister_devfs (&serial_tty_driver, serial->port[i].number);
+ info("%s converter now disconnected from ttyUSB%d", serial->type->name, serial->port[i].number);
}
/* return the minor range that this device had */
return_serial (serial);
- /* if this device has a tty_driver, then unregister it and free it */
- if (serial->tty_driver) {
- tty_unregister_driver (serial->tty_driver);
- kfree (serial->tty_driver);
- serial->tty_driver = NULL;
- }
/* free up any memory that we allocated */
kfree (serial);
}
+static struct tty_driver serial_tty_driver = {
+ magic: TTY_DRIVER_MAGIC,
+ driver_name: "usb-serial",
+ name: "usb/tts/%d",
+ major: SERIAL_TTY_MAJOR,
+ minor_start: 0,
+ num: SERIAL_TTY_MINORS,
+ type: TTY_DRIVER_TYPE_SERIAL,
+ subtype: SERIAL_TYPE_NORMAL,
+ flags: TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
+
+ refcount: &serial_refcount,
+ table: serial_tty,
+ termios: serial_termios,
+ termios_locked: serial_termios_locked,
+
+ open: serial_open,
+ close: serial_close,
+ write: serial_write,
+ write_room: serial_write_room,
+ ioctl: serial_ioctl,
+ set_termios: serial_set_termios,
+ throttle: serial_throttle,
+ unthrottle: serial_unthrottle,
+ break_ctl: serial_break,
+ chars_in_buffer: serial_chars_in_buffer,
+};
+
+
int usb_serial_init(void)
{
int i;
if (!something)
info ("USB Serial driver is not configured for any devices!");
+ /* register the tty driver */
+ serial_tty_driver.init_termios = tty_std_termios;
+ serial_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ if (tty_register_driver (&serial_tty_driver)) {
+ err("failed to register tty driver");
+ return -1;
+ }
+
/* register the USB driver */
result = usb_register(&usb_serial_driver);
if (result < 0) {
+ tty_unregister_driver(&serial_tty_driver);
err("usb_register failed for the usb-serial driver. Error number %d", result);
return -1;
}
void usb_serial_exit(void)
{
usb_deregister(&usb_serial_driver);
+ tty_unregister_driver(&serial_tty_driver);
}
/*
* USB HandSpring Visor driver
*
- * (C) Copyright (C) 1999, 2000
+ * Copyright (C) 1999, 2000
* Greg Kroah-Hartman (greg@kroah.com)
*
* This program is free software; you can redistribute it and/or modify
/*
* USB HandSpring Visor driver
*
- * (C) Copyright (C) 1999, 2000
+ * Copyright (C) 1999, 2000
* Greg Kroah-Hartman (greg@kroah.com)
*
* This program is free software; you can redistribute it and/or modify
/*
* USB ConnectTech WhiteHEAT driver
*
- * (C) Copyright (C) 1999, 2000
+ * Copyright (C) 1999, 2000
* Greg Kroah-Hartman (greg@kroah.com)
*
* This program is free software; you can redistribute it and/or modify
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
+ * (05/04/2000) gkh
+ * First cut at open and close commands. Data can flow through the ports at
+ * default speeds now.
+ *
* (03/26/2000) gkh
* Split driver up into device specific pieces.
*
#include "whiteheat_fw.h" /* firmware for the ConnectTech WhiteHEAT device */
+#include "whiteheat.h" /* WhiteHEAT specific commands */
#define CONNECT_TECH_VENDOR_ID 0x0710
#define CONNECT_TECH_FAKE_WHITE_HEAT_ID 0x0001
static void whiteheat_throttle (struct usb_serial_port *port);
static void whiteheat_unthrottle (struct usb_serial_port *port);
static int whiteheat_startup (struct usb_serial *serial);
+static void whiteheat_shutdown (struct usb_serial *serial);
/* All of the device info needed for the Connect Tech WhiteHEAT */
static __u16 connecttech_vendor_id = CONNECT_TECH_VENDOR_ID;
throttle: whiteheat_throttle,
unthrottle: whiteheat_unthrottle,
set_termios: whiteheat_set_termios,
+ shutdown: whiteheat_shutdown,
+};
+
+struct whiteheat_private {
+ __u8 command_finished;
+ wait_queue_head_t wait_command; /* for handling sleeping while waiting for a command to finish */
};
+#define COMMAND_PORT 4
+#define COMMAND_TIMEOUT (2*HZ) /* 2 second timeout for a command */
+
/*****************************************************************************
* Connect Tech's White Heat specific driver functions
*****************************************************************************/
+static void command_port_write_callback (struct urb *urb)
+{
+ unsigned char *data = urb->transfer_buffer;
+#ifdef DEBUG
+ int i;
+#endif
+
+ dbg ("command_port_write_callback");
+
+ if (urb->status) {
+ dbg ("nonzero urb status: %d", urb->status);
+ return;
+ }
+
+#ifdef DEBUG
+ if (urb->actual_length) {
+ printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", urb->actual_length);
+ for (i = 0; i < urb->actual_length; ++i) {
+ printk ("%.2x ", data[i]);
+ }
+ printk ("\n");
+ }
+#endif
+
+ return;
+}
+
+
+static void command_port_read_callback (struct urb *urb)
+{
+ struct whiteheat_private *info = (struct whiteheat_private *)urb->context;
+ unsigned char *data = urb->transfer_buffer;
+#ifdef DEBUG
+ int i;
+#endif
+
+ dbg ("command_port_write_callback");
+
+ if (urb->status) {
+ dbg ("nonzero urb status: %d", urb->status);
+ return;
+ }
+
+#ifdef DEBUG
+ if (urb->actual_length) {
+ printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", urb->actual_length);
+ for (i = 0; i < urb->actual_length; ++i) {
+ printk ("%.2x ", data[i]);
+ }
+ printk ("\n");
+ }
+#endif
+
+ /* right now, if the command is COMMAND_COMPLETE, just flip the bit saying the command finished */
+ /* in the future we're going to have to pay attention to the actual command that completed */
+ if (data[0] == WHITEHEAT_CMD_COMPLETE) {
+ info->command_finished = TRUE;
+ }
+
+ return;
+}
+
+
+static int whiteheat_send_cmd (struct usb_serial *serial, __u8 command, __u8 *data, __u8 datasize)
+{
+ struct whiteheat_private *info;
+ struct usb_serial_port *port;
+ int timeout;
+ __u8 *transfer_buffer;
+
+ dbg("whiteheat_send_cmd: %d", command);
+
+ port = &serial->port[COMMAND_PORT];
+ info = (struct whiteheat_private *)port->private;
+ info->command_finished = FALSE;
+
+ transfer_buffer = (__u8 *)port->write_urb->transfer_buffer;
+ transfer_buffer[0] = command;
+ memcpy (&transfer_buffer[1], data, datasize);
+ port->write_urb->transfer_buffer_length = datasize + 1;
+ if (usb_submit_urb (port->write_urb))
+ dbg ("submit urb failed");
+
+ /* wait for the command to complete */
+ timeout = COMMAND_TIMEOUT;
+ while (timeout && (info->command_finished == FALSE)) {
+ timeout = interruptible_sleep_on_timeout (&info->wait_command, timeout);
+ }
+
+ if (info->command_finished == FALSE) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
{
+ struct whiteheat_min_set open_command;
+ struct usb_serial_port *command_port;
+ struct whiteheat_private *info;
+
dbg("whiteheat_open port %d", port->number);
if (port->active) {
return -EINVAL;
}
port->active = 1;
-
- /*Start reading from the device*/
+
+ /* set up some stuff for our command port */
+ command_port = &port->serial->port[COMMAND_PORT];
+ if (command_port->private == NULL) {
+ info = (struct whiteheat_private *)kmalloc (sizeof(struct whiteheat_private), GFP_KERNEL);
+ if (info == NULL) {
+ err("out of memory");
+ return -ENOMEM;
+ }
+
+ init_waitqueue_head(&info->wait_command);
+ command_port->private = info;
+ command_port->write_urb->complete = command_port_write_callback;
+ command_port->read_urb->complete = command_port_read_callback;
+ usb_submit_urb (command_port->read_urb);
+ }
+
+ /* Start reading from the device */
if (usb_submit_urb(port->read_urb))
dbg("usb_submit_urb(read bulk) failed");
+ /* send an open port command */
+ open_command.port = port->number - port->minor;
+ whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command));
+
/* Need to do device specific setup here (control lines, baud rate, etc.) */
/* FIXME!!! */
+ dbg("whiteheat_open exit");
+
return (0);
}
static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
{
+ struct whiteheat_min_set close_command;
+
dbg("whiteheat_close port %d", port->number);
+ /* send a close command to the port */
+ close_command.port = port->number - port->minor;
+ whiteheat_send_cmd (port->serial, WHITEHEAT_CLOSE, (__u8 *)&close_command, sizeof(close_command));
+
/* Need to change the control lines here */
/* FIXME */
response = ezusb_set_reset (serial, 0);
/* we want this device to fail to have a driver assigned to it. */
- return (1);
+ return 1;
+}
+
+
+static void whiteheat_shutdown (struct usb_serial *serial)
+{
+ struct usb_serial_port *command_port;
+
+ dbg("whiteheat_shutdown");
+
+ /* set up some stuff for our command port */
+ command_port = &serial->port[COMMAND_PORT];
+ if (command_port->private != NULL) {
+ kfree (command_port->private);
+ command_port->private = NULL;
+ }
+
+ return;
}
#endif /* CONFIG_USB_SERIAL_WHITEHEAT */
--- /dev/null
+/*
+ * USB ConnectTech WhiteHEAT driver
+ *
+ * Copyright (C) 1999, 2000
+ * Greg Kroah-Hartman (greg@kroah.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * See Documentation/usb/usb-serial.txt for more information on using this driver
+ *
+ */
+
+#ifndef __LINUX_USB_SERIAL_WHITEHEAT_H
+#define __LINUX_USB_SERIAL_WHITEHEAT_H
+
+
+#define FALSE 0
+#define TRUE 1
+
+/* WhiteHEAT commands */
+#define WHITEHEAT_OPEN 1 /* open the port */
+#define WHITEHEAT_CLOSE 2 /* close the port */
+#define WHITEHEAT_SETUP_PORT 3 /* change port settings */
+#define WHITEHEAT_SET_RTS 4 /* turn RTS on or off */
+#define WHITEHEAT_SET_DTR 5 /* turn DTR on or off */
+#define WHITEHEAT_SET_BREAK 6 /* turn BREAK on or off */
+#define WHITEHEAT_DUMP 7 /* dump memory */
+#define WHITEHEAT_STATUS 8 /* get status */
+#define WHITEHEAT_PURGE 9 /* clear the UART fifos */
+#define WHITEHEAT_GET_DTR_RTS 10 /* get the state of DTR and RTS for a port */
+#define WHITEHEAT_GET_HW_INFO 11 /* get EEPROM info and hardware ID */
+#define WHITEHEAT_REPORT_TX_DONE 12 /* get the next TX done */
+#define WHITEHEAT_EVENT 13 /* unsolicited status events */
+#define WHITEHEAT_ECHO 14 /* send data to the indicated IN endpoint */
+#define WHITEHEAT_DO_TEST 15 /* perform the specified test */
+#define WHITEHEAT_CMD_COMPLETE 16 /* reply for certain commands */
+
+/* Data for the WHITEHEAT_SETUP_PORT command */
+#define WHITEHEAT_CTS_FLOW 0x08
+#define WHITEHEAT_RTS_FLOW 0x80
+#define WHITEHEAT_DSR_FLOW 0x10
+#define WHITEHEAT_DTR_FLOW 0x02
+struct whiteheat_port_settings {
+ __u8 port; /* port number (1 to N) */
+ __u32 baud; /* any value allowed, default 9600, arrives little endian, range is 7 - 460800 */
+ __u8 bits; /* 5, 6, 7, or 8, default 8 */
+ __u8 stop; /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */
+ __u8 parity; /* 'n, e, o, 0, or 1' (ascii), default 'n'
+ * n = none e = even o = odd
+ * 0 = force 0 1 = force 1 */
+ __u8 sflow; /* 'n, r, t, or b' (ascii), default 'n'
+ * n = none
+ * r = receive (XOFF/XON transmitted when receiver fills / empties)
+ * t = transmit (XOFF/XON received will stop/start TX)
+ * b = both */
+ __u8 xoff; /* XOFF byte value, default 0x13 */
+ __u8 xon; /* XON byte value, default 0x11 */
+ __u8 hflow; /* bits indicate mode as follows:
+ * CTS (0x08) (CTS off/on will control/cause TX off/on)
+ * DSR (0x10) (DSR off/on will control/cause TX off/on)
+ * RTS (0x80) (RTS off/on when receiver fills/empties)
+ * DTR (0x02) (DTR off/on when receiver fills/empties) */
+ __u8 lloop; /* local loopback 0 or 1, default 0 */
+};
+
+/* data for WHITEHEAT_SET_RTS, WHITEHEAT_SET_DTR, and WHITEHEAT_SET_BREAK commands */
+struct whiteheat_rdb_set {
+ __u8 port; /* port number (1 to N) */
+ __u8 state; /* 0 = off, non-zero = on */
+};
+
+/* data for:
+ WHITEHEAT_OPEN
+ WHITEHEAT_CLOSE
+ WHITEHEAT_STATUS
+ WHITEHEAT_GET_DTR_RTS
+ WHITEHEAT_REPORT_TX_DONE */
+struct whiteheat_min_set {
+ __u8 port; /* port number (1 to N) */
+};
+
+/* data for WHITEHEAT_PURGE command */
+#define WHITEHEAT_PURGE_INPUT 0x01
+#define WHITEHEAT_PURGE_OUTPUT 0x02
+struct whiteheat_purge_set {
+ __u8 port; /* port number (1 to N) */
+ __u8 what; /* bit pattern of what to purge */
+};
+
+/* data for WHITEHEAT_DUMP command */
+struct whiteheat_dump_info {
+ __u8 mem_type; /* memory type: 'd' = data, 'i' = idata, 'b' = bdata, 'x' = xdata */
+ __u16 addr; /* memory address to dump, address range depends on the above mem_type:
+ * 'd' = 0 to ff (80 to FF is SFR's)
+ * 'i' = 80 to ff
+ * 'b' = 20 to 2f (bits returned as bytes)
+ * 'x' = 0000 to ffff (also code space) */
+ __u16 length; /* number of bytes to dump, max 64 */
+};
+
+/* data for WHITEHEAT_ECHO command */
+struct whiteheat_echo_set {
+ __u8 port; /* port number (1 to N) */
+ __u8 length; /* length of message to echo */
+ __u8 echo_data[61]; /* data to echo */
+};
+
+/* data returned from WHITEHEAT_STATUS command */
+#define WHITEHEAT_OVERRUN_ERROR 0x02
+#define WHITEHEAT_PARITY_ERROR 0x04
+#define WHITEHEAT_FRAMING_ERROR 0x08
+#define WHITEHEAT_BREAK_ERROR 0x10
+
+#define WHITEHEAT_OHFLOW 0x01 /* TX is stopped by CTS (waiting for CTS to go ON) */
+#define WHITEHEAT_IHFLOW 0x02 /* remote TX is stopped by RTS */
+#define WHITEHEAT_OSFLOW 0x04 /* TX is stopped by XOFF received (waiting for XON to occur) */
+#define WHITEHEAT_ISFLOW 0x08 /* remote TX is stopped by XOFF transmitted */
+#define WHITEHEAT_TX_DONE 0x80 /* TX has completed */
+
+#define WHITEHEAT_MODEM_EVENT 0x01
+#define WHITEHEAT_ERROR_EVENT 0x02
+#define WHITEHEAT_FLOW_EVENT 0x04
+#define WHITEHEAT_CONNECT_EVENT 0x08
+struct whiteheat_status_info {
+ __u8 port; /* port number (1 to N) */
+ __u8 event; /* indicates which of the following bytes are the current event */
+ __u8 modem; /* modem signal status (copy of UART MSR register) */
+ __u8 error; /* PFO and RX break (copy of UART LSR register) */
+ __u8 flow; /* flow control state */
+ __u8 connect; /* connect state, non-zero value indicates connected */
+};
+
+/* data returned from WHITEHEAT_EVENT command */
+struct whiteheat_event {
+ __u8 port; /* port number (1 to N) */
+ __u8 event; /* indicates which of the following bytes are the current event */
+ __u8 info; /* either modem, error, flow, or connect information */
+};
+
+/* data retured by the WHITEHEAT_GET_HW_INFO command */
+struct whiteheat_hw_info {
+ __u8 hw_id; /* hardware id number, WhiteHEAT = 0 */
+ __u8 sw_major_rev; /* major version number */
+ __u8 sw_minor_rev; /* minor version number */
+ struct whiteheat_hw_eeprom_info {
+ __u8 b0; /* B0 */
+ __u8 vendor_id_low; /* vendor id (low byte) */
+ __u8 vendor_id_high; /* vendor id (high byte) */
+ __u8 product_id_low; /* product id (low byte) */
+ __u8 product_id_high; /* product id (high byte) */
+ __u8 device_id_low; /* device id (low byte) */
+ __u8 device_id_high; /* device id (high byte) */
+ __u8 not_used_1;
+ __u8 serial_number_0; /* serial number (low byte) */
+ __u8 serial_number_1; /* serial number */
+ __u8 serial_number_2; /* serial number */
+ __u8 serial_number_3; /* serial number (high byte) */
+ __u8 not_used_2;
+ __u8 not_used_3;
+ __u8 checksum_low; /* checksum (low byte) */
+ __u8 checksum_high; /* checksum (high byte */
+ } hw_eeprom_info; /* EEPROM contents */
+};
+
+#endif
+
/*
* drivers/video/clgenfb.c - driver for Cirrus Logic chipsets
*
- * Copyright 1999 Jeff Garzik <jgarzik@mandrakesoft.com>
+ * Copyright 1999,2000 Jeff Garzik <jgarzik@mandrakesoft.com>
*
* Contributors (thanks, all!)
*
*
*/
-#define CLGEN_VERSION "1.9.4.5"
+#define CLGEN_VERSION "1.9.5"
#include <linux/config.h>
#include <linux/module.h>
#include "vga.h"
-/*****************************************************************
- *
- * compatibility with older kernel versions
- *
- */
-
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-
-#ifndef KERNEL_VERSION
-#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-#endif
-
-#ifndef PCI_DEVICE_ID_CIRRUS_5462
-#define PCI_DEVICE_ID_CIRRUS_5462 0x00d0
-#endif
-
-
-
-
/*****************************************************************
*
* debugging and utility macros
#define MAX_NUM_BOARDS 7
-
-
/*****************************************************************
*
* chipset information
} clgen_board_t;
-
/*
* per-board-type information, used for enumerating and abstracting
* chip-specific information
#endif /* CONFIG_PCI */
-
#ifdef CONFIG_ZORRO
static const struct {
clgen_board_t btype;
int clgenfb_init (void);
int clgenfb_setup (char *options);
-#ifdef MODULE
-static void clgenfb_cleanup (struct clgenfb_info *info);
-#endif
-
static int clgenfb_open (struct fb_info *info, int user);
static int clgenfb_release (struct fb_info *info, int user);
static int clgenfb_ioctl (struct inode *inode, struct file *file,
iounmap (info->fbmem);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13)
release_mem_region(info->fbmem_phys, info->size);
+
+#if 0 /* if system didn't claim this region, we would... */
release_mem_region(0xA0000, 65535);
+#endif
if (release_io_ports)
release_region(0x3C0, 32);
#endif
board_addr);
return -1;
}
+#if 0 /* if the system didn't claim this region, we would... */
if (!request_mem_region(0xA0000, 65535, "clgenfb")) {
pci_write_config_word (pdev, PCI_COMMAND, tmp16);
printk(KERN_ERR "clgen: cannot reserve region 0x%lu, abort\n",
release_mem_region(board_addr, board_size);
return -1;
}
+#endif
if (request_region(0x3C0, 32, "clgenfb"))
release_io_ports = 1;
#if defined(CONFIG_FB_OF)
int __init clgen_of_init (struct device_node *dp)
{
- int rc;
-
- DPRINTK ("ENTER\n");
-
- rc = clgenfb_init ();
-
- DPRINTK ("EXIT, returning %d\n", rc);
-
- return rc;
+ return clgenfb_init ();
}
#endif /* CONFIG_FB_OF */
-
/*
* Cleanup (only needed for module)
*/
-#ifdef MODULE
-static void clgenfb_cleanup (struct clgenfb_info *info)
+static void __exit clgenfb_cleanup (struct clgenfb_info *info)
{
DPRINTK ("ENTER\n");
DPRINTK ("EXIT\n");
}
-#endif
-
-
#ifndef MODULE
#endif
-
-
-
/*
* Modularization
*/
-#ifdef MODULE
-MODULE_AUTHOR("Copyright 1999 Jeff Garzik <jgarzik@mandrakesoft.com>");
+MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@mandrakesoft.com>");
MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
-int init_module (void)
-{
-#if defined(CONFIG_FB_OF)
-/* Nothing to do, must be called from offb */
- return 0;
-#else
- int i;
-
- DPRINTK ("ENTER\n");
- i = clgenfb_init ();
- DPRINTK ("EXIT\n");
- return i;
-#endif
-}
-
-void cleanup_module (void)
+static void __exit clgenfb_exit (void)
{
DPRINTK ("ENTER\n");
DPRINTK ("EXIT\n");
}
-#endif /* MODULE */
+#ifdef MODULE
+module_init(clgenfb_init);
+#endif
+module_exit(clgenfb_exit);
/**********************************************************************/
}
-
/*** WSFR() - write to the "special function register" (SFR) ***/
static void WSFR (struct clgenfb_info *fb_info, unsigned char val)
{
}
-
#if 0
/*** RClut - read CLUT entry (range 0..63) ***/
static void RClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char *red,
DPRINTK ("EXIT\n");
}
+
/*******************************************************************
clgen_RectFill()
DPRINTK ("EXIT\n");
}
+
/**************************************************************************
* bestclock() - determine closest possible clock lower(?) than the
* desired pixel clock
}
-
-
-
-
/* -------------------------------------------------------------------------
*
* debugging functions
}
-
/**
* clgen_dbg_print_regs
* @base: If using newmmio, the newmmio base address, otherwise %NULL
}
-
-
-
/**
* clgen_dump
* @clgeninfo:
}
-
/**
* clgen_dbg_reg_dump
* @base: If using newmmio, the newmmio base address, otherwise %NULL
DPRINTK ("\n");
}
-
#endif /* CLGEN_DEBUG */
+
struct fb_info_sbusfb *fb = sbusfbinfo(info);
if (user) {
- if (fb->open) return -EBUSY;
- fb->mmaped = 0;
- fb->open = 1;
- fb->vtconsole = -1;
+ if (fb->open == 0) {
+ fb->mmaped = 0;
+ fb->open = 1;
+ fb->vtconsole = -1;
+ }
+ fb->open++;
} else
fb->consolecnt++;
MOD_INC_USE_COUNT;
struct fb_info_sbusfb *fb = sbusfbinfo(info);
if (user) {
- if (fb->vtconsole != -1) {
- vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
- if (fb->mmaped) {
- fb->graphmode--;
- sbusfb_clear_margin(&fb_display[fb->vtconsole], 0);
+ fb->open--;
+ if (fb->open == 0) {
+ if (fb->vtconsole != -1) {
+ vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
+ if (fb->mmaped) {
+ fb->graphmode--;
+ sbusfb_clear_margin(&fb_display[fb->vtconsole], 0);
+ }
}
+ if (fb->reset)
+ fb->reset(fb);
}
- if (fb->reset)
- fb->reset(fb);
fb->open = 0;
} else
fb->consolecnt--;
currcon = -1;
if (!nohwcursor) tdfxfb_hwcursor_init();
+ init_timer(&fb_info.cursor.timer);
fb_info.cursor.timer.function = do_flashcursor;
- fb_info.cursor.state = CM_ERASE;
- fb_info.cursor.timer.prev = fb_info.cursor.timer.next=NULL;
fb_info.cursor.timer.data = (unsigned long)(&fb_info);
+ fb_info.cursor.state = CM_ERASE;
spin_lock_init(&fb_info.DAClock);
strcpy(fb_info.fb_info.modename, "3Dfx ");
static int currcon = 0;
-static int release_io_ports = 0;
-
/* --------------------------------------------------------------------- */
/*
}
}
-int __init vga16_init(void)
+int __init vga16fb_init(void)
{
int i,j;
printk(KERN_DEBUG "vga16fb: initializing\n");
- if (!request_mem_region(VGA_FB_PHYS, VGA_FB_PHYS_LEN, "vga16fb")) {
- printk (KERN_ERR "vga16fb: unable to reserve VGA memory, exiting\n");
- return -1;
- }
+ /* XXX share VGA_FB_PHYS region with vgacon */
vga16fb.video_vbase = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN);
printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.video_vbase);
palette[i].blue = default_blu[j];
}
- /* note - does not cause failure, b/c vgacon probably still owns this
- * region (FIXME) */
- if (request_region(0x3C0, 32, "vga16fb"))
- release_io_ports = 1;
+ /* XXX share VGA I/O region with vgacon and others */
disp.var = vga16fb_defined;
return 0;
}
-#ifndef MODULE
-int __init vga16fb_init(void)
-{
- return vga16_init();
-}
-
-#else /* MODULE */
-
-int init_module(void)
-{
- return vga16_init();
-}
-
-void cleanup_module(void)
+static void __exit vga16fb_exit(void)
{
unregister_framebuffer(&vga16fb.fb_info);
iounmap(vga16fb.video_vbase);
- release_mem_region(VGA_FB_PHYS, VGA_FB_PHYS_LEN);
- if (release_io_ports)
- release_region(0x3c0, 32);
+ /* XXX unshare VGA regions */
}
+#ifdef MODULE
+module_init(vga16fb_init);
#endif
+module_exit(vga16fb_exit);
+
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
/*
* Run the hooks that have to be done when a page I/O has completed.
*/
- if (test_and_clear_bit(PG_decr_after, &page->flags))
+ if (PageTestandClearDecrAfter(page))
atomic_dec(&nr_async_pages);
UnlockPage(page);
if (!PageLocked(page))
panic("brw_page: page not locked for I/O");
-// clear_bit(PG_error, &page->flags);
+// ClearPageError(page);
/*
* We pretty much rely on the page lock for this, because
* create_page_buffers() might sleep.
dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n",
status, (long long)inode->i_size);
if (status < 0)
- clear_bit(PG_uptodate, &page->flags);
+ ClearPageUptodate(page);
return status;
}
{
int g;
+ read_lock(&tasklist_lock);
buffer += sprintf(buffer,
"State:\t%s\n"
"Pid:\t%d\n"
"PPid:\t%d\n"
"TracerPid:\t%d\n"
"Uid:\t%d\t%d\t%d\t%d\n"
- "Gid:\t%d\t%d\t%d\t%d\n"
- "FDSize:\t%d\n"
- "Groups:\t",
+ "Gid:\t%d\t%d\t%d\t%d\n",
get_task_state(p),
p->pid, p->p_opptr->pid, p->p_pptr->pid != p->p_opptr->pid ? p->p_opptr->pid : 0,
p->uid, p->euid, p->suid, p->fsuid,
- p->gid, p->egid, p->sgid, p->fsgid,
+ p->gid, p->egid, p->sgid, p->fsgid);
+ read_unlock(&tasklist_lock);
+ task_lock(p);
+ buffer += sprintf(buffer,
+ "FDSize:\t%d\n"
+ "Groups:\t",
p->files ? p->files->max_fds : 0);
+ task_unlock(p);
for (g = 0; g < p->ngroups; g++)
buffer += sprintf(buffer, "%d ", p->groups[g]);
}
-/* task is locked, so we are safe here */
-
int proc_pid_status(struct task_struct *task, char * buffer)
{
char * orig = buffer;
- struct mm_struct *mm = task->mm;
+ struct mm_struct *mm;
#if defined(CONFIG_ARCH_S390)
int line,len;
#endif
buffer = task_name(task, buffer);
buffer = task_state(task, buffer);
- if (mm)
+ task_lock(task);
+ mm = task->mm;
+ if(mm)
+ atomic_inc(&mm->mm_users);
+ task_unlock(task);
+ if (mm) {
buffer = task_mem(mm, buffer);
+ mmput(mm);
+ }
buffer = task_sig(task, buffer);
buffer = task_cap(task, buffer);
#if defined(CONFIG_ARCH_S390)
return buffer - orig;
}
-/* task is locked, so we are safe here */
-
int proc_pid_stat(struct task_struct *task, char * buffer)
{
- struct mm_struct *mm = task->mm;
unsigned long vsize, eip, esp, wchan;
long priority, nice;
int tty_pgrp;
sigset_t sigign, sigcatch;
char state;
int res;
+ pid_t ppid;
+ struct mm_struct *mm;
state = *get_task_state(task);
vsize = eip = esp = 0;
+ task_lock(task);
+ mm = task->mm;
+ if(mm)
+ atomic_inc(&mm->mm_users);
+ task_unlock(task);
if (mm) {
struct vm_area_struct *vma;
down(&mm->mmap_sem);
nice = task->priority;
nice = 20 - (nice * 20 + DEF_PRIORITY / 2) / DEF_PRIORITY;
+ read_lock(&tasklist_lock);
+ ppid = task->p_opptr->pid;
+ read_unlock(&tasklist_lock);
res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \
%lu %lu %lu %lu %lu %lu %lu %lu %d %d\n",
task->pid,
task->comm,
state,
- task->p_opptr->pid,
+ ppid,
task->pgrp,
task->session,
task->tty ? kdev_t_to_nr(task->tty->device) : 0,
task->cnswap,
task->exit_signal,
task->processor);
+ if(mm)
+ mmput(mm);
return res;
}
int proc_pid_statm(struct task_struct *task, char * buffer)
{
- struct mm_struct *mm = task->mm;
+ struct mm_struct *mm;
int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;
+ task_lock(task);
+ mm = task->mm;
+ if(mm)
+ atomic_inc(&mm->mm_users);
+ task_unlock(task);
if (mm) {
struct vm_area_struct * vma;
down(&mm->mmap_sem);
vma = vma->vm_next;
}
up(&mm->mmap_sem);
+ mmput(mm);
}
return sprintf(buffer,"%d %d %d %d %d %d %d\n",
size, resident, share, trs, lrs, drs, dt);
ssize_t proc_pid_read_maps (struct task_struct *task, struct file * file, char * buf,
size_t count, loff_t *ppos)
{
- struct mm_struct *mm = task->mm;
+ struct mm_struct *mm;
struct vm_area_struct * map, * next;
char * destptr = buf, * buffer;
loff_t lineno;
if (!buffer)
goto out;
- if (!mm || count == 0)
+ if (count == 0)
+ goto getlen_out;
+ task_lock(task);
+ mm = task->mm;
+ if (mm)
+ atomic_inc(&mm->mm_users);
+ task_unlock(task);
+ if (!mm)
goto getlen_out;
/* Check whether the mmaps could change if we sleep */
/* encode f_pos */
*ppos = (lineno << MAPS_LINE_SHIFT) + column;
+ mmput(mm);
getlen_out:
retval = destptr - buf;
int result = -ENOENT;
struct task_struct *task = inode->u.proc_i.task;
- if (!task_lock(task))
- return result;
+ task_lock(task);
mm = task->mm;
+ if (mm)
+ atomic_inc(&mm->mm_users);
+ task_unlock(task);
if (!mm)
goto out;
down(&mm->mmap_sem);
vma = vma->vm_next;
}
up(&mm->mmap_sem);
+ mmput(mm);
out:
- task_unlock(task);
return result;
}
static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
{
+ struct fs_struct *fs;
int result = -ENOENT;
- if (task_lock(inode->u.proc_i.task)) {
- struct fs_struct *fs = inode->u.proc_i.task->fs;
- if (fs) {
- *mnt = mntget(fs->pwdmnt);
- *dentry = dget(fs->pwd);
- result = 0;
- }
- task_unlock(inode->u.proc_i.task);
+ task_lock(inode->u.proc_i.task);
+ fs = inode->u.proc_i.task->fs;
+ if(fs)
+ atomic_inc(&fs->count);
+ task_unlock(inode->u.proc_i.task);
+ if (fs) {
+ *mnt = mntget(fs->pwdmnt);
+ *dentry = dget(fs->pwd);
+ result = 0;
+ put_fs_struct(fs);
}
return result;
}
static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
{
+ struct fs_struct *fs;
int result = -ENOENT;
- if (task_lock(inode->u.proc_i.task)) {
- struct fs_struct *fs = inode->u.proc_i.task->fs;
- if (fs) {
- *mnt = mntget(fs->rootmnt);
- *dentry = dget(fs->root);
- result = 0;
- }
- task_unlock(inode->u.proc_i.task);
+ task_lock(inode->u.proc_i.task);
+ fs = inode->u.proc_i.task->fs;
+ if(fs)
+ atomic_inc(&fs->count);
+ task_unlock(inode->u.proc_i.task);
+ if (fs) {
+ *mnt = mntget(fs->rootmnt);
+ *dentry = dget(fs->root);
+ result = 0;
}
return result;
}
-/* task is locked and can't drop mm, so we are safe */
-
static int proc_pid_environ(struct task_struct *task, char * buffer)
{
- struct mm_struct *mm = task->mm;
+ struct mm_struct *mm;
int res = 0;
+ task_lock(task);
+ mm = task->mm;
+ if (mm)
+ atomic_inc(&mm->mm_users);
+ task_unlock(task);
if (mm) {
int len = mm->env_end - mm->env_start;
if (len > PAGE_SIZE)
len = PAGE_SIZE;
res = access_process_vm(task, mm->env_start, buffer, len, 0);
+ mmput(mm);
}
return res;
}
-/* task is locked and can't drop mm, so we are safe */
-
static int proc_pid_cmdline(struct task_struct *task, char * buffer)
{
- struct mm_struct *mm = task->mm;
+ struct mm_struct *mm;
int res = 0;
+ task_lock(task);
+ mm = task->mm;
+ if (mm)
+ atomic_inc(&mm->mm_users);
+ task_unlock(task);
if (mm) {
int len = mm->arg_end - mm->arg_start;
if (len > PAGE_SIZE)
len = PAGE_SIZE;
res = access_process_vm(task, mm->arg_start, buffer, len, 0);
+ mmput(mm);
}
return res;
}
struct task_struct *task = inode->u.proc_i.task;
ssize_t res;
- if (!task_lock(task))
- return -EIO;
res = proc_pid_read_maps(task, file, buf, count, ppos);
- task_unlock(task);
return res;
}
if (!(page = __get_free_page(GFP_KERNEL)))
return -ENOMEM;
- if (!task_lock(task)) {
+ /* FIXME: check that all proc_read function
+ * handle a dying task gracefully.
+ * The memory for the task structure
+ * won't be freed, we've called get_task_struct().
+ */
+#if 0
+ if (!task->p_pptr) {
free_page(page);
return -EIO;
}
+#endif
length = inode->u.proc_i.op.proc_read(task, (char*)page);
- task_unlock(task);
-
if (length < 0) {
free_page(page);
return length;
/* We can't replace this with ClearPageError. why? is it a problem?
fs/buffer.c:brw_page does the same. */
- /* clear_bit(PG_error, &page->flags); */
+ /* ClearPageError(page); */
#ifdef SMBFS_DEBUG_VERBOSE
printk("smb_readpage_sync: file %s/%s, count=%d@%ld, rsize=%d\n",
count = d_active_refs(sb->s_root);
if (mnt->mnt_parent == mnt)
count--;
- if (count != 2)
+ if (count != 2) {
+ mntput(mnt);
return -EBUSY;
+ }
- if (sb->s_root->d_inode->i_state)
+ if (sb->s_root->d_inode->i_state) {
+ mntput(mnt);
return -EBUSY;
+ }
/* OK, that's the point of no return */
mntput(mnt);
-/* $Id: system.h,v 1.57 2000/03/27 10:38:57 davem Exp $ */
+/* $Id: system.h,v 1.58 2000/05/05 18:47:41 davem Exp $ */
#ifndef __SPARC64_SYSTEM_H
#define __SPARC64_SYSTEM_H
extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noreturn));
+/*
+ * Atomic compare and exchange. Compare OLD with MEM, if identical,
+ * store NEW in MEM. Return the initial value in MEM. Success is
+ * indicated by comparing RETURN with OLD.
+ */
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+extern __inline__ unsigned long
+__cmpxchg_u32(volatile int *m, int old, int new)
+{
+ __asm__ __volatile__("cas [%2], %3, %0"
+ : "=&r" (new)
+ : "0" (new), "r" (m), "r" (old)
+ : "memory");
+
+ return new;
+}
+
+extern __inline__ unsigned long
+__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
+{
+ __asm__ __volatile__("casx [%2], %3, %0"
+ : "=&r" (new)
+ : "0" (new), "r" (m), "r" (old)
+ : "memory");
+
+ return new;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+ if something tries to do an invalid cmpxchg(). */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32(ptr, old, new);
+ case 8:
+ return __cmpxchg_u64(ptr, old, new);
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
+#define cmpxchg(ptr,o,n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr))); \
+ })
+
#endif /* !(__ASSEMBLY__) */
#endif /* !(__SPARC64_SYSTEM_H) */
* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
*
* Since those functions where calling other functions, it was completely
- * bogos to make them all "static inline".
+ * bogus to make them all "extern inline".
*
- * The removal of this pseudo optimization saved me scandaleous:
+ * The removal of this pseudo optimization saved me scandalous:
*
* 3756 (i386 arch)
*
extern void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long offset);
-#define touch_buffer(bh) set_bit(PG_referenced, &bh->b_page->flags)
+#define touch_buffer(bh) SetPageReferenced(bh->b_page)
#include <linux/pipe_fs_i.h>
#define SetPageError(page) set_bit(PG_error, &(page)->flags)
#define ClearPageError(page) clear_bit(PG_error, &(page)->flags)
#define PageReferenced(page) test_bit(PG_referenced, &(page)->flags)
+#define SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags)
+#define PageTestandClearReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags)
#define PageDecrAfter(page) test_bit(PG_decr_after, &(page)->flags)
+#define SetPageDecrAfter(page) set_bit(PG_decr_after, &(page)->flags)
+#define PageTestandClearDecrAfter(page) test_and_clear_bit(PG_decr_after, &(page)->flags)
#define PageSlab(page) test_bit(PG_slab, &(page)->flags)
#define PageSwapCache(page) test_bit(PG_swap_cache, &(page)->flags)
#define PageReserved(page) test_bit(PG_reserved, &(page)->flags)
/* Thread group tracking */
u32 parent_exec_id;
u32 self_exec_id;
-/* Protection of fields allocatio/deallocation */
- struct semaphore exit_sem;
+/* Protection of (de-)allocation: mm, files, fs */
+ spinlock_t alloc_lock;
};
/*
blocked: {{0}}, \
sigqueue: NULL, \
sigqueue_tail: &tsk.sigqueue, \
- exit_sem: __MUTEX_INITIALIZER(tsk.exit_sem) \
+ alloc_lock: SPIN_LOCK_UNLOCKED \
}
write_unlock_irq(&tasklist_lock);
}
-static inline int task_lock(struct task_struct *p)
+static inline void task_lock(struct task_struct *p)
{
- down(&p->exit_sem);
- if (p->p_pptr)
- return 1;
- /* He's dead, Jim. You take his wallet, I'll take the tricorder... */
- up(&p->exit_sem);
- return 0;
+ spin_lock(&p->alloc_lock);
}
static inline void task_unlock(struct task_struct *p)
{
- up(&p->exit_sem);
+ spin_unlock(&p->alloc_lock);
}
#endif /* __KERNEL__ */
p->p_cptr = NULL;
init_waitqueue_head(&p->wait_chldexit);
p->vfork_sem = NULL;
- sema_init(&p->exit_sem, 1);
+ spin_lock_init(&p->alloc_lock);
p->sigpending = 0;
sigemptyset(&p->signal);
#ifdef CONFIG_MODULES
EXPORT_SYMBOL(get_module_symbol);
+EXPORT_SYMBOL(try_inc_mod_count);
#endif
EXPORT_SYMBOL(get_option);
EXPORT_SYMBOL(get_options);
struct vm_area_struct * vma;
/* Worry about races with exit() */
- lock_kernel();
+ task_lock(tsk);
mm = tsk->mm;
- atomic_inc(&mm->mm_users);
- unlock_kernel();
+ if (mm)
+ atomic_inc(&mm->mm_users);
+ task_unlock(tsk);
+ if (!mm)
+ return 0;
down(&mm->mmap_sem);
vma = find_extend_vma(mm, addr);
if (!zone)
BUG();
- count = (nr_lru_pages << 1) >> priority;
+ count = nr_lru_pages >> priority;
if (!count)
return ret;
* &young to make sure that we won't try to free it the next
* time */
dispose = &young;
- if (test_and_clear_bit(PG_referenced, &page->flags))
+ if (PageTestandClearReferenced(page))
goto dispose_continue;
- if (p_zone->free_pages > p_zone->pages_high)
+ if (!page->buffers && page_count(page) > 1)
goto dispose_continue;
- if (!page->buffers && page_count(page) > 1)
+ /*
+ * Ok, it wasn't young, so leave it at the end of
+ * the list ("old").
+ */
+ dispose = &old;
+ if (p_zone->free_pages > p_zone->pages_high)
goto dispose_continue;
count--;
/* Page not used -> free it or put it on the old list
* so it gets freed first the next time */
- dispose = &old;
if (TryLockPage(page))
goto dispose_continue;
if (page->index == offset)
break;
}
- set_bit(PG_referenced, &page->flags);
+ SetPageReferenced(page);
not_found:
return page;
}
return 0;
}
if (!wait) {
- set_bit(PG_decr_after, &page->flags);
+ SetPageDecrAfter(page);
atomic_inc(&nr_async_pages);
}
* tables to the global page map.
*/
set_pte(page_table, pte_mkold(pte));
- set_bit(PG_referenced, &page->flags);
+ SetPageReferenced(page);
goto out_failed;
}
- /* Don't look at this page if it's in a zone that we're not interested in.. */
- if (!page->zone->zone_wake_kswapd)
- goto out_failed;
-
if (TryLockPage(page))
goto out_failed;
if (!(gfp_mask & __GFP_IO))
goto out_unlock;
+ /*
+ * Don't do any of the expensive stuff if
+ * we're not really interested in this zone.
+ */
+ if (!page->zone->zone_wake_kswapd)
+ goto out_unlock;
+
/*
* Ok, it's really dirty. That means that
* we should either create a new swap cache
rpciod_pid = current->pid;
up(&rpciod_running);
+ exit_fs(current);
exit_files(current);
exit_mm(current);