diff options
Diffstat (limited to 'drivers')
87 files changed, 2728 insertions, 3442 deletions
diff --git a/drivers/acorn/char/defkeymap-l7200.c b/drivers/acorn/char/defkeymap-l7200.c index 9e18ce742e38..28a5fbc6aa1a 100644 --- a/drivers/acorn/char/defkeymap-l7200.c +++ b/drivers/acorn/char/defkeymap-l7200.c @@ -346,7 +346,7 @@ char *func_table[MAX_NR_FUNC] = { 0, }; -struct kbdiacr accent_table[MAX_DIACR] = { +struct kbdiacruc accent_table[MAX_DIACR] = { {'`', 'A', '\300'}, {'`', 'a', '\340'}, {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, {'^', 'A', '\302'}, {'^', 'a', '\342'}, diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c index 7647abfe1890..fbae8674e491 100644 --- a/drivers/base/dmapool.c +++ b/drivers/base/dmapool.c @@ -302,7 +302,7 @@ restart: if (mem_flags & __GFP_WAIT) { DECLARE_WAITQUEUE (wait, current); - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue (&pool->waitq, &wait); spin_unlock_irqrestore (&pool->lock, flags); diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index ba07f762c4cb..07f02f855ab5 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h @@ -48,15 +48,6 @@ struct aoe_hdr { __be32 tag; }; -#ifdef __KERNEL__ -#include <linux/skbuff.h> - -static inline struct aoe_hdr *aoe_hdr(const struct sk_buff *skb) -{ - return (struct aoe_hdr *)skb_mac_header(skb); -} -#endif - struct aoe_atahdr { unsigned char aflags; unsigned char errfeat; diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 99672017ca56..4d59d5057734 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -120,7 +120,7 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f) /* initialize the headers & frame */ skb = f->skb; - h = aoe_hdr(skb); + h = (struct aoe_hdr *) skb_mac_header(skb); ah = (struct aoe_atahdr *) (h+1); skb_put(skb, sizeof *h + sizeof *ah); memset(h, 0, skb->len); @@ -209,7 +209,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) skb->dev = ifp; if (sl_tail == NULL) sl_tail = skb; - h = aoe_hdr(skb); + h = (struct aoe_hdr *) skb_mac_header(skb); memset(h, 0, sizeof *h + sizeof *ch); memset(h->dst, 0xff, sizeof h->dst); @@ -304,7 +304,7 @@ rexmit(struct aoedev *d, struct frame *f) aoechr_error(buf); skb = f->skb; - h = aoe_hdr(skb); + h = (struct aoe_hdr *) skb_mac_header(skb); ah = (struct aoe_atahdr *) (h+1); f->tag = n; h->tag = cpu_to_be32(n); @@ -533,7 +533,7 @@ aoecmd_ata_rsp(struct sk_buff *skb) char ebuf[128]; u16 aoemajor; - hin = aoe_hdr(skb); + hin = (struct aoe_hdr *) skb_mac_header(skb); aoemajor = be16_to_cpu(get_unaligned(&hin->major)); d = aoedev_by_aoeaddr(aoemajor, hin->minor); if (d == NULL) { @@ -565,7 +565,7 @@ aoecmd_ata_rsp(struct sk_buff *skb) calc_rttavg(d, tsince(f->tag)); ahin = (struct aoe_atahdr *) (hin+1); - hout = aoe_hdr(f->skb); + hout = (struct aoe_hdr *) skb_mac_header(f->skb); ahout = (struct aoe_atahdr *) (hout+1); buf = f->buf; @@ -699,7 +699,7 @@ aoecmd_ata_id(struct aoedev *d) /* initialize the headers & frame */ skb = f->skb; - h = aoe_hdr(skb); + h = (struct aoe_hdr *) skb_mac_header(skb); ah = (struct aoe_atahdr *) (h+1); skb_put(skb, sizeof *h + sizeof *ah); memset(h, 0, skb->len); @@ -730,7 +730,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb) enum { MAXFRAMES = 16 }; u16 n; - h = aoe_hdr(skb); + h = (struct aoe_hdr *) skb_mac_header(skb); ch = (struct aoe_cfghdr *) (h+1); /* diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index 4dc0fb7da94b..4e6deb7f5c24 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c @@ -127,7 +127,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, goto exit; skb_push(skb, ETH_HLEN); /* (1) */ - h = aoe_hdr(skb); + h = (struct aoe_hdr *) skb_mac_header(skb); n = be32_to_cpu(get_unaligned(&h->tag)); if ((h->verfl & AOEFL_RSP) == 0 || (n & 1<<31)) goto exit; diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index e330c26c5ad9..7c2cfde08f18 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1582,38 +1582,36 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, * allows us to delete disk zero but keep the controller registered. */ if (h->gendisk[0] != disk) { - if (disk) { - struct request_queue *q = disk->queue; - if (disk->flags & GENHD_FL_UP) - del_gendisk(disk); - if (q) { - blk_cleanup_queue(q); - /* Set drv->queue to NULL so that we do not try - * to call blk_start_queue on this queue in the - * interrupt handler - */ - drv->queue = NULL; - } - /* If clear_all is set then we are deleting the logical - * drive, not just refreshing its info. For drives - * other than disk 0 we will call put_disk. We do not - * do this for disk 0 as we need it to be able to - * configure the controller. + struct request_queue *q = disk->queue; + if (disk->flags & GENHD_FL_UP) + del_gendisk(disk); + if (q) { + blk_cleanup_queue(q); + /* Set drv->queue to NULL so that we do not try + * to call blk_start_queue on this queue in the + * interrupt handler + */ + drv->queue = NULL; + } + /* If clear_all is set then we are deleting the logical + * drive, not just refreshing its info. For drives + * other than disk 0 we will call put_disk. We do not + * do this for disk 0 as we need it to be able to + * configure the controller. + */ + if (clear_all){ + /* This isn't pretty, but we need to find the + * disk in our array and NULL our the pointer. + * This is so that we will call alloc_disk if + * this index is used again later. */ - if (clear_all){ - /* This isn't pretty, but we need to find the - * disk in our array and NULL our the pointer. - * This is so that we will call alloc_disk if - * this index is used again later. - */ - for (i=0; i < CISS_MAX_LUN; i++){ - if(h->gendisk[i] == disk){ - h->gendisk[i] = NULL; - break; - } + for (i=0; i < CISS_MAX_LUN; i++){ + if(h->gendisk[i] == disk){ + h->gendisk[i] = NULL; + break; } - put_disk(disk); } + put_disk(disk); } } else { set_capacity(disk, 0); @@ -2365,30 +2363,55 @@ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c) start_io(h); } +static inline unsigned int make_status_bytes(unsigned int scsi_status_byte, + unsigned int msg_byte, unsigned int host_byte, + unsigned int driver_byte) +{ + /* inverse of macros in scsi.h */ + return (scsi_status_byte & 0xff) | + ((msg_byte & 0xff) << 8) | + ((host_byte & 0xff) << 16) | + ((driver_byte & 0xff) << 24); +} + static inline int evaluate_target_status(CommandList_struct *cmd) { unsigned char sense_key; - int error_count = 1; + unsigned char status_byte, msg_byte, host_byte, driver_byte; + int error_value; + + /* If we get in here, it means we got "target status", that is, scsi status */ + status_byte = cmd->err_info->ScsiStatus; + driver_byte = DRIVER_OK; + msg_byte = cmd->err_info->CommandStatus; /* correct? seems too device specific */ + + if (blk_pc_request(cmd->rq)) + host_byte = DID_PASSTHROUGH; + else + host_byte = DID_OK; + + error_value = make_status_bytes(status_byte, msg_byte, + host_byte, driver_byte); - if (cmd->err_info->ScsiStatus != 0x02) { /* not check condition? */ + if (cmd->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) { if (!blk_pc_request(cmd->rq)) printk(KERN_WARNING "cciss: cmd %p " "has SCSI Status 0x%x\n", cmd, cmd->err_info->ScsiStatus); - return error_count; + return error_value; } /* check the sense key */ sense_key = 0xf & cmd->err_info->SenseInfo[2]; /* no status or recovered error */ - if ((sense_key == 0x0) || (sense_key == 0x1)) - error_count = 0; + if (((sense_key == 0x0) || (sense_key == 0x1)) && !blk_pc_request(cmd->rq)) + error_value = 0; if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */ - if (error_count != 0) + if (error_value != 0) printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION" " sense key = 0x%x\n", cmd, sense_key); - return error_count; + return error_value; } /* SG_IO or similar, copy sense data back */ @@ -2400,7 +2423,7 @@ static inline int evaluate_target_status(CommandList_struct *cmd) } else cmd->rq->sense_len = 0; - return error_count; + return error_value; } /* checks the status of the job and calls complete buffers to mark all @@ -2416,7 +2439,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, rq->errors = 0; if (timeout) - rq->errors = 1; + rq->errors = make_status_bytes(0, 0, 0, DRIVER_TIMEOUT); if (cmd->err_info->CommandStatus == 0) /* no error has occurred */ goto after_error_processing; @@ -2442,32 +2465,44 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, case CMD_INVALID: printk(KERN_WARNING "cciss: cmd %p is " "reported invalid\n", cmd); - rq->errors = 1; + rq->errors = make_status_bytes(SAM_STAT_GOOD, + cmd->err_info->CommandStatus, DRIVER_OK, + blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); break; case CMD_PROTOCOL_ERR: printk(KERN_WARNING "cciss: cmd %p has " "protocol error \n", cmd); - rq->errors = 1; + rq->errors = make_status_bytes(SAM_STAT_GOOD, + cmd->err_info->CommandStatus, DRIVER_OK, + blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); break; case CMD_HARDWARE_ERR: printk(KERN_WARNING "cciss: cmd %p had " " hardware error\n", cmd); - rq->errors = 1; + rq->errors = make_status_bytes(SAM_STAT_GOOD, + cmd->err_info->CommandStatus, DRIVER_OK, + blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); break; case CMD_CONNECTION_LOST: printk(KERN_WARNING "cciss: cmd %p had " "connection lost\n", cmd); - rq->errors = 1; + rq->errors = make_status_bytes(SAM_STAT_GOOD, + cmd->err_info->CommandStatus, DRIVER_OK, + blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); break; case CMD_ABORTED: printk(KERN_WARNING "cciss: cmd %p was " "aborted\n", cmd); - rq->errors = 1; + rq->errors = make_status_bytes(SAM_STAT_GOOD, + cmd->err_info->CommandStatus, DRIVER_OK, + blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ABORT); break; case CMD_ABORT_FAILED: printk(KERN_WARNING "cciss: cmd %p reports " "abort failed\n", cmd); - rq->errors = 1; + rq->errors = make_status_bytes(SAM_STAT_GOOD, + cmd->err_info->CommandStatus, DRIVER_OK, + blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); break; case CMD_UNSOLICITED_ABORT: printk(KERN_WARNING "cciss%d: unsolicited " @@ -2481,17 +2516,23 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, printk(KERN_WARNING "cciss%d: %p retried too " "many times\n", h->ctlr, cmd); - rq->errors = 1; + rq->errors = make_status_bytes(SAM_STAT_GOOD, + cmd->err_info->CommandStatus, DRIVER_OK, + blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ABORT); break; case CMD_TIMEOUT: printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); - rq->errors = 1; + rq->errors = make_status_bytes(SAM_STAT_GOOD, + cmd->err_info->CommandStatus, DRIVER_OK, + blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); break; default: printk(KERN_WARNING "cciss: cmd %p returned " "unknown status %x\n", cmd, cmd->err_info->CommandStatus); - rq->errors = 1; + rq->errors = make_status_bytes(SAM_STAT_GOOD, + cmd->err_info->CommandStatus, DRIVER_OK, + blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); } after_error_processing: diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 80483aac4cc9..639ed14bb08d 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -5,6 +5,7 @@ * Copyright (C) 1993, 1994 Alain Knaff * Copyright (C) 1998 Alan Cox */ + /* * 02.12.91 - Changed to static variables to indicate need for reset * and recalibrate. This makes some things easier (output_byte reset @@ -149,7 +150,7 @@ #define REALLY_SLOW_IO #define DEBUGT 2 -#define DCL_DEBUG /* debug disk change line */ +#define DCL_DEBUG /* debug disk change line */ /* do print messages for unexpected interrupts */ static int print_unex = 1; @@ -161,10 +162,8 @@ static int print_unex = 1; #include <linux/workqueue.h> #define FDPATCHES #include <linux/fdreg.h> - #include <linux/fd.h> #include <linux/hdreg.h> - #include <linux/errno.h> #include <linux/slab.h> #include <linux/mm.h> @@ -274,8 +273,7 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l) return; /* we have the memory */ if (can_use_virtual_dma != 2) return; /* no fallback allowed */ - printk - ("DMA memory shortage. Temporarily falling back on virtual DMA\n"); + printk("DMA memory shortage. Temporarily falling back on virtual DMA\n"); *addr = (char *)nodma_mem_alloc(l); #else return; @@ -291,8 +289,8 @@ static int initialising = 1; #define TOMINOR(x) ((x & 3) | ((x & 4) << 5)) #define UNIT(x) ((x) & 0x03) /* drive on fdc */ #define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */ + /* reverse mapping from unit and fdc to drive */ #define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2)) - /* reverse mapping from unit and fdc to drive */ #define DP (&drive_params[current_drive]) #define DRS (&drive_state[current_drive]) #define DRWE (&write_errors[current_drive]) @@ -356,7 +354,6 @@ static int inr; /* size of reply buffer, when called from interrupt */ #define R_HEAD (reply_buffer[4]) #define R_SECTOR (reply_buffer[5]) #define R_SIZECODE (reply_buffer[6]) - #define SEL_DLY (2*HZ/100) /* @@ -472,8 +469,8 @@ static struct floppy_struct floppy_type[32] = { { 6400,40,2,80,0,0x25,0x5B,0xCF,0x00,"E3200" }, /* 26 3.20MB 3.5" */ { 7040,44,2,80,0,0x25,0x5B,0xCF,0x00,"E3520" }, /* 27 3.52MB 3.5" */ { 7680,48,2,80,0,0x25,0x63,0xCF,0x00,"E3840" }, /* 28 3.84MB 3.5" */ - { 3680,23,2,80,0,0x1C,0x10,0xCF,0x00,"H1840" }, /* 29 1.84MB 3.5" */ + { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" }, /* 30 800KB 3.5" */ { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5" */ }; @@ -539,12 +536,12 @@ static char *floppy_track_buffer; static int max_buffer_sectors; static int *errors; -typedef void (*done_f) (int); +typedef void (*done_f)(int); static struct cont_t { - void (*interrupt) (void); /* this is called after the interrupt of the + void (*interrupt)(void); /* this is called after the interrupt of the * main command */ - void (*redo) (void); /* this is called to retry the operation */ - void (*error) (void); /* this is called to tally an error */ + void (*redo)(void); /* this is called to retry the operation */ + void (*error)(void); /* this is called to tally an error */ done_f done; /* this is called to say if the operation has * succeeded/failed */ } *cont; @@ -694,7 +691,6 @@ static void reschedule_timeout(int drive, const char *message, int marg) } #define INFBOUND(a,b) (a)=max_t(int, a, b) - #define SUPBOUND(a,b) (a)=min_t(int, a, b) /* @@ -733,6 +729,7 @@ static void reschedule_timeout(int drive, const char *message, int marg) static int disk_change(int drive) { int fdc = FDC(drive); + #ifdef FLOPPY_SANITY_CHECK if (time_before(jiffies, UDRS->select_date + UDP->select_delay)) DPRINT("WARNING disk change called early\n"); @@ -771,7 +768,6 @@ static int disk_change(int drive) floppy_sizes[TOMINOR(drive)] = MAX_DISK_SIZE << 1; } - /*USETF(FD_DISK_NEWCHANGE); */ return 1; } else { UDRS->last_checked = jiffies; @@ -787,7 +783,10 @@ static inline int is_selected(int dor, int unit) static int set_dor(int fdc, char mask, char data) { - register unsigned char drive, unit, newdor, olddor; + unsigned char unit; + unsigned char drive; + unsigned char newdor; + unsigned char olddor; if (FDCS->address == -1) return -1; @@ -892,7 +891,6 @@ static int _lock_fdc(int drive, int interruptible, int line) set_current_state(TASK_RUNNING); remove_wait_queue(&fdc_wait, &wait); - flush_scheduled_work(); } command_status = FD_COMMAND_NONE; @@ -942,7 +940,7 @@ static void motor_off_callback(unsigned long nr) static void floppy_off(unsigned int drive) { unsigned long volatile delta; - register int fdc = FDC(drive); + int fdc = FDC(drive); if (!(FDCS->dor & (0x10 << UNIT(drive)))) return; @@ -968,7 +966,9 @@ static void floppy_off(unsigned int drive) */ static void scandrives(void) { - int i, drive, saved_drive; + int i; + int drive; + int saved_drive; if (DP->select_delay) return; @@ -1146,7 +1146,9 @@ static void show_floppy(void); /* waits until the fdc becomes ready */ static int wait_til_ready(void) { - int counter, status; + int status; + int counter; + if (FDCS->reset) return -1; for (counter = 0; counter < 10000; counter++) { @@ -1193,7 +1195,8 @@ static int output_byte(char byte) /* gets the response from the fdc */ static int result(void) { - int i, status = 0; + int i; + int status = 0; for (i = 0; i < MAX_REPLIES; i++) { if ((status = wait_til_ready()) < 0) @@ -1226,6 +1229,7 @@ static int result(void) static int need_more_output(void) { int status; + if ((status = wait_til_ready()) < 0) return -1; if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY) @@ -1309,8 +1313,11 @@ static int fdc_configure(void) */ static void fdc_specify(void) { - unsigned char spec1, spec2; - unsigned long srt, hlt, hut; + unsigned char spec1; + unsigned char spec2; + unsigned long srt; + unsigned long hlt; + unsigned long hut; unsigned long dtr = NOMINAL_DTR; unsigned long scale_dtr = NOMINAL_DTR; int hlt_max_code = 0x7f; @@ -1319,7 +1326,6 @@ static void fdc_specify(void) if (FDCS->need_configure && FDCS->version >= FDC_82072A) { fdc_configure(); FDCS->need_configure = 0; - /*DPRINT("FIFO enabled\n"); */ } switch (raw_cmd->rate & 0x03) { @@ -1472,7 +1478,6 @@ static int interpret_errors(void) tell_sector(); } printk("\n"); - } if (ST2 & ST2_WC || ST2 & ST2_BC) /* wrong cylinder => recal */ @@ -1498,7 +1503,10 @@ static int interpret_errors(void) */ static void setup_rw_floppy(void) { - int i, r, flags, dflags; + int i; + int r; + int flags; + int dflags; unsigned long ready_date; timeout_fn function; @@ -1728,9 +1736,9 @@ static void print_result(char *message, int inr) /* interrupt handler. Note that this can be called externally on the Sparc */ irqreturn_t floppy_interrupt(int irq, void *dev_id) { - void (*handler) (void) = do_floppy; int do_print; unsigned long f; + void (*handler)(void) = do_floppy; lasthandler = handler; interruptjiffies = jiffies; @@ -1912,12 +1920,11 @@ static void floppy_shutdown(unsigned long data) is_alive("floppy shutdown"); } -/*typedef void (*timeout_fn)(unsigned long);*/ - /* start motor, check media-changed condition and write protection */ -static int start_motor(void (*function) (void)) +static int start_motor(void (*function)(void)) { - int mask, data; + int mask; + int data; mask = 0xfc; data = UNIT(current_drive); @@ -2020,17 +2027,17 @@ static struct cont_t wakeup_cont = { .interrupt = empty, .redo = do_wakeup, .error = empty, - .done = (done_f) empty + .done = (done_f)empty }; static struct cont_t intr_cont = { .interrupt = empty, .redo = process_fd_request, .error = empty, - .done = (done_f) empty + .done = (done_f)empty }; -static int wait_til_done(void (*handler) (void), int interruptible) +static int wait_til_done(void (*handler)(void), int interruptible) { int ret; @@ -2049,7 +2056,6 @@ static int wait_til_done(void (*handler) (void), int interruptible) break; is_alive("wait_til_done"); - schedule(); } @@ -2141,6 +2147,7 @@ static void bad_flp_intr(void) static void set_floppy(int drive) { int type = ITYPE(UDRS->fd_device); + if (type) _floppy = floppy_type + type; else @@ -2169,11 +2176,14 @@ static void format_interrupt(void) #define CT(x) ((x) | 0xc0) static void setup_format_params(int track) { + int n; + int il; + int count; + int head_shift; + int track_shift; struct fparm { unsigned char track, head, sect, size; } *here = (struct fparm *)floppy_track_buffer; - int il, n; - int count, head_shift, track_shift; raw_cmd = &default_raw_cmd; raw_cmd->track = track; @@ -2344,7 +2354,10 @@ static void request_done(int uptodate) /* Interrupt handler evaluating the result of the r/w operation */ static void rw_interrupt(void) { - int nr_sectors, ssize, eoc, heads; + int eoc; + int ssize; + int heads; + int nr_sectors; if (R_HEAD >= 2) { /* some Toshiba floppy controllers occasionnally seem to @@ -2476,7 +2489,8 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) { int remaining; /* number of transferred 512-byte sectors */ struct bio_vec *bv; - char *buffer, *dma_buffer; + char *buffer; + char *dma_buffer; int size; struct req_iterator iter; @@ -2556,19 +2570,6 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) #endif } -#if 0 -static inline int check_dma_crossing(char *start, - unsigned long length, char *message) -{ - if (CROSS_64KB(start, length)) { - printk("DMA xfer crosses 64KB boundary in %s %p-%p\n", - message, start, start + length); - return 1; - } else - return 0; -} -#endif - /* work around a bug in pseudo DMA * (on some FDCs) pseudo DMA does not stop when the CPU stops * sending data. Hence we need a different way to signal the @@ -2578,7 +2579,8 @@ static inline int check_dma_crossing(char *start, */ static void virtualdmabug_workaround(void) { - int hard_sectors, end_sector; + int hard_sectors; + int end_sector; if (CT(COMMAND) == FD_WRITE) { COMMAND &= ~0x80; /* switch off multiple track mode */ @@ -2610,7 +2612,10 @@ static void virtualdmabug_workaround(void) static int make_raw_rw_request(void) { int aligned_sector_t; - int max_sector, max_size, tracksize, ssize; + int max_sector; + int max_size; + int tracksize; + int ssize; if (max_buffer_sectors == 0) { printk("VFS: Block I/O scheduled on unopened device\n"); @@ -2762,9 +2767,7 @@ static int make_raw_rw_request(void) */ if (!direct || (indirect * 2 > direct * 3 && - *errors < DP->max_errors.read_track && - /*!TESTF(FD_NEED_TWADDLE) && */ - ((!probing + *errors < DP->max_errors.read_track && ((!probing || (DP->read_track & (1 << DRS->probed_format)))))) { max_size = current_req->nr_sectors; } else { @@ -2777,10 +2780,6 @@ static int make_raw_rw_request(void) indirect, direct, fsector_t); return 0; } -/* check_dma_crossing(raw_cmd->kernel_data, - raw_cmd->length, - "end of make_raw_request [1]");*/ - virtualdmabug_workaround(); return 2; } @@ -2830,8 +2829,6 @@ static int make_raw_rw_request(void) raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1; raw_cmd->length <<= 9; #ifdef FLOPPY_SANITY_CHECK - /*check_dma_crossing(raw_cmd->kernel_data, raw_cmd->length, - "end of make_raw_request"); */ if ((raw_cmd->length < current_count_sectors << 9) || (raw_cmd->kernel_data != current_req->buffer && CT(COMMAND) == FD_WRITE && @@ -3011,6 +3008,7 @@ static struct cont_t poll_cont = { static int poll_drive(int interruptible, int flag) { int ret; + /* no auto-sense, just clear dcl */ raw_cmd = &default_raw_cmd; raw_cmd->flags = flag; @@ -3173,7 +3171,8 @@ static inline int raw_cmd_copyout(int cmd, char __user *param, static void raw_cmd_free(struct floppy_raw_cmd **ptr) { - struct floppy_raw_cmd *next, *this; + struct floppy_raw_cmd *next; + struct floppy_raw_cmd *this; this = *ptr; *ptr = NULL; @@ -3245,8 +3244,10 @@ static inline int raw_cmd_copyin(int cmd, char __user *param, static int raw_cmd_ioctl(int cmd, void __user *param) { - int drive, ret, ret2; struct floppy_raw_cmd *my_raw_cmd; + int drive; + int ret2; + int ret; if (FDCS->rawcmd <= 1) FDCS->rawcmd = 1; @@ -3453,7 +3454,8 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0 int drive = (long)inode->i_bdev->bd_disk->private_data; - int i, type = ITYPE(UDRS->fd_device); + int type = ITYPE(UDRS->fd_device); + int i; int ret; int size; union inparam { @@ -3619,8 +3621,7 @@ static void __init config_types(void) if (!UDP->cmos && FLOPPY1_TYPE) UDP->cmos = FLOPPY1_TYPE; - /* XXX */ - /* additional physical CMOS drive detection should go here */ + /* FIXME: additional physical CMOS drive detection should go here */ for (drive = 0; drive < N_DRIVE; drive++) { unsigned int type = UDP->cmos; @@ -3903,13 +3904,13 @@ static int floppy_revalidate(struct gendisk *disk) } static struct block_device_operations floppy_fops = { - .owner = THIS_MODULE, - .open = floppy_open, - .release = floppy_release, - .ioctl = fd_ioctl, - .getgeo = fd_getgeo, - .media_changed = check_floppy_change, - .revalidate_disk = floppy_revalidate, + .owner = THIS_MODULE, + .open = floppy_open, + .release = floppy_release, + .ioctl = fd_ioctl, + .getgeo = fd_getgeo, + .media_changed = check_floppy_change, + .revalidate_disk = floppy_revalidate, }; /* @@ -4388,11 +4389,15 @@ static int floppy_grab_irq_and_dma(void) if (fd_request_dma()) { DPRINT("Unable to grab DMA%d for the floppy driver\n", FLOPPY_DMA); - fd_free_irq(); - spin_lock_irqsave(&floppy_usage_lock, flags); - usage_count--; - spin_unlock_irqrestore(&floppy_usage_lock, flags); - return -1; + if (can_use_virtual_dma & 2) + use_virtual_dma = can_use_virtual_dma = 1; + if (!(can_use_virtual_dma & 1)) { + fd_free_irq(); + spin_lock_irqsave(&floppy_usage_lock, flags); + usage_count--; + spin_unlock_irqrestore(&floppy_usage_lock, flags); + return -1; + } } for (fdc = 0; fdc < N_FDC; fdc++) { @@ -4424,8 +4429,8 @@ static int floppy_grab_irq_and_dma(void) if (FDCS->address != -1) fd_outb(FDCS->dor, FD_DOR); /* - * The driver will try and free resources and relies on us - * to know if they were allocated or not. + * The driver will try and free resources and relies on us + * to know if they were allocated or not. */ fdc = 0; irqdma_allocated = 1; diff --git a/drivers/block/loop.c b/drivers/block/loop.c index e5a051577a5e..589cbbd9cd4f 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1285,7 +1285,6 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a struct loop_device *lo = inode->i_bdev->bd_disk->private_data; int err; - lock_kernel(); switch(cmd) { case LOOP_SET_STATUS: mutex_lock(&lo->lo_ctl_mutex); @@ -1311,7 +1310,6 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a err = -ENOIOCTLCMD; break; } - unlock_kernel(); return err; } #endif diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index be5ec3a9b1fc..cb136a919f2a 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -113,12 +113,42 @@ static void nbd_end_request(struct request *req) spin_unlock_irqrestore(q->queue_lock, flags); } +static void sock_shutdown(struct nbd_device *lo, int lock) +{ + /* Forcibly shutdown the socket causing all listeners + * to error + * + * FIXME: This code is duplicated from sys_shutdown, but + * there should be a more generic interface rather than + * calling socket ops directly here */ + if (lock) + mutex_lock(&lo->tx_lock); + if (lo->sock) { + printk(KERN_WARNING "%s: shutting down socket\n", + lo->disk->disk_name); + lo->sock->ops->shutdown(lo->sock, SEND_SHUTDOWN|RCV_SHUTDOWN); + lo->sock = NULL; + } + if (lock) + mutex_unlock(&lo->tx_lock); +} + +static void nbd_xmit_timeout(unsigned long arg) +{ + struct task_struct *task = (struct task_struct *)arg; + + printk(KERN_WARNING "nbd: killing hung xmit (%s, pid: %d)\n", + task->comm, task->pid); + force_sig(SIGKILL, task); +} + /* * Send or receive packet. */ -static int sock_xmit(struct socket *sock, int send, void *buf, int size, +static int sock_xmit(struct nbd_device *lo, int send, void *buf, int size, int msg_flags) { + struct socket *sock = lo->sock; int result; struct msghdr msg; struct kvec iov; @@ -139,9 +169,20 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size, msg.msg_controllen = 0; msg.msg_flags = msg_flags | MSG_NOSIGNAL; - if (send) + if (send) { + struct timer_list ti; + + if (lo->xmit_timeout) { + init_timer(&ti); + ti.function = nbd_xmit_timeout; + ti.data = (unsigned long)current; + ti.expires = jiffies + lo->xmit_timeout; + add_timer(&ti); + } result = kernel_sendmsg(sock, &msg, &iov, 1, size); - else + if (lo->xmit_timeout) + del_timer_sync(&ti); + } else result = kernel_recvmsg(sock, &msg, &iov, 1, size, 0); if (signal_pending(current)) { @@ -150,6 +191,7 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size, current->pid, current->comm, dequeue_signal_lock(current, ¤t->blocked, &info)); result = -EINTR; + sock_shutdown(lo, !send); break; } @@ -167,23 +209,22 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size, return result; } -static inline int sock_send_bvec(struct socket *sock, struct bio_vec *bvec, +static inline int sock_send_bvec(struct nbd_device *lo, struct bio_vec *bvec, int flags) { int result; void *kaddr = kmap(bvec->bv_page); - result = sock_xmit(sock, 1, kaddr + bvec->bv_offset, bvec->bv_len, - flags); + result = sock_xmit(lo, 1, kaddr + bvec->bv_offset, bvec->bv_len, flags); kunmap(bvec->bv_page); return result; } +/* always call with the tx_lock held */ static int nbd_send_req(struct nbd_device *lo, struct request *req) { int result, flags; struct nbd_request request; unsigned long size = req->nr_sectors << 9; - struct socket *sock = lo->sock; request.magic = htonl(NBD_REQUEST_MAGIC); request.type = htonl(nbd_cmd(req)); @@ -196,8 +237,8 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req) nbdcmd_to_ascii(nbd_cmd(req)), (unsigned long long)req->sector << 9, req->nr_sectors << 9); - result = sock_xmit(sock, 1, &request, sizeof(request), - (nbd_cmd(req) == NBD_CMD_WRITE)? MSG_MORE: 0); + result = sock_xmit(lo, 1, &request, sizeof(request), + (nbd_cmd(req) == NBD_CMD_WRITE) ? MSG_MORE : 0); if (result <= 0) { printk(KERN_ERR "%s: Send control failed (result %d)\n", lo->disk->disk_name, result); @@ -217,7 +258,7 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req) flags = MSG_MORE; dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n", lo->disk->disk_name, req, bvec->bv_len); - result = sock_send_bvec(sock, bvec, flags); + result = sock_send_bvec(lo, bvec, flags); if (result <= 0) { printk(KERN_ERR "%s: Send data failed (result %d)\n", lo->disk->disk_name, result); @@ -231,22 +272,18 @@ error_out: return 1; } -static struct request *nbd_find_request(struct nbd_device *lo, char *handle) +static struct request *nbd_find_request(struct nbd_device *lo, + struct request *xreq) { - struct request *req; - struct list_head *tmp; - struct request *xreq; + struct request *req, *tmp; int err; - memcpy(&xreq, handle, sizeof(xreq)); - err = wait_event_interruptible(lo->active_wq, lo->active_req != xreq); if (unlikely(err)) goto out; spin_lock(&lo->queue_lock); - list_for_each(tmp, &lo->queue_head) { - req = list_entry(tmp, struct request, queuelist); + list_for_each_entry_safe(req, tmp, &lo->queue_head, queuelist) { if (req != xreq) continue; list_del_init(&req->queuelist); @@ -261,11 +298,11 @@ out: return ERR_PTR(err); } -static inline int sock_recv_bvec(struct socket *sock, struct bio_vec *bvec) +static inline int sock_recv_bvec(struct nbd_device *lo, struct bio_vec *bvec) { int result; void *kaddr = kmap(bvec->bv_page); - result = sock_xmit(sock, 0, kaddr + bvec->bv_offset, bvec->bv_len, + result = sock_xmit(lo, 0, kaddr + bvec->bv_offset, bvec->bv_len, MSG_WAITALL); kunmap(bvec->bv_page); return result; @@ -277,10 +314,9 @@ static struct request *nbd_read_stat(struct nbd_device *lo) int result; struct nbd_reply reply; struct request *req; - struct socket *sock = lo->sock; reply.magic = 0; - result = sock_xmit(sock, 0, &reply, sizeof(reply), MSG_WAITALL); + result = sock_xmit(lo, 0, &reply, sizeof(reply), MSG_WAITALL); if (result <= 0) { printk(KERN_ERR "%s: Receive control failed (result %d)\n", lo->disk->disk_name, result); @@ -295,7 +331,7 @@ static struct request *nbd_read_stat(struct nbd_device *lo) goto harderror; } - req = nbd_find_request(lo, reply.handle); + req = nbd_find_request(lo, *(struct request **)reply.handle); if (unlikely(IS_ERR(req))) { result = PTR_ERR(req); if (result != -ENOENT) @@ -321,7 +357,7 @@ static struct request *nbd_read_stat(struct nbd_device *lo) struct bio_vec *bvec; rq_for_each_segment(bvec, req, iter) { - result = sock_recv_bvec(sock, bvec); + result = sock_recv_bvec(lo, bvec); if (result <= 0) { printk(KERN_ERR "%s: Receive data failed (result %d)\n", lo->disk->disk_name, result); @@ -396,6 +432,7 @@ static void nbd_clear_que(struct nbd_device *lo) } } + /* * We always wait for result of write, for now. It would be nice to make it optional * in future @@ -504,7 +541,9 @@ static int nbd_ioctl(struct inode *inode, struct file *file, sreq.nr_sectors = 0; if (!lo->sock) return -EINVAL; + mutex_lock(&lo->tx_lock); nbd_send_req(lo, &sreq); + mutex_unlock(&lo->tx_lock); return 0; case NBD_CLEAR_SOCK: @@ -548,6 +587,9 @@ static int nbd_ioctl(struct inode *inode, struct file *file, set_blocksize(inode->i_bdev, lo->blksize); set_capacity(lo->disk, lo->bytesize >> 9); return 0; + case NBD_SET_TIMEOUT: + lo->xmit_timeout = arg * HZ; + return 0; case NBD_SET_SIZE_BLOCKS: lo->bytesize = ((u64) arg) * lo->blksize; inode->i_bdev->bd_inode->i_size = lo->bytesize; @@ -560,28 +602,16 @@ static int nbd_ioctl(struct inode *inode, struct file *file, error = nbd_do_it(lo); if (error) return error; - /* on return tidy up in case we have a signal */ - /* Forcibly shutdown the socket causing all listeners - * to error - * - * FIXME: This code is duplicated from sys_shutdown, but - * there should be a more generic interface rather than - * calling socket ops directly here */ - mutex_lock(&lo->tx_lock); - if (lo->sock) { - printk(KERN_WARNING "%s: shutting down socket\n", - lo->disk->disk_name); - lo->sock->ops->shutdown(lo->sock, - SEND_SHUTDOWN|RCV_SHUTDOWN); - lo->sock = NULL; - } - mutex_unlock(&lo->tx_lock); + sock_shutdown(lo, 1); file = lo->file; lo->file = NULL; nbd_clear_que(lo); printk(KERN_WARNING "%s: queue cleared\n", lo->disk->disk_name); if (file) fput(file); + lo->bytesize = 0; + inode->i_bdev->bd_inode->i_size = 0; + set_capacity(lo->disk, 0); return lo->harderror; case NBD_CLEAR_QUE: /* @@ -659,14 +689,14 @@ static int __init nbd_init(void) mutex_init(&nbd_dev[i].tx_lock); init_waitqueue_head(&nbd_dev[i].active_wq); nbd_dev[i].blksize = 1024; - nbd_dev[i].bytesize = 0x7ffffc00ULL << 10; /* 2TB */ + nbd_dev[i].bytesize = 0; disk->major = NBD_MAJOR; disk->first_minor = i; disk->fops = &nbd_fops; disk->private_data = &nbd_dev[i]; disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; sprintf(disk->disk_name, "nbd%d", i); - set_capacity(disk, 0x7ffffc00ULL << 1); /* 2 TB */ + set_capacity(disk, 0); add_disk(disk); } diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 701ea77f62e9..08176d23a46c 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c @@ -411,6 +411,9 @@ static void __exit rd_cleanup(void) blk_cleanup_queue(rd_queue[i]); } unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); + + bdi_destroy(&rd_file_backing_dev_info); + bdi_destroy(&rd_backing_dev_info); } /* @@ -419,7 +422,19 @@ static void __exit rd_cleanup(void) static int __init rd_init(void) { int i; - int err = -ENOMEM; + int err; + + err = bdi_init(&rd_backing_dev_info); + if (err) + goto out2; + + err = bdi_init(&rd_file_backing_dev_info); + if (err) { + bdi_destroy(&rd_backing_dev_info); + goto out2; + } + + err = -ENOMEM; if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 || (rd_blocksize & (rd_blocksize-1))) { @@ -473,6 +488,9 @@ out: put_disk(rd_disks[i]); blk_cleanup_queue(rd_queue[i]); } + bdi_destroy(&rd_backing_dev_info); + bdi_destroy(&rd_file_backing_dev_info); +out2: return err; } @@ -486,17 +504,12 @@ static int __init ramdisk_size(char *str) rd_size = simple_strtol(str,NULL,0); return 1; } -static int __init ramdisk_size2(char *str) /* kludge */ -{ - return ramdisk_size(str); -} static int __init ramdisk_blocksize(char *str) { rd_blocksize = simple_strtol(str,NULL,0); return 1; } -__setup("ramdisk=", ramdisk_size); -__setup("ramdisk_size=", ramdisk_size2); +__setup("ramdisk_size=", ramdisk_size); __setup("ramdisk_blocksize=", ramdisk_blocksize); #endif diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index f6f8c03047fa..204d53e506de 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -36,6 +36,23 @@ config VT If unsure, say Y, or else you won't be able to do much with your new shiny Linux system :-) +config VT_UNICODE + bool "Virtual console is Unicode by default" + depends on VT + default n + ---help--- + If you say Y here, the virtual terminal will be in UTF-8 by default, + and the keyboard will run in unicode mode. + + If you say N here, the virtual terminal will not be in UTF-8 by + default, and the keyboard will run in XLATE mode. + + This can also be changed by passing 'default_utf8=<0|1>' on the + kernel command line. + + Historically, the kernel has defaulted to non-UTF8 and XLATE mode. + If unsure, say N here. + config VT_CONSOLE bool "Support for console on virtual terminal" if EMBEDDED depends on VT @@ -568,8 +585,8 @@ config TIPAR config HVC_DRIVER bool help - Users of pSeries machines that want to utilize the hvc console front-end - module for their backend console driver should select this option. + Generic "hypervisor virtual console" infrastructure for various + hypervisors (pSeries, iSeries, Xen, lguest). It will automatically be selected if one of the back-end console drivers is selected. diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 313a133a1172..cbb0444467ba 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -14,15 +14,12 @@ #include <linux/pci.h> #include <linux/init.h> #include <linux/agp_backend.h> +#include <linux/log2.h> #include <asm/acpi-ext.h> #include "agp.h" -#ifndef log2 -#define log2(x) ffz(~(x)) -#endif - #define HP_ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */ /* HP ZX1 IOC registers */ @@ -257,7 +254,7 @@ hp_zx1_configure (void) readl(hp->ioc_regs+HP_ZX1_IMASK); writel(hp->iova_base|1, hp->ioc_regs+HP_ZX1_IBASE); readl(hp->ioc_regs+HP_ZX1_IBASE); - writel(hp->iova_base|log2(HP_ZX1_IOVA_SIZE), hp->ioc_regs+HP_ZX1_PCOM); + writel(hp->iova_base|ilog2(HP_ZX1_IOVA_SIZE), hp->ioc_regs+HP_ZX1_PCOM); readl(hp->ioc_regs+HP_ZX1_PCOM); } @@ -285,7 +282,7 @@ hp_zx1_tlbflush (struct agp_memory *mem) { struct _hp_private *hp = &hp_private; - writeq(hp->gart_base | log2(hp->gart_size), hp->ioc_regs+HP_ZX1_PCOM); + writeq(hp->gart_base | ilog2(hp->gart_size), hp->ioc_regs+HP_ZX1_PCOM); readq(hp->ioc_regs+HP_ZX1_PCOM); } diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index 70117df4d067..e72a83e2bad5 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c @@ -13,6 +13,7 @@ #include <linux/string.h> #include <linux/slab.h> #include <linux/agp_backend.h> +#include <linux/log2.h> #include "agp.h" @@ -59,8 +60,6 @@ */ #define WR_FLUSH_GATT(index) RD_GATT(index) -#define log2(x) ffz(~(x)) - static struct { void *gatt; /* ioremap'd GATT area */ @@ -148,7 +147,7 @@ static int i460_fetch_size (void) * values[i].size. */ values[i].num_entries = (values[i].size << 8) >> (I460_IO_PAGE_SHIFT - 12); - values[i].page_order = log2((sizeof(u32)*values[i].num_entries) >> PAGE_SHIFT); + values[i].page_order = ilog2((sizeof(u32)*values[i].num_entries) >> PAGE_SHIFT); } for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) { diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index f4562cc22343..2939e3570f9d 100644 --- a/drivers/char/agp/parisc-agp.c +++ b/drivers/char/agp/parisc-agp.c @@ -18,6 +18,7 @@ #include <linux/init.h> #include <linux/klist.h> #include <linux/agp_backend.h> +#include <linux/log2.h> #include <asm-parisc/parisc-device.h> #include <asm-parisc/ropes.h> @@ -27,10 +28,6 @@ #define DRVNAME "quicksilver" #define DRVPFX DRVNAME ": " -#ifndef log2 -#define log2(x) ffz(~(x)) -#endif - #define AGP8X_MODE_BIT 3 #define AGP8X_MODE (1 << AGP8X_MODE_BIT) @@ -92,7 +89,7 @@ parisc_agp_tlbflush(struct agp_memory *mem) { struct _parisc_agp_info *info = &parisc_agp_info; - writeq(info->gart_base | log2(info->gart_size), info->ioc_regs+IOC_PCOM); + writeq(info->gart_base | ilog2(info->gart_size), info->ioc_regs+IOC_PCOM); readq(info->ioc_regs+IOC_PCOM); /* flush */ } diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c index 4b3916f54909..6b104e45a322 100644 --- a/drivers/char/consolemap.c +++ b/drivers/char/consolemap.c @@ -494,12 +494,11 @@ int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui) p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; if (p && p->readonly) return -EIO; if (!p || --p->refcount) { - q = kmalloc(sizeof(*p), GFP_KERNEL); + q = kzalloc(sizeof(*p), GFP_KERNEL); if (!q) { if (p) p->refcount++; return -ENOMEM; } - memset(q, 0, sizeof(*q)); q->refcount=1; *vc->vc_uni_pagedir_loc = (unsigned long)q; } else { @@ -670,19 +669,29 @@ void con_protect_unimap(struct vc_data *vc, int rdonly) p->readonly = rdonly; } +/* + * Always use USER_MAP. These functions are used by the keyboard, + * which shouldn't be affected by G0/G1 switching, etc. + * If the user map still contains default values, i.e. the + * direct-to-font mapping, then assume user is using Latin1. + */ /* may be called during an interrupt */ u32 conv_8bit_to_uni(unsigned char c) { - /* - * Always use USER_MAP. This function is used by the keyboard, - * which shouldn't be affected by G0/G1 switching, etc. - * If the user map still contains default values, i.e. the - * direct-to-font mapping, then assume user is using Latin1. - */ unsigned short uni = translations[USER_MAP][c]; return uni == (0xf000 | c) ? c : uni; } +int conv_uni_to_8bit(u32 uni) +{ + int c; + for (c = 0; c < 0x100; c++) + if (translations[USER_MAP][c] == uni || + (translations[USER_MAP][c] == (c | 0xf000) && uni == c)) + return c; + return -1; +} + int conv_uni_to_pc(struct vc_data *conp, long ucs) { diff --git a/drivers/char/defkeymap.c_shipped b/drivers/char/defkeymap.c_shipped index 453a2f1ffa15..0aa419a61767 100644 --- a/drivers/char/defkeymap.c_shipped +++ b/drivers/char/defkeymap.c_shipped @@ -222,7 +222,7 @@ char *func_table[MAX_NR_FUNC] = { NULL, }; -struct kbdiacr accent_table[MAX_DIACR] = { +struct kbdiacruc accent_table[MAX_DIACR] = { {'`', 'A', '\300'}, {'`', 'a', '\340'}, {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, {'^', 'A', '\302'}, {'^', 'a', '\342'}, diff --git a/drivers/char/epca.c b/drivers/char/epca.c index c6c56fb8ba50..ffcecde9e2a5 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c @@ -1,34 +1,30 @@ /* - - Copyright (C) 1996 Digi International. - + For technical support please email digiLinux@dgii.com or call Digi tech support at (612) 912-3456 ** This driver is no longer supported by Digi ** - Much of this design and code came from epca.c which was - copyright (C) 1994, 1995 Troy De Jongh, and subsquently - modified by David Nugent, Christoph Lameter, Mike McLagan. - - 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. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - ---------------------------------------------------------------------------- */ -/* See README.epca for change history --DAT*/ + Much of this design and code came from epca.c which was + copyright (C) 1994, 1995 Troy De Jongh, and subsquently + modified by David Nugent, Christoph Lameter, Mike McLagan. + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* See README.epca for change history --DAT*/ #include <linux/module.h> #include <linux/kernel.h> @@ -54,13 +50,10 @@ #include "epca.h" #include "epcaconfig.h" -/* ---------------------- Begin defines ------------------------ */ - #define VERSION "1.3.0.1-LK2.6" /* This major needs to be submitted to Linux to join the majors list */ - -#define DIGIINFOMAJOR 35 /* For Digi specific ioctl */ +#define DIGIINFOMAJOR 35 /* For Digi specific ioctl */ #define MAXCARDS 7 @@ -68,60 +61,48 @@ #define PFX "epca: " -/* ----------------- Begin global definitions ------------------- */ - static int nbdevs, num_cards, liloconfig; static int digi_poller_inhibited = 1 ; static int setup_error_code; static int invalid_lilo_config; -/* The ISA boards do window flipping into the same spaces so its only sane - with a single lock. It's still pretty efficient */ - +/* + * The ISA boards do window flipping into the same spaces so its only sane with + * a single lock. It's still pretty efficient. + */ static DEFINE_SPINLOCK(epca_lock); -/* ----------------------------------------------------------------------- - MAXBOARDS is typically 12, but ISA and EISA cards are restricted to - 7 below. ---------------------------------------------------------------------------*/ +/* MAXBOARDS is typically 12, but ISA and EISA cards are restricted to 7 below. */ static struct board_info boards[MAXBOARDS]; - -/* ------------- Begin structures used for driver registeration ---------- */ - static struct tty_driver *pc_driver; static struct tty_driver *pc_info; /* ------------------ Begin Digi specific structures -------------------- */ -/* ------------------------------------------------------------------------ - digi_channels represents an array of structures that keep track of - each channel of the Digi product. Information such as transmit and - receive pointers, termio data, and signal definitions (DTR, CTS, etc ...) - are stored here. This structure is NOT used to overlay the cards - physical channel structure. --------------------------------------------------------------------------- */ - +/* + * digi_channels represents an array of structures that keep track of each + * channel of the Digi product. Information such as transmit and receive + * pointers, termio data, and signal definitions (DTR, CTS, etc ...) are stored + * here. This structure is NOT used to overlay the cards physical channel + * structure. + */ static struct channel digi_channels[MAX_ALLOC]; -/* ------------------------------------------------------------------------ - card_ptr is an array used to hold the address of the - first channel structure of each card. This array will hold - the addresses of various channels located in digi_channels. --------------------------------------------------------------------------- */ +/* + * card_ptr is an array used to hold the address of the first channel structure + * of each card. This array will hold the addresses of various channels located + * in digi_channels. + */ static struct channel *card_ptr[MAXCARDS]; static struct timer_list epca_timer; -/* ---------------------- Begin function prototypes --------------------- */ - -/* ---------------------------------------------------------------------- - Begin generic memory functions. These functions will be alias - (point at) more specific functions dependent on the board being - configured. ------------------------------------------------------------------------ */ - +/* + * Begin generic memory functions. These functions will be alias (point at) + * more specific functions dependent on the board being configured. + */ static void memwinon(struct board_info *b, unsigned int win); static void memwinoff(struct board_info *b, unsigned int win); static void globalwinon(struct channel *ch); @@ -170,8 +151,6 @@ static void dummy_memoff(struct channel *ch); static void dummy_assertgwinon(struct channel *ch); static void dummy_assertmemoff(struct channel *ch); -/* ------------------- Begin declare functions ----------------------- */ - static struct channel *verifyChannel(struct tty_struct *); static void pc_sched_event(struct channel *, int); static void epca_error(int, char *); @@ -213,62 +192,55 @@ static int pc_write(struct tty_struct *, const unsigned char *, int); static int pc_init(void); static int init_PCI(void); - -/* ------------------------------------------------------------------ - Table of functions for each board to handle memory. Mantaining - parallelism is a *very* good idea here. The idea is for the - runtime code to blindly call these functions, not knowing/caring - about the underlying hardware. This stuff should contain no - conditionals; if more functionality is needed a different entry - should be established. These calls are the interface calls and - are the only functions that should be accessed. Anyone caught - making direct calls deserves what they get. --------------------------------------------------------------------- */ - +/* + * Table of functions for each board to handle memory. Mantaining parallelism + * is a *very* good idea here. The idea is for the runtime code to blindly call + * these functions, not knowing/caring about the underlying hardware. This + * stuff should contain no conditionals; if more functionality is needed a + * different entry should be established. These calls are the interface calls + * and are the only functions that should be accessed. Anyone caught making + * direct calls deserves what they get. + */ static void memwinon(struct board_info *b, unsigned int win) { - (b->memwinon)(b, win); + b->memwinon(b, win); } static void memwinoff(struct board_info *b, unsigned int win) { - (b->memwinoff)(b, win); + b->memwinoff(b, win); } static void globalwinon(struct channel *ch) { - (ch->board->globalwinon)(ch); + ch->board->globalwinon(ch); } static void rxwinon(struct channel *ch) { - (ch->board->rxwinon)(ch); + ch->board->rxwinon(ch); } static void txwinon(struct channel *ch) { - (ch->board->txwinon)(ch); + ch->board->txwinon(ch); } static void memoff(struct channel *ch) { - (ch->board->memoff)(ch); + ch->board->memoff(ch); } static void assertgwinon(struct channel *ch) { - (ch->board->assertgwinon)(ch); + ch->board->assertgwinon(ch); } static void assertmemoff(struct channel *ch) { - (ch->board->assertmemoff)(ch); + ch->board->assertmemoff(ch); } -/* --------------------------------------------------------- - PCXEM windowing is the same as that used in the PCXR - and CX series cards. ------------------------------------------------------------- */ - +/* PCXEM windowing is the same as that used in the PCXR and CX series cards. */ static void pcxem_memwinon(struct board_info *b, unsigned int win) { outb_p(FEPWIN|win, b->port + 1); @@ -300,32 +272,30 @@ static void pcxem_memoff(struct channel *ch) } /* ----------------- Begin pcxe memory window stuff ------------------ */ - static void pcxe_memwinon(struct board_info *b, unsigned int win) { - outb_p(FEPWIN | win, b->port + 1); + outb_p(FEPWIN | win, b->port + 1); } static void pcxe_memwinoff(struct board_info *b, unsigned int win) { - outb_p(inb(b->port) & ~FEPMEM, - b->port + 1); + outb_p(inb(b->port) & ~FEPMEM, b->port + 1); outb_p(0, b->port + 1); } static void pcxe_globalwinon(struct channel *ch) { - outb_p( FEPWIN, (int)ch->board->port + 1); + outb_p(FEPWIN, (int)ch->board->port + 1); } static void pcxe_rxwinon(struct channel *ch) { - outb_p(ch->rxwin, (int)ch->board->port + 1); + outb_p(ch->rxwin, (int)ch->board->port + 1); } static void pcxe_txwinon(struct channel *ch) { - outb_p(ch->txwin, (int)ch->board->port + 1); + outb_p(ch->txwin, (int)ch->board->port + 1); } static void pcxe_memoff(struct channel *ch) @@ -335,10 +305,9 @@ static void pcxe_memoff(struct channel *ch) } /* ------------- Begin pc64xe and pcxi memory window stuff -------------- */ - static void pcxi_memwinon(struct board_info *b, unsigned int win) { - outb_p(inb(b->port) | FEPMEM, b->port); + outb_p(inb(b->port) | FEPMEM, b->port); } static void pcxi_memwinoff(struct board_info *b, unsigned int win) @@ -353,12 +322,12 @@ static void pcxi_globalwinon(struct channel *ch) static void pcxi_rxwinon(struct channel *ch) { - outb_p(FEPMEM, ch->board->port); + outb_p(FEPMEM, ch->board->port); } static void pcxi_txwinon(struct channel *ch) { - outb_p(FEPMEM, ch->board->port); + outb_p(FEPMEM, ch->board->port); } static void pcxi_memoff(struct channel *ch) @@ -376,16 +345,13 @@ static void pcxi_assertmemoff(struct channel *ch) epcaassert(!(inb(ch->board->port) & FEPMEM), "Memory on"); } - -/* ---------------------------------------------------------------------- - Not all of the cards need specific memory windowing routines. Some - cards (Such as PCI) needs no windowing routines at all. We provide - these do nothing routines so that the same code base can be used. - The driver will ALWAYS call a windowing routine if it thinks it needs - to; regardless of the card. However, dependent on the card the routine - may or may not do anything. ----------------------------------------------------------------------------*/ - +/* + * Not all of the cards need specific memory windowing routines. Some cards + * (Such as PCI) needs no windowing routines at all. We provide these do + * nothing routines so that the same code base can be used. The driver will + * ALWAYS call a windowing routine if it thinks it needs to; regardless of the + * card. However, dependent on the card the routine may or may not do anything. + */ static void dummy_memwinon(struct board_info *b, unsigned int win) { } @@ -418,15 +384,14 @@ static void dummy_assertmemoff(struct channel *ch) { } -/* ----------------- Begin verifyChannel function ----------------------- */ static struct channel *verifyChannel(struct tty_struct *tty) -{ /* Begin verifyChannel */ - /* -------------------------------------------------------------------- - This routine basically provides a sanity check. It insures that - the channel returned is within the proper range of addresses as - well as properly initialized. If some bogus info gets passed in - through tty->driver_data this should catch it. - --------------------------------------------------------------------- */ +{ + /* + * This routine basically provides a sanity check. It insures that the + * channel returned is within the proper range of addresses as well as + * properly initialized. If some bogus info gets passed in + * through tty->driver_data this should catch it. + */ if (tty) { struct channel *ch = (struct channel *)tty->driver_data; if ((ch >= &digi_channels[0]) && (ch < &digi_channels[nbdevs])) { @@ -435,62 +400,55 @@ static struct channel *verifyChannel(struct tty_struct *tty) } } return NULL; - -} /* End verifyChannel */ - -/* ------------------ Begin pc_sched_event ------------------------- */ +} static void pc_sched_event(struct channel *ch, int event) { - /* ---------------------------------------------------------------------- - We call this to schedule interrupt processing on some event. The - kernel sees our request and calls the related routine in OUR driver. - -------------------------------------------------------------------------*/ + /* + * We call this to schedule interrupt processing on some event. The + * kernel sees our request and calls the related routine in OUR driver. + */ ch->event |= 1 << event; schedule_work(&ch->tqueue); -} /* End pc_sched_event */ - -/* ------------------ Begin epca_error ------------------------- */ +} static void epca_error(int line, char *msg) { printk(KERN_ERR "epca_error (Digi): line = %d %s\n",line,msg); } -/* ------------------ Begin pc_close ------------------------- */ -static void pc_close(struct tty_struct * tty, struct file * filp) +static void pc_close(struct tty_struct *tty, struct file *filp) { struct channel *ch; unsigned long flags; - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ - if ((ch = verifyChannel(tty)) != NULL) { /* Begin if ch != NULL */ + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + if ((ch = verifyChannel(tty)) != NULL) { spin_lock_irqsave(&epca_lock, flags); if (tty_hung_up_p(filp)) { spin_unlock_irqrestore(&epca_lock, flags); return; } - /* Check to see if the channel is open more than once */ if (ch->count-- > 1) { /* Begin channel is open more than once */ - /* ------------------------------------------------------------- - Return without doing anything. Someone might still be using - the channel. - ---------------------------------------------------------------- */ + /* + * Return without doing anything. Someone might still + * be using the channel. + */ spin_unlock_irqrestore(&epca_lock, flags); return; - } /* End channel is open more than once */ + } /* Port open only once go ahead with shutdown & reset */ BUG_ON(ch->count < 0); - /* --------------------------------------------------------------- - Let the rest of the driver know the channel is being closed. - This becomes important if an open is attempted before close - is finished. - ------------------------------------------------------------------ */ + /* + * Let the rest of the driver know the channel is being closed. + * This becomes important if an open is attempted before close + * is finished. + */ ch->asyncflags |= ASYNC_CLOSING; tty->closing = 1; @@ -498,7 +456,7 @@ static void pc_close(struct tty_struct * tty, struct file * filp) if (ch->asyncflags & ASYNC_INITIALIZED) { /* Setup an event to indicate when the transmit buffer empties */ - setup_empty_event(tty, ch); + setup_empty_event(tty, ch); tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ } if (tty->driver->flush_buffer) @@ -513,27 +471,24 @@ static void pc_close(struct tty_struct * tty, struct file * filp) ch->tty = NULL; spin_unlock_irqrestore(&epca_lock, flags); - if (ch->blocked_open) { /* Begin if blocked_open */ - if (ch->close_delay) + if (ch->blocked_open) { + if (ch->close_delay) msleep_interruptible(jiffies_to_msecs(ch->close_delay)); wake_up_interruptible(&ch->open_wait); - } /* End if blocked_open */ - ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED | + } + ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED | ASYNC_CLOSING); wake_up_interruptible(&ch->close_wait); - } /* End if ch != NULL */ -} /* End pc_close */ - -/* ------------------ Begin shutdown ------------------------- */ + } +} static void shutdown(struct channel *ch) -{ /* Begin shutdown */ - +{ unsigned long flags; struct tty_struct *tty; struct board_chan __iomem *bc; - if (!(ch->asyncflags & ASYNC_INITIALIZED)) + if (!(ch->asyncflags & ASYNC_INITIALIZED)) return; spin_lock_irqsave(&epca_lock, flags); @@ -541,50 +496,40 @@ static void shutdown(struct channel *ch) globalwinon(ch); bc = ch->brdchan; - /* ------------------------------------------------------------------ - In order for an event to be generated on the receipt of data the - idata flag must be set. Since we are shutting down, this is not - necessary clear this flag. - --------------------------------------------------------------------- */ - + /* + * In order for an event to be generated on the receipt of data the + * idata flag must be set. Since we are shutting down, this is not + * necessary clear this flag. + */ if (bc) writeb(0, &bc->idata); tty = ch->tty; - /* ---------------------------------------------------------------- - If we're a modem control device and HUPCL is on, drop RTS & DTR. - ------------------------------------------------------------------ */ - + /* If we're a modem control device and HUPCL is on, drop RTS & DTR. */ if (tty->termios->c_cflag & HUPCL) { ch->omodem &= ~(ch->m_rts | ch->m_dtr); fepcmd(ch, SETMODEM, 0, ch->m_dtr | ch->m_rts, 10, 1); } memoff(ch); - /* ------------------------------------------------------------------ - The channel has officialy been closed. The next time it is opened - it will have to reinitialized. Set a flag to indicate this. - ---------------------------------------------------------------------- */ - + /* + * The channel has officialy been closed. The next time it is opened it + * will have to reinitialized. Set a flag to indicate this. + */ /* Prevent future Digi programmed interrupts from coming active */ - ch->asyncflags &= ~ASYNC_INITIALIZED; spin_unlock_irqrestore(&epca_lock, flags); - -} /* End shutdown */ - -/* ------------------ Begin pc_hangup ------------------------- */ +} static void pc_hangup(struct tty_struct *tty) -{ /* Begin pc_hangup */ +{ struct channel *ch; - - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ - if ((ch = verifyChannel(tty)) != NULL) { /* Begin if ch != NULL */ + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + if ((ch = verifyChannel(tty)) != NULL) { unsigned long flags; if (tty->driver->flush_buffer) @@ -599,15 +544,12 @@ static void pc_hangup(struct tty_struct *tty) ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED); spin_unlock_irqrestore(&epca_lock, flags); wake_up_interruptible(&ch->open_wait); - } /* End if ch != NULL */ - -} /* End pc_hangup */ - -/* ------------------ Begin pc_write ------------------------- */ + } +} -static int pc_write(struct tty_struct * tty, +static int pc_write(struct tty_struct *tty, const unsigned char *buf, int bytesAvailable) -{ /* Begin pc_write */ +{ unsigned int head, tail; int dataLen; int size; @@ -617,25 +559,23 @@ static int pc_write(struct tty_struct * tty, int remain; struct board_chan __iomem *bc; - /* ---------------------------------------------------------------- - pc_write is primarily called directly by the kernel routine - tty_write (Though it can also be called by put_char) found in - tty_io.c. pc_write is passed a line discipline buffer where - the data to be written out is stored. The line discipline - implementation itself is done at the kernel level and is not - brought into the driver. - ------------------------------------------------------------------- */ - - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ + /* + * pc_write is primarily called directly by the kernel routine + * tty_write (Though it can also be called by put_char) found in + * tty_io.c. pc_write is passed a line discipline buffer where the data + * to be written out is stored. The line discipline implementation + * itself is done at the kernel level and is not brought into the + * driver. + */ + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ if ((ch = verifyChannel(tty)) == NULL) return 0; /* Make a pointer to the channel data structure found on the board. */ - bc = ch->brdchan; size = ch->txbufsize; amountCopied = 0; @@ -650,37 +590,36 @@ static int pc_write(struct tty_struct * tty, tail = readw(&bc->tout); tail &= (size - 1); - /* If head >= tail, head has not wrapped around. */ - if (head >= tail) { /* Begin head has not wrapped */ - /* --------------------------------------------------------------- - remain (much like dataLen above) represents the total amount of - space available on the card for data. Here dataLen represents - the space existing between the head pointer and the end of - buffer. This is important because a memcpy cannot be told to - automatically wrap around when it hits the buffer end. - ------------------------------------------------------------------ */ + if (head >= tail) { + /* head has not wrapped */ + /* + * remain (much like dataLen above) represents the total amount + * of space available on the card for data. Here dataLen + * represents the space existing between the head pointer and + * the end of buffer. This is important because a memcpy cannot + * be told to automatically wrap around when it hits the buffer + * end. + */ dataLen = size - head; remain = size - (head - tail) - 1; - } else { /* Begin head has wrapped around */ - + } else { + /* head has wrapped around */ remain = tail - head - 1; dataLen = remain; - - } /* End head has wrapped around */ - /* ------------------------------------------------------------------- - Check the space on the card. If we have more data than - space; reduce the amount of data to fit the space. - ---------------------------------------------------------------------- */ + } + /* + * Check the space on the card. If we have more data than space; reduce + * the amount of data to fit the space. + */ bytesAvailable = min(remain, bytesAvailable); txwinon(ch); - while (bytesAvailable > 0) - { /* Begin while there is data to copy onto card */ - - /* ----------------------------------------------------------------- - If head is not wrapped, the below will make sure the first - data copy fills to the end of card buffer. - ------------------------------------------------------------------- */ + while (bytesAvailable > 0) { + /* there is data to copy onto card */ + /* + * If head is not wrapped, the below will make sure the first + * data copy fills to the end of card buffer. + */ dataLen = min(bytesAvailable, dataLen); memcpy_toio(ch->txptr + head, buf, dataLen); buf += dataLen; @@ -692,7 +631,7 @@ static int pc_write(struct tty_struct * tty, head = 0; dataLen = tail; } - } /* End while there is data to copy onto card */ + } ch->statusflags |= TXBUSY; globalwinon(ch); writew(head, &bc->tin); @@ -703,22 +642,16 @@ static int pc_write(struct tty_struct * tty, } memoff(ch); spin_unlock_irqrestore(&epca_lock, flags); - return(amountCopied); - -} /* End pc_write */ - -/* ------------------ Begin pc_put_char ------------------------- */ + return amountCopied; +} static void pc_put_char(struct tty_struct *tty, unsigned char c) -{ /* Begin pc_put_char */ +{ pc_write(tty, &c, 1); -} /* End pc_put_char */ - -/* ------------------ Begin pc_write_room ------------------------- */ +} static int pc_write_room(struct tty_struct *tty) -{ /* Begin pc_write_room */ - +{ int remain; struct channel *ch; unsigned long flags; @@ -727,11 +660,10 @@ static int pc_write_room(struct tty_struct *tty) remain = 0; - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ - + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ if ((ch = verifyChannel(tty)) != NULL) { spin_lock_irqsave(&epca_lock, flags); globalwinon(ch); @@ -757,14 +689,10 @@ static int pc_write_room(struct tty_struct *tty) } /* Return how much room is left on card */ return remain; - -} /* End pc_write_room */ - -/* ------------------ Begin pc_chars_in_buffer ---------------------- */ +} static int pc_chars_in_buffer(struct tty_struct *tty) -{ /* Begin pc_chars_in_buffer */ - +{ int chars; unsigned int ctail, head, tail; int remain; @@ -772,13 +700,12 @@ static int pc_chars_in_buffer(struct tty_struct *tty) struct channel *ch; struct board_chan __iomem *bc; - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ - + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ if ((ch = verifyChannel(tty)) == NULL) - return(0); + return 0; spin_lock_irqsave(&epca_lock, flags); globalwinon(ch); @@ -793,45 +720,40 @@ static int pc_chars_in_buffer(struct tty_struct *tty) else { /* Begin if some space on the card has been used */ head = readw(&bc->tin) & (ch->txbufsize - 1); tail &= (ch->txbufsize - 1); - /* -------------------------------------------------------------- - The logic here is basically opposite of the above pc_write_room - here we are finding the amount of bytes in the buffer filled. - Not the amount of bytes empty. - ------------------------------------------------------------------- */ + /* + * The logic here is basically opposite of the above + * pc_write_room here we are finding the amount of bytes in the + * buffer filled. Not the amount of bytes empty. + */ if ((remain = tail - head - 1) < 0 ) remain += ch->txbufsize; chars = (int)(ch->txbufsize - remain); - /* ------------------------------------------------------------- - Make it possible to wakeup anything waiting for output - in tty_ioctl.c, etc. - - If not already set. Setup an event to indicate when the - transmit buffer empties - ----------------------------------------------------------------- */ + /* + * Make it possible to wakeup anything waiting for output in + * tty_ioctl.c, etc. + * + * If not already set. Setup an event to indicate when the + * transmit buffer empties. + */ if (!(ch->statusflags & EMPTYWAIT)) setup_empty_event(tty,ch); - } /* End if some space on the card has been used */ memoff(ch); spin_unlock_irqrestore(&epca_lock, flags); /* Return number of characters residing on card. */ - return(chars); - -} /* End pc_chars_in_buffer */ - -/* ------------------ Begin pc_flush_buffer ---------------------- */ + return chars; +} static void pc_flush_buffer(struct tty_struct *tty) -{ /* Begin pc_flush_buffer */ - +{ unsigned int tail; unsigned long flags; struct channel *ch; struct board_chan __iomem *bc; - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ if ((ch = verifyChannel(tty)) == NULL) return; @@ -844,51 +766,47 @@ static void pc_flush_buffer(struct tty_struct *tty) memoff(ch); spin_unlock_irqrestore(&epca_lock, flags); tty_wakeup(tty); -} /* End pc_flush_buffer */ - -/* ------------------ Begin pc_flush_chars ---------------------- */ +} static void pc_flush_chars(struct tty_struct *tty) -{ /* Begin pc_flush_chars */ - struct channel * ch; - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ +{ + struct channel *ch; + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ if ((ch = verifyChannel(tty)) != NULL) { unsigned long flags; spin_lock_irqsave(&epca_lock, flags); - /* ---------------------------------------------------------------- - If not already set and the transmitter is busy setup an event - to indicate when the transmit empties. - ------------------------------------------------------------------- */ + /* + * If not already set and the transmitter is busy setup an + * event to indicate when the transmit empties. + */ if ((ch->statusflags & TXBUSY) && !(ch->statusflags & EMPTYWAIT)) setup_empty_event(tty,ch); spin_unlock_irqrestore(&epca_lock, flags); } -} /* End pc_flush_chars */ - -/* ------------------ Begin block_til_ready ---------------------- */ +} -static int block_til_ready(struct tty_struct *tty, +static int block_til_ready(struct tty_struct *tty, struct file *filp, struct channel *ch) -{ /* Begin block_til_ready */ +{ DECLARE_WAITQUEUE(wait,current); - int retval, do_clocal = 0; + int retval, do_clocal = 0; unsigned long flags; if (tty_hung_up_p(filp)) { if (ch->asyncflags & ASYNC_HUP_NOTIFY) retval = -EAGAIN; else - retval = -ERESTARTSYS; - return(retval); + retval = -ERESTARTSYS; + return retval; } - /* ----------------------------------------------------------------- - If the device is in the middle of being closed, then block - until it's done, and then try again. - -------------------------------------------------------------------- */ + /* + * If the device is in the middle of being closed, then block until + * it's done, and then try again. + */ if (ch->asyncflags & ASYNC_CLOSING) { interruptible_sleep_on(&ch->close_wait); @@ -899,17 +817,17 @@ static int block_til_ready(struct tty_struct *tty, } if (filp->f_flags & O_NONBLOCK) { - /* ----------------------------------------------------------------- - If non-blocking mode is set, then make the check up front - and then exit. - -------------------------------------------------------------------- */ + /* + * If non-blocking mode is set, then make the check up front + * and then exit. + */ ch->asyncflags |= ASYNC_NORMAL_ACTIVE; return 0; } if (tty->termios->c_cflag & CLOCAL) do_clocal = 1; /* Block waiting for the carrier detect and the line to become free */ - + retval = 0; add_wait_queue(&ch->open_wait, &wait); @@ -918,19 +836,18 @@ static int block_til_ready(struct tty_struct *tty, if (!tty_hung_up_p(filp)) ch->count--; ch->blocked_open++; - while(1) - { /* Begin forever while */ + while (1) { set_current_state(TASK_INTERRUPTIBLE); if (tty_hung_up_p(filp) || - !(ch->asyncflags & ASYNC_INITIALIZED)) + !(ch->asyncflags & ASYNC_INITIALIZED)) { if (ch->asyncflags & ASYNC_HUP_NOTIFY) retval = -EAGAIN; else - retval = -ERESTARTSYS; + retval = -ERESTARTSYS; break; } - if (!(ch->asyncflags & ASYNC_CLOSING) && + if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal || (ch->imodem & ch->dcd))) break; if (signal_pending(current)) { @@ -938,16 +855,15 @@ static int block_til_ready(struct tty_struct *tty, break; } spin_unlock_irqrestore(&epca_lock, flags); - /* --------------------------------------------------------------- - Allow someone else to be scheduled. We will occasionally go - through this loop until one of the above conditions change. - The below schedule call will allow other processes to enter and - prevent this loop from hogging the cpu. - ------------------------------------------------------------------ */ + /* + * Allow someone else to be scheduled. We will occasionally go + * through this loop until one of the above conditions change. + * The below schedule call will allow other processes to enter + * and prevent this loop from hogging the cpu. + */ schedule(); spin_lock_irqsave(&epca_lock, flags); - - } /* End forever while */ + } __set_current_state(TASK_RUNNING); remove_wait_queue(&ch->open_wait, &wait); @@ -962,13 +878,10 @@ static int block_til_ready(struct tty_struct *tty, ch->asyncflags |= ASYNC_NORMAL_ACTIVE; return 0; -} /* End block_til_ready */ - -/* ------------------ Begin pc_open ---------------------- */ +} static int pc_open(struct tty_struct *tty, struct file * filp) -{ /* Begin pc_open */ - +{ struct channel *ch; unsigned long flags; int line, retval, boardnum; @@ -984,12 +897,11 @@ static int pc_open(struct tty_struct *tty, struct file * filp) /* Check status of board configured in system. */ - /* ----------------------------------------------------------------- - I check to see if the epca_setup routine detected an user error. - It might be better to put this in pc_init, but for the moment it - goes here. - ---------------------------------------------------------------------- */ - + /* + * I check to see if the epca_setup routine detected an user error. It + * might be better to put this in pc_init, but for the moment it goes + * here. + */ if (invalid_lilo_config) { if (setup_error_code & INVALID_BOARD_TYPE) printk(KERN_ERR "epca: pc_open: Invalid board type specified in kernel options.\n"); @@ -1010,49 +922,48 @@ static int pc_open(struct tty_struct *tty, struct file * filp) tty->driver_data = NULL; /* Mark this device as 'down' */ return(-ENODEV); } - + if ((bc = ch->brdchan) == 0) { tty->driver_data = NULL; return -ENODEV; } spin_lock_irqsave(&epca_lock, flags); - /* ------------------------------------------------------------------ - Every time a channel is opened, increment a counter. This is - necessary because we do not wish to flush and shutdown the channel - until the last app holding the channel open, closes it. - --------------------------------------------------------------------- */ + /* + * Every time a channel is opened, increment a counter. This is + * necessary because we do not wish to flush and shutdown the channel + * until the last app holding the channel open, closes it. + */ ch->count++; - /* ---------------------------------------------------------------- - Set a kernel structures pointer to our local channel - structure. This way we can get to it when passed only - a tty struct. - ------------------------------------------------------------------ */ + /* + * Set a kernel structures pointer to our local channel structure. This + * way we can get to it when passed only a tty struct. + */ tty->driver_data = ch; - /* ---------------------------------------------------------------- - If this is the first time the channel has been opened, initialize - the tty->termios struct otherwise let pc_close handle it. - -------------------------------------------------------------------- */ + /* + * If this is the first time the channel has been opened, initialize + * the tty->termios struct otherwise let pc_close handle it. + */ globalwinon(ch); ch->statusflags = 0; /* Save boards current modem status */ ch->imodem = readb(&bc->mstat); - /* ---------------------------------------------------------------- - Set receive head and tail ptrs to each other. This indicates - no data available to read. - ----------------------------------------------------------------- */ + /* + * Set receive head and tail ptrs to each other. This indicates no data + * available to read. + */ head = readw(&bc->rin); writew(head, &bc->rout); /* Set the channels associated tty structure */ ch->tty = tty; - /* ----------------------------------------------------------------- - The below routine generally sets up parity, baud, flow control - issues, etc.... It effect both control flags and input flags. - -------------------------------------------------------------------- */ + /* + * The below routine generally sets up parity, baud, flow control + * issues, etc.... It effect both control flags and input flags. + */ epcaparam(tty,ch); ch->asyncflags |= ASYNC_INITIALIZED; memoff(ch); @@ -1061,10 +972,10 @@ static int pc_open(struct tty_struct *tty, struct file * filp) retval = block_til_ready(tty, filp, ch); if (retval) return retval; - /* ------------------------------------------------------------- - Set this again in case a hangup set it to zero while this - open() was waiting for the line... - --------------------------------------------------------------- */ + /* + * Set this again in case a hangup set it to zero while this open() was + * waiting for the line... + */ spin_lock_irqsave(&epca_lock, flags); ch->tty = tty; globalwinon(ch); @@ -1073,13 +984,12 @@ static int pc_open(struct tty_struct *tty, struct file * filp) memoff(ch); spin_unlock_irqrestore(&epca_lock, flags); return 0; -} /* End pc_open */ +} static int __init epca_module_init(void) -{ /* Begin init_module */ +{ return pc_init(); } - module_init(epca_module_init); static struct pci_driver epca_driver; @@ -1092,8 +1002,7 @@ static void __exit epca_module_exit(void) del_timer_sync(&epca_timer); - if ((tty_unregister_driver(pc_driver)) || - (tty_unregister_driver(pc_info))) + if (tty_unregister_driver(pc_driver) || tty_unregister_driver(pc_info)) { printk(KERN_WARNING "epca: cleanup_module failed to un-register tty driver\n"); return; @@ -1101,23 +1010,20 @@ static void __exit epca_module_exit(void) put_tty_driver(pc_driver); put_tty_driver(pc_info); - for (crd = 0; crd < num_cards; crd++) { /* Begin for each card */ + for (crd = 0; crd < num_cards; crd++) { bd = &boards[crd]; - if (!bd) - { /* Begin sanity check */ + if (!bd) { /* sanity check */ printk(KERN_ERR "<Error> - Digi : cleanup_module failed\n"); return; - } /* End sanity check */ + } ch = card_ptr[crd]; - for (count = 0; count < bd->numports; count++, ch++) - { /* Begin for each port */ + for (count = 0; count < bd->numports; count++, ch++) { if (ch && ch->tty) tty_hangup(ch->tty); - } /* End for each port */ - } /* End for each card */ - pci_unregister_driver (&epca_driver); + } + } + pci_unregister_driver(&epca_driver); } - module_exit(epca_module_exit); static const struct tty_operations pc_ops = { @@ -1148,10 +1054,8 @@ static struct tty_operations info_ops = { .ioctl = info_ioctl, }; -/* ------------------ Begin pc_init ---------------------- */ - static int __init pc_init(void) -{ /* Begin pc_init */ +{ int crd; struct board_info *bd; unsigned char board_id = 0; @@ -1169,63 +1073,57 @@ static int __init pc_init(void) if (!pc_info) goto out2; - /* ----------------------------------------------------------------------- - If epca_setup has not been ran by LILO set num_cards to defaults; copy - board structure defined by digiConfig into drivers board structure. - Note : If LILO has ran epca_setup then epca_setup will handle defining - num_cards as well as copying the data into the board structure. - -------------------------------------------------------------------------- */ - if (!liloconfig) { /* Begin driver has been configured via. epcaconfig */ - + /* + * If epca_setup has not been ran by LILO set num_cards to defaults; + * copy board structure defined by digiConfig into drivers board + * structure. Note : If LILO has ran epca_setup then epca_setup will + * handle defining num_cards as well as copying the data into the board + * structure. + */ + if (!liloconfig) { + /* driver has been configured via. epcaconfig */ nbdevs = NBDEVS; num_cards = NUMCARDS; - memcpy((void *)&boards, (void *)&static_boards, - (sizeof(struct board_info) * NUMCARDS)); - } /* End driver has been configured via. epcaconfig */ - - /* ----------------------------------------------------------------- - Note : If lilo was used to configure the driver and the - ignore epcaconfig option was choosen (digiepca=2) then - nbdevs and num_cards will equal 0 at this point. This is - okay; PCI cards will still be picked up if detected. - --------------------------------------------------------------------- */ - - /* ----------------------------------------------------------- - Set up interrupt, we will worry about memory allocation in - post_fep_init. - --------------------------------------------------------------- */ + memcpy(&boards, &static_boards, + sizeof(struct board_info) * NUMCARDS); + } + /* + * Note : If lilo was used to configure the driver and the ignore + * epcaconfig option was choosen (digiepca=2) then nbdevs and num_cards + * will equal 0 at this point. This is okay; PCI cards will still be + * picked up if detected. + */ + /* + * Set up interrupt, we will worry about memory allocation in + * post_fep_init. + */ printk(KERN_INFO "DIGI epca driver version %s loaded.\n",VERSION); - /* ------------------------------------------------------------------ - NOTE : This code assumes that the number of ports found in - the boards array is correct. This could be wrong if - the card in question is PCI (And therefore has no ports - entry in the boards structure.) The rest of the - information will be valid for PCI because the beginning - of pc_init scans for PCI and determines i/o and base - memory addresses. I am not sure if it is possible to - read the number of ports supported by the card prior to - it being booted (Since that is the state it is in when - pc_init is run). Because it is not possible to query the - number of supported ports until after the card has booted; - we are required to calculate the card_ptrs as the card is - is initialized (Inside post_fep_init). The negative thing - about this approach is that digiDload's call to GET_INFO - will have a bad port value. (Since this is called prior - to post_fep_init.) - - --------------------------------------------------------------------- */ - + /* + * NOTE : This code assumes that the number of ports found in the + * boards array is correct. This could be wrong if the card in question + * is PCI (And therefore has no ports entry in the boards structure.) + * The rest of the information will be valid for PCI because the + * beginning of pc_init scans for PCI and determines i/o and base + * memory addresses. I am not sure if it is possible to read the number + * of ports supported by the card prior to it being booted (Since that + * is the state it is in when pc_init is run). Because it is not + * possible to query the number of supported ports until after the card + * has booted; we are required to calculate the card_ptrs as the card + * is initialized (Inside post_fep_init). The negative thing about this + * approach is that digiDload's call to GET_INFO will have a bad port + * value. (Since this is called prior to post_fep_init.) + */ pci_boards_found = 0; - if(num_cards < MAXBOARDS) + if (num_cards < MAXBOARDS) pci_boards_found += init_PCI(); num_cards += pci_boards_found; pc_driver->owner = THIS_MODULE; - pc_driver->name = "ttyD"; - pc_driver->major = DIGI_MAJOR; + pc_driver->name = "ttyD"; + pc_driver->major = DIGI_MAJOR; pc_driver->minor_start = 0; pc_driver->type = TTY_DRIVER_TYPE_SERIAL; pc_driver->subtype = SERIAL_TYPE_NORMAL; @@ -1256,120 +1154,108 @@ static int __init pc_init(void) tty_set_operations(pc_info, &info_ops); - for (crd = 0; crd < num_cards; crd++) - { /* Begin for each card */ - - /* ------------------------------------------------------------------ - This is where the appropriate memory handlers for the hardware is - set. Everything at runtime blindly jumps through these vectors. - ---------------------------------------------------------------------- */ + for (crd = 0; crd < num_cards; crd++) { + /* + * This is where the appropriate memory handlers for the + * hardware is set. Everything at runtime blindly jumps through + * these vectors. + */ /* defined in epcaconfig.h */ bd = &boards[crd]; - switch (bd->type) - { /* Begin switch on bd->type {board type} */ - case PCXEM: - case EISAXEM: - bd->memwinon = pcxem_memwinon ; - bd->memwinoff = pcxem_memwinoff ; - bd->globalwinon = pcxem_globalwinon ; - bd->txwinon = pcxem_txwinon ; - bd->rxwinon = pcxem_rxwinon ; - bd->memoff = pcxem_memoff ; - bd->assertgwinon = dummy_assertgwinon; - bd->assertmemoff = dummy_assertmemoff; - break; - - case PCIXEM: - case PCIXRJ: - case PCIXR: - bd->memwinon = dummy_memwinon; - bd->memwinoff = dummy_memwinoff; - bd->globalwinon = dummy_globalwinon; - bd->txwinon = dummy_txwinon; - bd->rxwinon = dummy_rxwinon; - bd->memoff = dummy_memoff; - bd->assertgwinon = dummy_assertgwinon; - bd->assertmemoff = dummy_assertmemoff; - break; - - case PCXE: - case PCXEVE: - - bd->memwinon = pcxe_memwinon; - bd->memwinoff = pcxe_memwinoff; - bd->globalwinon = pcxe_globalwinon; - bd->txwinon = pcxe_txwinon; - bd->rxwinon = pcxe_rxwinon; - bd->memoff = pcxe_memoff; - bd->assertgwinon = dummy_assertgwinon; - bd->assertmemoff = dummy_assertmemoff; - break; - - case PCXI: - case PC64XE: - - bd->memwinon = pcxi_memwinon; - bd->memwinoff = pcxi_memwinoff; - bd->globalwinon = pcxi_globalwinon; - bd->txwinon = pcxi_txwinon; - bd->rxwinon = pcxi_rxwinon; - bd->memoff = pcxi_memoff; - bd->assertgwinon = pcxi_assertgwinon; - bd->assertmemoff = pcxi_assertmemoff; - break; - - default: - break; - - } /* End switch on bd->type */ - - /* --------------------------------------------------------------- - Some cards need a memory segment to be defined for use in - transmit and receive windowing operations. These boards - are listed in the below switch. In the case of the XI the - amount of memory on the board is variable so the memory_seg - is also variable. This code determines what they segment - should be. - ----------------------------------------------------------------- */ - - switch (bd->type) - { /* Begin switch on bd->type {board type} */ - - case PCXE: - case PCXEVE: - case PC64XE: - bd->memory_seg = 0xf000; + switch (bd->type) { + case PCXEM: + case EISAXEM: + bd->memwinon = pcxem_memwinon; + bd->memwinoff = pcxem_memwinoff; + bd->globalwinon = pcxem_globalwinon; + bd->txwinon = pcxem_txwinon; + bd->rxwinon = pcxem_rxwinon; + bd->memoff = pcxem_memoff; + bd->assertgwinon = dummy_assertgwinon; + bd->assertmemoff = dummy_assertmemoff; break; - case PCXI: - board_id = inb((int)bd->port); - if ((board_id & 0x1) == 0x1) - { /* Begin it's an XI card */ - - /* Is it a 64K board */ - if ((board_id & 0x30) == 0) - bd->memory_seg = 0xf000; - - /* Is it a 128K board */ - if ((board_id & 0x30) == 0x10) - bd->memory_seg = 0xe000; + case PCIXEM: + case PCIXRJ: + case PCIXR: + bd->memwinon = dummy_memwinon; + bd->memwinoff = dummy_memwinoff; + bd->globalwinon = dummy_globalwinon; + bd->txwinon = dummy_txwinon; + bd->rxwinon = dummy_rxwinon; + bd->memoff = dummy_memoff; + bd->assertgwinon = dummy_assertgwinon; + bd->assertmemoff = dummy_assertmemoff; + break; - /* Is is a 256K board */ - if ((board_id & 0x30) == 0x20) - bd->memory_seg = 0xc000; + case PCXE: + case PCXEVE: + bd->memwinon = pcxe_memwinon; + bd->memwinoff = pcxe_memwinoff; + bd->globalwinon = pcxe_globalwinon; + bd->txwinon = pcxe_txwinon; + bd->rxwinon = pcxe_rxwinon; + bd->memoff = pcxe_memoff; + bd->assertgwinon = dummy_assertgwinon; + bd->assertmemoff = dummy_assertmemoff; + break; - /* Is it a 512K board */ - if ((board_id & 0x30) == 0x30) - bd->memory_seg = 0x8000; + case PCXI: + case PC64XE: + bd->memwinon = pcxi_memwinon; + bd->memwinoff = pcxi_memwinoff; + bd->globalwinon = pcxi_globalwinon; + bd->txwinon = pcxi_txwinon; + bd->rxwinon = pcxi_rxwinon; + bd->memoff = pcxi_memoff; + bd->assertgwinon = pcxi_assertgwinon; + bd->assertmemoff = pcxi_assertmemoff; + break; - } else printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n",(int)bd->port); + default: break; + } - } /* End switch on bd->type */ + /* + * Some cards need a memory segment to be defined for use in + * transmit and receive windowing operations. These boards are + * listed in the below switch. In the case of the XI the amount + * of memory on the board is variable so the memory_seg is also + * variable. This code determines what they segment should be. + */ + switch (bd->type) { + case PCXE: + case PCXEVE: + case PC64XE: + bd->memory_seg = 0xf000; + break; - } /* End for each card */ + case PCXI: + board_id = inb((int)bd->port); + if ((board_id & 0x1) == 0x1) { + /* it's an XI card */ + /* Is it a 64K board */ + if ((board_id & 0x30) == 0) + bd->memory_seg = 0xf000; + + /* Is it a 128K board */ + if ((board_id & 0x30) == 0x10) + bd->memory_seg = 0xe000; + + /* Is is a 256K board */ + if ((board_id & 0x30) == 0x20) + bd->memory_seg = 0xc000; + + /* Is it a 512K board */ + if ((board_id & 0x30) == 0x30) + bd->memory_seg = 0x8000; + } else + printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n",(int)bd->port); + break; + } + } err = tty_register_driver(pc_driver); if (err) { @@ -1383,10 +1269,7 @@ static int __init pc_init(void) goto out4; } - /* ------------------------------------------------------------------- - Start up the poller to check for events on all enabled boards - ---------------------------------------------------------------------- */ - + /* Start up the poller to check for events on all enabled boards */ init_timer(&epca_timer); epca_timer.function = epcapoll; mod_timer(&epca_timer, jiffies + HZ/25); @@ -1400,51 +1283,47 @@ out2: put_tty_driver(pc_driver); out1: return err; - -} /* End pc_init */ - -/* ------------------ Begin post_fep_init ---------------------- */ +} static void post_fep_init(unsigned int crd) -{ /* Begin post_fep_init */ - +{ int i; void __iomem *memaddr; struct global_data __iomem *gd; struct board_info *bd; struct board_chan __iomem *bc; - struct channel *ch; - int shrinkmem = 0, lowwater ; - - /* ------------------------------------------------------------- - This call is made by the user via. the ioctl call DIGI_INIT. - It is responsible for setting up all the card specific stuff. - ---------------------------------------------------------------- */ - bd = &boards[crd]; + struct channel *ch; + int shrinkmem = 0, lowwater; - /* ----------------------------------------------------------------- - If this is a PCI board, get the port info. Remember PCI cards - do not have entries into the epcaconfig.h file, so we can't get - the number of ports from it. Unfortunetly, this means that anyone - doing a DIGI_GETINFO before the board has booted will get an invalid - number of ports returned (It should return 0). Calls to DIGI_GETINFO - after DIGI_INIT has been called will return the proper values. - ------------------------------------------------------------------- */ + /* + * This call is made by the user via. the ioctl call DIGI_INIT. It is + * responsible for setting up all the card specific stuff. + */ + bd = &boards[crd]; + /* + * If this is a PCI board, get the port info. Remember PCI cards do not + * have entries into the epcaconfig.h file, so we can't get the number + * of ports from it. Unfortunetly, this means that anyone doing a + * DIGI_GETINFO before the board has booted will get an invalid number + * of ports returned (It should return 0). Calls to DIGI_GETINFO after + * DIGI_INIT has been called will return the proper values. + */ if (bd->type >= PCIXEM) { /* Begin get PCI number of ports */ - /* -------------------------------------------------------------------- - Below we use XEMPORTS as a memory offset regardless of which PCI - card it is. This is because all of the supported PCI cards have - the same memory offset for the channel data. This will have to be - changed if we ever develop a PCI/XE card. NOTE : The FEP manual - states that the port offset is 0xC22 as opposed to 0xC02. This is - only true for PC/XE, and PC/XI cards; not for the XEM, or CX series. - On the PCI cards the number of ports is determined by reading a - ID PROM located in the box attached to the card. The card can then - determine the index the id to determine the number of ports available. - (FYI - The id should be located at 0x1ac (And may use up to 4 bytes - if the box in question is a XEM or CX)). - ------------------------------------------------------------------------ */ + /* + * Below we use XEMPORTS as a memory offset regardless of which + * PCI card it is. This is because all of the supported PCI + * cards have the same memory offset for the channel data. This + * will have to be changed if we ever develop a PCI/XE card. + * NOTE : The FEP manual states that the port offset is 0xC22 + * as opposed to 0xC02. This is only true for PC/XE, and PC/XI + * cards; not for the XEM, or CX series. On the PCI cards the + * number of ports is determined by reading a ID PROM located + * in the box attached to the card. The card can then determine + * the index the id to determine the number of ports available. + * (FYI - The id should be located at 0x1ac (And may use up to + * 4 bytes if the box in question is a XEM or CX)). + */ /* PCI cards are already remapped at this point ISA are not */ bd->numports = readw(bd->re_map_membase + XEMPORTS); epcaassert(bd->numports <= 64,"PCI returned a invalid number of ports"); @@ -1465,95 +1344,87 @@ static void post_fep_init(unsigned int crd) memaddr = bd->re_map_membase; - /* ----------------------------------------------------------------- - The below assignment will set bc to point at the BEGINING of - the cards channel structures. For 1 card there will be between - 8 and 64 of these structures. - -------------------------------------------------------------------- */ - + /* + * The below assignment will set bc to point at the BEGINING of the + * cards channel structures. For 1 card there will be between 8 and 64 + * of these structures. + */ bc = memaddr + CHANSTRUCT; - /* ------------------------------------------------------------------- - The below assignment will set gd to point at the BEGINING of - global memory address 0xc00. The first data in that global - memory actually starts at address 0xc1a. The command in - pointer begins at 0xd10. - ---------------------------------------------------------------------- */ - + /* + * The below assignment will set gd to point at the BEGINING of global + * memory address 0xc00. The first data in that global memory actually + * starts at address 0xc1a. The command in pointer begins at 0xd10. + */ gd = memaddr + GLOBAL; - /* -------------------------------------------------------------------- - XEPORTS (address 0xc22) points at the number of channels the - card supports. (For 64XE, XI, XEM, and XR use 0xc02) - ----------------------------------------------------------------------- */ - + /* + * XEPORTS (address 0xc22) points at the number of channels the card + * supports. (For 64XE, XI, XEM, and XR use 0xc02) + */ if ((bd->type == PCXEVE || bd->type == PCXE) && (readw(memaddr + XEPORTS) < 3)) shrinkmem = 1; if (bd->type < PCIXEM) if (!request_region((int)bd->port, 4, board_desc[bd->type])) - return; + return; memwinon(bd, 0); - /* -------------------------------------------------------------------- - Remember ch is the main drivers channels structure, while bc is - the cards channel structure. - ------------------------------------------------------------------------ */ - - /* For every port on the card do ..... */ - - for (i = 0; i < bd->numports; i++, ch++, bc++) { /* Begin for each port */ + /* + * Remember ch is the main drivers channels structure, while bc is the + * cards channel structure. + */ + for (i = 0; i < bd->numports; i++, ch++, bc++) { unsigned long flags; u16 tseg, rseg; - ch->brdchan = bc; - ch->mailbox = gd; + ch->brdchan = bc; + ch->mailbox = gd; INIT_WORK(&ch->tqueue, do_softint); - ch->board = &boards[crd]; + ch->board = &boards[crd]; spin_lock_irqsave(&epca_lock, flags); switch (bd->type) { - /* ---------------------------------------------------------------- - Since some of the boards use different bitmaps for their - control signals we cannot hard code these values and retain - portability. We virtualize this data here. - ------------------------------------------------------------------- */ - case EISAXEM: - case PCXEM: - case PCIXEM: - case PCIXRJ: - case PCIXR: - ch->m_rts = 0x02 ; - ch->m_dcd = 0x80 ; - ch->m_dsr = 0x20 ; - ch->m_cts = 0x10 ; - ch->m_ri = 0x40 ; - ch->m_dtr = 0x01 ; - break; - - case PCXE: - case PCXEVE: - case PCXI: - case PC64XE: - ch->m_rts = 0x02 ; - ch->m_dcd = 0x08 ; - ch->m_dsr = 0x10 ; - ch->m_cts = 0x20 ; - ch->m_ri = 0x40 ; - ch->m_dtr = 0x80 ; - break; - - } /* End switch bd->type */ + /* + * Since some of the boards use different bitmaps for + * their control signals we cannot hard code these + * values and retain portability. We virtualize this + * data here. + */ + case EISAXEM: + case PCXEM: + case PCIXEM: + case PCIXRJ: + case PCIXR: + ch->m_rts = 0x02; + ch->m_dcd = 0x80; + ch->m_dsr = 0x20; + ch->m_cts = 0x10; + ch->m_ri = 0x40; + ch->m_dtr = 0x01; + break; + + case PCXE: + case PCXEVE: + case PCXI: + case PC64XE: + ch->m_rts = 0x02; + ch->m_dcd = 0x08; + ch->m_dsr = 0x10; + ch->m_cts = 0x20; + ch->m_ri = 0x40; + ch->m_dtr = 0x80; + break; + } if (boards[crd].altpin) { ch->dsr = ch->m_dcd; ch->dcd = ch->m_dsr; ch->digiext.digi_flags |= DIGI_ALTPIN; - } - else { + } else { ch->dcd = ch->m_dcd; ch->dsr = ch->m_dsr; } - + ch->boardnum = crd; ch->channelnum = i; ch->magic = EPCA_MAGIC; @@ -1568,71 +1439,67 @@ static void post_fep_init(unsigned int crd) rseg = readw(&bc->rseg); switch (bd->type) { + case PCIXEM: + case PCIXRJ: + case PCIXR: + /* Cover all the 2MEG cards */ + ch->txptr = memaddr + ((tseg << 4) & 0x1fffff); + ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff); + ch->txwin = FEPWIN | (tseg >> 11); + ch->rxwin = FEPWIN | (rseg >> 11); + break; - case PCIXEM: - case PCIXRJ: - case PCIXR: - /* Cover all the 2MEG cards */ - ch->txptr = memaddr + ((tseg << 4) & 0x1fffff); - ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff); - ch->txwin = FEPWIN | (tseg >> 11); - ch->rxwin = FEPWIN | (rseg >> 11); - break; - - case PCXEM: - case EISAXEM: - /* Cover all the 32K windowed cards */ - /* Mask equal to window size - 1 */ - ch->txptr = memaddr + ((tseg << 4) & 0x7fff); - ch->rxptr = memaddr + ((rseg << 4) & 0x7fff); - ch->txwin = FEPWIN | (tseg >> 11); - ch->rxwin = FEPWIN | (rseg >> 11); - break; - - case PCXEVE: - case PCXE: - ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) & 0x1fff); - ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9); - ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) & 0x1fff); - ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >>9 ); - break; - - case PCXI: - case PC64XE: - ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4); - ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4); - ch->txwin = ch->rxwin = 0; - break; - - } /* End switch bd->type */ + case PCXEM: + case EISAXEM: + /* Cover all the 32K windowed cards */ + /* Mask equal to window size - 1 */ + ch->txptr = memaddr + ((tseg << 4) & 0x7fff); + ch->rxptr = memaddr + ((rseg << 4) & 0x7fff); + ch->txwin = FEPWIN | (tseg >> 11); + ch->rxwin = FEPWIN | (rseg >> 11); + break; + + case PCXEVE: + case PCXE: + ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) & 0x1fff); + ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9); + ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) & 0x1fff); + ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >>9 ); + break; + + case PCXI: + case PC64XE: + ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4); + ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4); + ch->txwin = ch->rxwin = 0; + break; + } ch->txbufhead = 0; ch->txbufsize = readw(&bc->tmax) + 1; - + ch->rxbufhead = 0; ch->rxbufsize = readw(&bc->rmax) + 1; - + lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2); /* Set transmitter low water mark */ fepcmd(ch, STXLWATER, lowwater, 0, 10, 0); /* Set receiver low water mark */ - fepcmd(ch, SRXLWATER, (ch->rxbufsize / 4), 0, 10, 0); /* Set receiver high water mark */ - fepcmd(ch, SRXHWATER, (3 * ch->rxbufsize / 4), 0, 10, 0); writew(100, &bc->edelay); writeb(1, &bc->idata); - + ch->startc = readb(&bc->startc); ch->stopc = readb(&bc->stopc); ch->startca = readb(&bc->startca); ch->stopca = readb(&bc->stopca); - + ch->fepcflag = 0; ch->fepiflag = 0; ch->fepoflag = 0; @@ -1640,7 +1507,7 @@ static void post_fep_init(unsigned int crd) ch->fepstopc = 0; ch->fepstartca = 0; ch->fepstopca = 0; - + ch->close_delay = 50; ch->count = 0; ch->blocked_open = 0; @@ -1648,80 +1515,66 @@ static void post_fep_init(unsigned int crd) init_waitqueue_head(&ch->close_wait); spin_unlock_irqrestore(&epca_lock, flags); - } /* End for each port */ + } - printk(KERN_INFO - "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n", + printk(KERN_INFO + "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n", VERSION, board_desc[bd->type], (long)bd->port, (long)bd->membase, bd->numports); memwinoff(bd, 0); - -} /* End post_fep_init */ - -/* --------------------- Begin epcapoll ------------------------ */ +} static void epcapoll(unsigned long ignored) -{ /* Begin epcapoll */ - +{ unsigned long flags; int crd; volatile unsigned int head, tail; struct channel *ch; struct board_info *bd; - /* ------------------------------------------------------------------- - This routine is called upon every timer interrupt. Even though - the Digi series cards are capable of generating interrupts this - method of non-looping polling is more efficient. This routine - checks for card generated events (Such as receive data, are transmit - buffer empty) and acts on those events. - ----------------------------------------------------------------------- */ - - for (crd = 0; crd < num_cards; crd++) - { /* Begin for each card */ - + /* + * This routine is called upon every timer interrupt. Even though the + * Digi series cards are capable of generating interrupts this method + * of non-looping polling is more efficient. This routine checks for + * card generated events (Such as receive data, are transmit buffer + * empty) and acts on those events. + */ + for (crd = 0; crd < num_cards; crd++) { bd = &boards[crd]; ch = card_ptr[crd]; if ((bd->status == DISABLED) || digi_poller_inhibited) - continue; /* Begin loop next interation */ - - /* ----------------------------------------------------------- - assertmemoff is not needed here; indeed it is an empty subroutine. - It is being kept because future boards may need this as well as - some legacy boards. - ---------------------------------------------------------------- */ + continue; + /* + * assertmemoff is not needed here; indeed it is an empty + * subroutine. It is being kept because future boards may need + * this as well as some legacy boards. + */ spin_lock_irqsave(&epca_lock, flags); assertmemoff(ch); globalwinon(ch); - /* --------------------------------------------------------------- - In this case head and tail actually refer to the event queue not - the transmit or receive queue. - ------------------------------------------------------------------- */ - + /* + * In this case head and tail actually refer to the event queue + * not the transmit or receive queue. + */ head = readw(&ch->mailbox->ein); tail = readw(&ch->mailbox->eout); - - /* If head isn't equal to tail we have an event */ + /* If head isn't equal to tail we have an event */ if (head != tail) doevent(crd); memoff(ch); spin_unlock_irqrestore(&epca_lock, flags); - } /* End for each card */ mod_timer(&epca_timer, jiffies + (HZ / 25)); -} /* End epcapoll */ - -/* --------------------- Begin doevent ------------------------ */ +} static void doevent(int crd) -{ /* Begin doevent */ - +{ void __iomem *eventbuf; struct channel *ch, *chan0; static struct tty_struct *tty; @@ -1731,28 +1584,28 @@ static void doevent(int crd) int event, channel; int mstat, lstat; - /* ------------------------------------------------------------------- - This subroutine is called by epcapoll when an event is detected - in the event queue. This routine responds to those events. - --------------------------------------------------------------------- */ + /* + * This subroutine is called by epcapoll when an event is detected + * in the event queue. This routine responds to those events. + */ bd = &boards[crd]; chan0 = card_ptr[crd]; epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range"); assertgwinon(chan0); - while ((tail = readw(&chan0->mailbox->eout)) != (head = readw(&chan0->mailbox->ein))) - { /* Begin while something in event queue */ + while ((tail = readw(&chan0->mailbox->eout)) != (head = readw(&chan0->mailbox->ein))) { /* Begin while something in event queue */ assertgwinon(chan0); eventbuf = bd->re_map_membase + tail + ISTART; /* Get the channel the event occurred on */ channel = readb(eventbuf); /* Get the actual event code that occurred */ event = readb(eventbuf + 1); - /* ---------------------------------------------------------------- - The two assignments below get the current modem status (mstat) - and the previous modem status (lstat). These are useful becuase - an event could signal a change in modem signals itself. - ------------------------------------------------------------------- */ + /* + * The two assignments below get the current modem status + * (mstat) and the previous modem status (lstat). These are + * useful becuase an event could signal a change in modem + * signals itself. + */ mstat = readb(eventbuf + 2); lstat = readb(eventbuf + 3); @@ -1772,37 +1625,36 @@ static void doevent(int crd) assertgwinon(ch); } /* End DATA_IND */ /* else *//* Fix for DCD transition missed bug */ - if (event & MODEMCHG_IND) { /* Begin MODEMCHG_IND */ + if (event & MODEMCHG_IND) { /* A modem signal change has been indicated */ ch->imodem = mstat; - if (ch->asyncflags & ASYNC_CHECK_CD) { + if (ch->asyncflags & ASYNC_CHECK_CD) { if (mstat & ch->dcd) /* We are now receiving dcd */ wake_up_interruptible(&ch->open_wait); else pc_sched_event(ch, EPCA_EVENT_HANGUP); /* No dcd; hangup */ } - } /* End MODEMCHG_IND */ + } tty = ch->tty; - if (tty) { /* Begin if valid tty */ - if (event & BREAK_IND) { /* Begin if BREAK_IND */ + if (tty) { + if (event & BREAK_IND) { /* A break has been indicated */ tty_insert_flip_char(tty, 0, TTY_BREAK); - tty_schedule_flip(tty); - } else if (event & LOWTX_IND) { /* Begin LOWTX_IND */ - if (ch->statusflags & LOWWAIT) - { /* Begin if LOWWAIT */ + tty_schedule_flip(tty); + } else if (event & LOWTX_IND) { + if (ch->statusflags & LOWWAIT) { ch->statusflags &= ~LOWWAIT; tty_wakeup(tty); - } /* End if LOWWAIT */ - } else if (event & EMPTYTX_IND) { /* Begin EMPTYTX_IND */ + } + } else if (event & EMPTYTX_IND) { /* This event is generated by setup_empty_event */ ch->statusflags &= ~TXBUSY; - if (ch->statusflags & EMPTYWAIT) { /* Begin if EMPTYWAIT */ + if (ch->statusflags & EMPTYWAIT) { ch->statusflags &= ~EMPTYWAIT; tty_wakeup(tty); - } /* End if EMPTYWAIT */ - } /* End EMPTYTX_IND */ - } /* End if valid tty */ + } + } + } next: globalwinon(ch); BUG_ON(!bc); @@ -1810,13 +1662,11 @@ static void doevent(int crd) writew((tail + 4) & (IMAX - ISTART - 4), &chan0->mailbox->eout); globalwinon(chan0); } /* End while something in event queue */ -} /* End doevent */ - -/* --------------------- Begin fepcmd ------------------------ */ +} static void fepcmd(struct channel *ch, int cmd, int word_or_byte, int byte2, int ncmds, int bytecmd) -{ /* Begin fepcmd */ +{ unchar __iomem *memaddr; unsigned int head, cmdTail, cmdStart, cmdMax; long count; @@ -1831,11 +1681,11 @@ static void fepcmd(struct channel *ch, int cmd, int word_or_byte, head = readw(&ch->mailbox->cin); /* cmdStart is a base address */ cmdStart = readw(&ch->mailbox->cstart); - /* ------------------------------------------------------------------ - We do the addition below because we do not want a max pointer - relative to cmdStart. We want a max pointer that points at the - physical end of the command queue. - -------------------------------------------------------------------- */ + /* + * We do the addition below because we do not want a max pointer + * relative to cmdStart. We want a max pointer that points at the + * physical end of the command queue. + */ cmdMax = (cmdStart + 4 + readw(&ch->mailbox->cmax)); memaddr = ch->board->re_map_membase; @@ -1860,7 +1710,7 @@ static void fepcmd(struct channel *ch, int cmd, int word_or_byte, writew(head, &ch->mailbox->cin); count = FEPTIMEOUT; - for (;;) { /* Begin forever loop */ + for (;;) { count--; if (count == 0) { printk(KERN_ERR "<Error> - Fep not responding in fepcmd()\n"); @@ -1869,26 +1719,23 @@ static void fepcmd(struct channel *ch, int cmd, int word_or_byte, head = readw(&ch->mailbox->cin); cmdTail = readw(&ch->mailbox->cout); n = (head - cmdTail) & (cmdMax - cmdStart - 4); - /* ---------------------------------------------------------- - Basically this will break when the FEP acknowledges the - command by incrementing cmdTail (Making it equal to head). - ------------------------------------------------------------- */ + /* + * Basically this will break when the FEP acknowledges the + * command by incrementing cmdTail (Making it equal to head). + */ if (n <= ncmds * (sizeof(short) * 4)) - break; /* Well nearly forever :-) */ - } /* End forever loop */ -} /* End fepcmd */ - -/* --------------------------------------------------------------------- - Digi products use fields in their channels structures that are very - similar to the c_cflag and c_iflag fields typically found in UNIX - termios structures. The below three routines allow mappings - between these hardware "flags" and their respective Linux flags. -------------------------------------------------------------------------- */ - -/* --------------------- Begin termios2digi_h -------------------- */ + break; + } +} +/* + * Digi products use fields in their channels structures that are very similar + * to the c_cflag and c_iflag fields typically found in UNIX termios + * structures. The below three routines allow mappings between these hardware + * "flags" and their respective Linux flags. + */ static unsigned termios2digi_h(struct channel *ch, unsigned cflag) -{ /* Begin termios2digi_h */ +{ unsigned res = 0; if (cflag & CRTSCTS) { @@ -1918,86 +1765,73 @@ static unsigned termios2digi_h(struct channel *ch, unsigned cflag) ch->digiext.digi_flags |= CTSPACE; return res; +} -} /* End termios2digi_h */ - -/* --------------------- Begin termios2digi_i -------------------- */ static unsigned termios2digi_i(struct channel *ch, unsigned iflag) -{ /* Begin termios2digi_i */ - - unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | +{ + unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP|IXON|IXANY|IXOFF); if (ch->digiext.digi_flags & DIGI_AIXON) res |= IAIXON; return res; - -} /* End termios2digi_i */ - -/* --------------------- Begin termios2digi_c -------------------- */ +} static unsigned termios2digi_c(struct channel *ch, unsigned cflag) -{ /* Begin termios2digi_c */ - +{ unsigned res = 0; - if (cflag & CBAUDEX) { /* Begin detected CBAUDEX */ + if (cflag & CBAUDEX) { ch->digiext.digi_flags |= DIGI_FAST; - /* ------------------------------------------------------------- - HUPCL bit is used by FEP to indicate fast baud - table is to be used. - ----------------------------------------------------------------- */ + /* + * HUPCL bit is used by FEP to indicate fast baud table is to + * be used. + */ res |= FEP_HUPCL; - } /* End detected CBAUDEX */ - else ch->digiext.digi_flags &= ~DIGI_FAST; - /* ------------------------------------------------------------------- - CBAUD has bit position 0x1000 set these days to indicate Linux - baud rate remap. Digi hardware can't handle the bit assignment. - (We use a different bit assignment for high speed.). Clear this - bit out. - ---------------------------------------------------------------------- */ + } else + ch->digiext.digi_flags &= ~DIGI_FAST; + /* + * CBAUD has bit position 0x1000 set these days to indicate Linux + * baud rate remap. Digi hardware can't handle the bit assignment. + * (We use a different bit assignment for high speed.). Clear this + * bit out. + */ res |= cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE); - /* ------------------------------------------------------------- - This gets a little confusing. The Digi cards have their own - representation of c_cflags controling baud rate. For the most - part this is identical to the Linux implementation. However; - Digi supports one rate (76800) that Linux doesn't. This means - that the c_cflag entry that would normally mean 76800 for Digi - actually means 115200 under Linux. Without the below mapping, - a stty 115200 would only drive the board at 76800. Since - the rate 230400 is also found after 76800, the same problem afflicts - us when we choose a rate of 230400. Without the below modificiation - stty 230400 would actually give us 115200. - - There are two additional differences. The Linux value for CLOCAL - (0x800; 0004000) has no meaning to the Digi hardware. Also in - later releases of Linux; the CBAUD define has CBAUDEX (0x1000; - 0010000) ored into it (CBAUD = 0x100f as opposed to 0xf). CBAUDEX - should be checked for a screened out prior to termios2digi_c - returning. Since CLOCAL isn't used by the board this can be - ignored as long as the returned value is used only by Digi hardware. - ----------------------------------------------------------------- */ + /* + * This gets a little confusing. The Digi cards have their own + * representation of c_cflags controling baud rate. For the most part + * this is identical to the Linux implementation. However; Digi + * supports one rate (76800) that Linux doesn't. This means that the + * c_cflag entry that would normally mean 76800 for Digi actually means + * 115200 under Linux. Without the below mapping, a stty 115200 would + * only drive the board at 76800. Since the rate 230400 is also found + * after 76800, the same problem afflicts us when we choose a rate of + * 230400. Without the below modificiation stty 230400 would actually + * give us 115200. + * + * There are two additional differences. The Linux value for CLOCAL + * (0x800; 0004000) has no meaning to the Digi hardware. Also in later + * releases of Linux; the CBAUD define has CBAUDEX (0x1000; 0010000) + * ored into it (CBAUD = 0x100f as opposed to 0xf). CBAUDEX should be + * checked for a screened out prior to termios2digi_c returning. Since + * CLOCAL isn't used by the board this can be ignored as long as the + * returned value is used only by Digi hardware. + */ if (cflag & CBAUDEX) { - /* ------------------------------------------------------------- - The below code is trying to guarantee that only baud rates - 115200 and 230400 are remapped. We use exclusive or because - the various baud rates share common bit positions and therefore - can't be tested for easily. - ----------------------------------------------------------------- */ - - - if ((!((cflag & 0x7) ^ (B115200 & ~CBAUDEX))) || + /* + * The below code is trying to guarantee that only baud rates + * 115200 and 230400 are remapped. We use exclusive or because + * the various baud rates share common bit positions and + * therefore can't be tested for easily. + */ + if ((!((cflag & 0x7) ^ (B115200 & ~CBAUDEX))) || (!((cflag & 0x7) ^ (B230400 & ~CBAUDEX)))) res += 1; } return res; - -} /* End termios2digi_c */ - -/* --------------------- Begin epcaparam ----------------------- */ +} /* Caller must hold the locks */ static void epcaparam(struct tty_struct *tty, struct channel *ch) -{ /* Begin epcaparam */ - +{ unsigned int cmdHead; struct ktermios *ts; struct board_chan __iomem *bc; @@ -2013,28 +1847,29 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch) writew(cmdHead, &bc->rout); cmdHead = readw(&bc->tin); /* Changing baud in mid-stream transmission can be wonderful */ - /* --------------------------------------------------------------- - Flush current transmit buffer by setting cmdTail pointer (tout) - to cmdHead pointer (tin). Hopefully the transmit buffer is empty. - ----------------------------------------------------------------- */ + /* + * Flush current transmit buffer by setting cmdTail pointer + * (tout) to cmdHead pointer (tin). Hopefully the transmit + * buffer is empty. + */ fepcmd(ch, STOUT, (unsigned) cmdHead, 0, 0, 0); mval = 0; - } else { /* Begin CBAUD not detected */ - /* ------------------------------------------------------------------- - c_cflags have changed but that change had nothing to do with BAUD. - Propagate the change to the card. - ---------------------------------------------------------------------- */ + } else { /* Begin CBAUD not detected */ + /* + * c_cflags have changed but that change had nothing to do with + * BAUD. Propagate the change to the card. + */ cflag = termios2digi_c(ch, ts->c_cflag); if (cflag != ch->fepcflag) { ch->fepcflag = cflag; /* Set baud rate, char size, stop bits, parity */ fepcmd(ch, SETCTRLFLAGS, (unsigned) cflag, 0, 0, 0); } - /* ---------------------------------------------------------------- - If the user has not forced CLOCAL and if the device is not a - CALLOUT device (Which is always CLOCAL) we set flags such that - the driver will wait on carrier detect. - ------------------------------------------------------------------- */ + /* + * If the user has not forced CLOCAL and if the device is not a + * CALLOUT device (Which is always CLOCAL) we set flags such + * that the driver will wait on carrier detect. + */ if (ts->c_cflag & CLOCAL) ch->asyncflags &= ~ASYNC_CHECK_CD; else @@ -2045,19 +1880,19 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch) /* Check input mode flags */ if (iflag != ch->fepiflag) { ch->fepiflag = iflag; - /* --------------------------------------------------------------- - Command sets channels iflag structure on the board. Such things - as input soft flow control, handling of parity errors, and - break handling are all set here. - ------------------------------------------------------------------- */ + /* + * Command sets channels iflag structure on the board. Such + * things as input soft flow control, handling of parity + * errors, and break handling are all set here. + */ /* break handling, parity handling, input stripping, flow control chars */ fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0); } - /* --------------------------------------------------------------- - Set the board mint value for this channel. This will cause hardware - events to be generated each time the DCD signal (Described in mint) - changes. - ------------------------------------------------------------------- */ + /* + * Set the board mint value for this channel. This will cause hardware + * events to be generated each time the DCD signal (Described in mint) + * changes. + */ writeb(ch->dcd, &bc->mint); if ((ts->c_cflag & CLOCAL) || (ch->digiext.digi_flags & DIGI_FORCEDCD)) if (ch->digiext.digi_flags & DIGI_FORCEDCD) @@ -2066,23 +1901,23 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch) hflow = termios2digi_h(ch, ts->c_cflag); if (hflow != ch->hflow) { ch->hflow = hflow; - /* -------------------------------------------------------------- - Hard flow control has been selected but the board is not - using it. Activate hard flow control now. - ----------------------------------------------------------------- */ + /* + * Hard flow control has been selected but the board is not + * using it. Activate hard flow control now. + */ fepcmd(ch, SETHFLOW, hflow, 0xff, 0, 1); } mval ^= ch->modemfake & (mval ^ ch->modem); if (ch->omodem ^ mval) { ch->omodem = mval; - /* -------------------------------------------------------------- - The below command sets the DTR and RTS mstat structure. If - hard flow control is NOT active these changes will drive the - output of the actual DTR and RTS lines. If hard flow control - is active, the changes will be saved in the mstat structure and - only asserted when hard flow control is turned off. - ----------------------------------------------------------------- */ + /* + * The below command sets the DTR and RTS mstat structure. If + * hard flow control is NOT active these changes will drive the + * output of the actual DTR and RTS lines. If hard flow control + * is active, the changes will be saved in the mstat structure + * and only asserted when hard flow control is turned off. + */ /* First reset DTR & RTS; then set them */ fepcmd(ch, SETMODEM, 0, ((ch->m_dtr)|(ch->m_rts)), 0, 1); @@ -2091,28 +1926,26 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch) if (ch->startc != ch->fepstartc || ch->stopc != ch->fepstopc) { ch->fepstartc = ch->startc; ch->fepstopc = ch->stopc; - /* ------------------------------------------------------------ - The XON / XOFF characters have changed; propagate these - changes to the card. - --------------------------------------------------------------- */ + /* + * The XON / XOFF characters have changed; propagate these + * changes to the card. + */ fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1); } if (ch->startca != ch->fepstartca || ch->stopca != ch->fepstopca) { ch->fepstartca = ch->startca; ch->fepstopca = ch->stopca; - /* --------------------------------------------------------------- - Similar to the above, this time the auxilarly XON / XOFF - characters have changed; propagate these changes to the card. - ------------------------------------------------------------------ */ + /* + * Similar to the above, this time the auxilarly XON / XOFF + * characters have changed; propagate these changes to the card. + */ fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1); } -} /* End epcaparam */ +} -/* --------------------- Begin receive_data ----------------------- */ /* Caller holds lock */ static void receive_data(struct channel *ch) -{ /* Begin receive_data */ - +{ unchar *rptr; struct ktermios *ts = NULL; struct tty_struct *tty; @@ -2121,11 +1954,10 @@ static void receive_data(struct channel *ch) unsigned int tail, head; unsigned int wrapmask; - /* --------------------------------------------------------------- - This routine is called by doint when a receive data event - has taken place. - ------------------------------------------------------------------- */ - + /* + * This routine is called by doint when a receive data event has taken + * place. + */ globalwinon(ch); if (ch->statusflags & RXSTOPPED) return; @@ -2136,10 +1968,10 @@ static void receive_data(struct channel *ch) BUG_ON(!bc); wrapmask = ch->rxbufsize - 1; - /* --------------------------------------------------------------------- - Get the head and tail pointers to the receiver queue. Wrap the - head pointer if it has reached the end of the buffer. - ------------------------------------------------------------------------ */ + /* + * Get the head and tail pointers to the receiver queue. Wrap the head + * pointer if it has reached the end of the buffer. + */ head = readw(&bc->rin); head &= wrapmask; tail = readw(&bc->rout) & wrapmask; @@ -2148,10 +1980,7 @@ static void receive_data(struct channel *ch) if (bytesAvailable == 0) return; - /* ------------------------------------------------------------------ - If CREAD bit is off or device not open, set TX tail to head - --------------------------------------------------------------------- */ - + /* If CREAD bit is off or device not open, set TX tail to head */ if (!tty || !ts || !(ts->c_cflag & CREAD)) { writew(head, &bc->rout); return; @@ -2168,22 +1997,20 @@ static void receive_data(struct channel *ch) rxwinon(ch); while (bytesAvailable > 0) { /* Begin while there is data on the card */ wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; - /* --------------------------------------------------------------- - Even if head has wrapped around only report the amount of - data to be equal to the size - tail. Remember memcpy can't - automaticly wrap around the receive buffer. - ----------------------------------------------------------------- */ + /* + * Even if head has wrapped around only report the amount of + * data to be equal to the size - tail. Remember memcpy can't + * automaticly wrap around the receive buffer. + */ dataToRead = (wrapgap < bytesAvailable) ? wrapgap : bytesAvailable; - /* -------------------------------------------------------------- - Make sure we don't overflow the buffer - ----------------------------------------------------------------- */ + /* Make sure we don't overflow the buffer */ dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead); if (dataToRead == 0) break; - /* --------------------------------------------------------------- - Move data read from our card into the line disciplines buffer - for translation if necessary. - ------------------------------------------------------------------ */ + /* + * Move data read from our card into the line disciplines + * buffer for translation if necessary. + */ memcpy_fromio(rptr, ch->rxptr + tail, dataToRead); tail = (tail + dataToRead) & wrapmask; bytesAvailable -= dataToRead; @@ -2191,28 +2018,26 @@ static void receive_data(struct channel *ch) globalwinon(ch); writew(tail, &bc->rout); /* Must be called with global data */ - tty_schedule_flip(ch->tty); - return; -} /* End receive_data */ + tty_schedule_flip(ch->tty); +} -static int info_ioctl(struct tty_struct *tty, struct file * file, +static int info_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { - switch (cmd) - { /* Begin switch cmd */ - case DIGI_GETINFO: - { /* Begin case DIGI_GETINFO */ - struct digi_info di ; + switch (cmd) { + case DIGI_GETINFO: + { + struct digi_info di; int brd; - if(get_user(brd, (unsigned int __user *)arg)) + if (get_user(brd, (unsigned int __user *)arg)) return -EFAULT; if (brd < 0 || brd >= num_cards || num_cards == 0) return -ENODEV; memset(&di, 0, sizeof(di)); - di.board = brd ; + di.board = brd; di.status = boards[brd].status; di.type = boards[brd].type ; di.numports = boards[brd].numports ; @@ -2220,45 +2045,44 @@ static int info_ioctl(struct tty_struct *tty, struct file * file, di.port = (unsigned char *)boards[brd].port ; di.membase = (unsigned char *)boards[brd].membase ; - if (copy_to_user((void __user *)arg, &di, sizeof (di))) + if (copy_to_user((void __user *)arg, &di, sizeof(di))) return -EFAULT; break; - } /* End case DIGI_GETINFO */ - - case DIGI_POLLER: - { /* Begin case DIGI_POLLER */ + } - int brd = arg & 0xff000000 >> 16 ; - unsigned char state = arg & 0xff ; + case DIGI_POLLER: + { + int brd = arg & 0xff000000 >> 16; + unsigned char state = arg & 0xff; if (brd < 0 || brd >= num_cards) { printk(KERN_ERR "epca: DIGI POLLER : brd not valid!\n"); - return (-ENODEV); + return -ENODEV; } - digi_poller_inhibited = state ; - break ; - } /* End case DIGI_POLLER */ - - case DIGI_INIT: - { /* Begin case DIGI_INIT */ - /* ------------------------------------------------------------ - This call is made by the apps to complete the initilization - of the board(s). This routine is responsible for setting - the card to its initial state and setting the drivers control - fields to the sutianle settings for the card in question. - ---------------------------------------------------------------- */ - int crd ; - for (crd = 0; crd < num_cards; crd++) - post_fep_init (crd); - break ; - } /* End case DIGI_INIT */ - default: - return -ENOTTY; - } /* End switch cmd */ - return (0) ; + digi_poller_inhibited = state; + break; + } + + case DIGI_INIT: + { + /* + * This call is made by the apps to complete the + * initilization of the board(s). This routine is + * responsible for setting the card to its initial + * state and setting the drivers control fields to the + * sutianle settings for the card in question. + */ + int crd; + for (crd = 0; crd < num_cards; crd++) + post_fep_init(crd); + break; + } + default: + return -ENOTTY; + } + return 0; } -/* --------------------- Begin pc_ioctl ----------------------- */ static int pc_tiocmget(struct tty_struct *tty, struct file *file) { @@ -2304,9 +2128,9 @@ static int pc_tiocmset(struct tty_struct *tty, struct file *file, spin_lock_irqsave(&epca_lock, flags); /* - * I think this modemfake stuff is broken. It doesn't - * correctly reflect the behaviour desired by the TIOCM* - * ioctls. Therefore this is probably broken. + * I think this modemfake stuff is broken. It doesn't correctly reflect + * the behaviour desired by the TIOCM* ioctls. Therefore this is + * probably broken. */ if (set & TIOCM_RTS) { ch->modemfake |= ch->m_rts; @@ -2325,10 +2149,10 @@ static int pc_tiocmset(struct tty_struct *tty, struct file *file, ch->modem &= ~ch->m_dtr; } globalwinon(ch); - /* -------------------------------------------------------------- - The below routine generally sets up parity, baud, flow control - issues, etc.... It effect both control flags and input flags. - ------------------------------------------------------------------ */ + /* + * The below routine generally sets up parity, baud, flow control + * issues, etc.... It effect both control flags and input flags. + */ epcaparam(tty,ch); memoff(ch); spin_unlock_irqrestore(&epca_lock, flags); @@ -2337,8 +2161,7 @@ static int pc_tiocmset(struct tty_struct *tty, struct file *file, static int pc_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) -{ /* Begin pc_ioctl */ - +{ digiflow_t dflow; int retval; unsigned long flags; @@ -2347,49 +2170,47 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, struct board_chan __iomem *bc; struct channel *ch = (struct channel *) tty->driver_data; void __user *argp = (void __user *)arg; - + if (ch) bc = ch->brdchan; - else + else return -EINVAL; - /* ------------------------------------------------------------------- - For POSIX compliance we need to add more ioctls. See tty_ioctl.c - in /usr/src/linux/drivers/char for a good example. In particular - think about adding TCSETAF, TCSETAW, TCSETA, TCSETSF, TCSETSW, TCSETS. - ---------------------------------------------------------------------- */ - - switch (cmd) - { /* Begin switch cmd */ - case TCSBRK: /* SVID version: non-zero arg --> no break */ - retval = tty_check_change(tty); - if (retval) - return retval; - /* Setup an event to indicate when the transmit buffer empties */ - spin_lock_irqsave(&epca_lock, flags); - setup_empty_event(tty,ch); - spin_unlock_irqrestore(&epca_lock, flags); - tty_wait_until_sent(tty, 0); - if (!arg) - digi_send_break(ch, HZ/4); /* 1/4 second */ - return 0; - case TCSBRKP: /* support for POSIX tcsendbreak() */ - retval = tty_check_change(tty); - if (retval) - return retval; + /* + * For POSIX compliance we need to add more ioctls. See tty_ioctl.c in + * /usr/src/linux/drivers/char for a good example. In particular think + * about adding TCSETAF, TCSETAW, TCSETA, TCSETSF, TCSETSW, TCSETS. + */ + switch (cmd) { + case TCSBRK: /* SVID version: non-zero arg --> no break */ + retval = tty_check_change(tty); + if (retval) + return retval; + /* Setup an event to indicate when the transmit buffer empties */ + spin_lock_irqsave(&epca_lock, flags); + setup_empty_event(tty,ch); + spin_unlock_irqrestore(&epca_lock, flags); + tty_wait_until_sent(tty, 0); + if (!arg) + digi_send_break(ch, HZ / 4); /* 1/4 second */ + return 0; + case TCSBRKP: /* support for POSIX tcsendbreak() */ + retval = tty_check_change(tty); + if (retval) + return retval; - /* Setup an event to indicate when the transmit buffer empties */ - spin_lock_irqsave(&epca_lock, flags); - setup_empty_event(tty,ch); - spin_unlock_irqrestore(&epca_lock, flags); - tty_wait_until_sent(tty, 0); - digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4); - return 0; - case TIOCGSOFTCAR: - if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)arg)) - return -EFAULT; - return 0; - case TIOCSSOFTCAR: + /* Setup an event to indicate when the transmit buffer empties */ + spin_lock_irqsave(&epca_lock, flags); + setup_empty_event(tty,ch); + spin_unlock_irqrestore(&epca_lock, flags); + tty_wait_until_sent(tty, 0); + digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4); + return 0; + case TIOCGSOFTCAR: + if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)arg)) + return -EFAULT; + return 0; + case TIOCSSOFTCAR: { unsigned int value; @@ -2400,144 +2221,141 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, (value ? CLOCAL : 0)); return 0; } - case TIOCMODG: - mflag = pc_tiocmget(tty, file); - if (put_user(mflag, (unsigned long __user *)argp)) - return -EFAULT; - break; - case TIOCMODS: - if (get_user(mstat, (unsigned __user *)argp)) - return -EFAULT; - return pc_tiocmset(tty, file, mstat, ~mstat); - case TIOCSDTR: - spin_lock_irqsave(&epca_lock, flags); - ch->omodem |= ch->m_dtr; - globalwinon(ch); - fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - break; + case TIOCMODG: + mflag = pc_tiocmget(tty, file); + if (put_user(mflag, (unsigned long __user *)argp)) + return -EFAULT; + break; + case TIOCMODS: + if (get_user(mstat, (unsigned __user *)argp)) + return -EFAULT; + return pc_tiocmset(tty, file, mstat, ~mstat); + case TIOCSDTR: + spin_lock_irqsave(&epca_lock, flags); + ch->omodem |= ch->m_dtr; + globalwinon(ch); + fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1); + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + break; - case TIOCCDTR: + case TIOCCDTR: + spin_lock_irqsave(&epca_lock, flags); + ch->omodem &= ~ch->m_dtr; + globalwinon(ch); + fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1); + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + break; + case DIGI_GETA: + if (copy_to_user(argp, &ch->digiext, sizeof(digi_t))) + return -EFAULT; + break; + case DIGI_SETAW: + case DIGI_SETAF: + if (cmd == DIGI_SETAW) { + /* Setup an event to indicate when the transmit buffer empties */ spin_lock_irqsave(&epca_lock, flags); - ch->omodem &= ~ch->m_dtr; - globalwinon(ch); - fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1); - memoff(ch); + setup_empty_event(tty,ch); spin_unlock_irqrestore(&epca_lock, flags); - break; - case DIGI_GETA: - if (copy_to_user(argp, &ch->digiext, sizeof(digi_t))) - return -EFAULT; - break; - case DIGI_SETAW: - case DIGI_SETAF: - if (cmd == DIGI_SETAW) { - /* Setup an event to indicate when the transmit buffer empties */ - spin_lock_irqsave(&epca_lock, flags); - setup_empty_event(tty,ch); - spin_unlock_irqrestore(&epca_lock, flags); - tty_wait_until_sent(tty, 0); - } else { - /* ldisc lock already held in ioctl */ - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - } - /* Fall Thru */ - case DIGI_SETA: - if (copy_from_user(&ch->digiext, argp, sizeof(digi_t))) - return -EFAULT; - - if (ch->digiext.digi_flags & DIGI_ALTPIN) { - ch->dcd = ch->m_dsr; - ch->dsr = ch->m_dcd; - } else { - ch->dcd = ch->m_dcd; - ch->dsr = ch->m_dsr; + tty_wait_until_sent(tty, 0); + } else { + /* ldisc lock already held in ioctl */ + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + } + /* Fall Thru */ + case DIGI_SETA: + if (copy_from_user(&ch->digiext, argp, sizeof(digi_t))) + return -EFAULT; + + if (ch->digiext.digi_flags & DIGI_ALTPIN) { + ch->dcd = ch->m_dsr; + ch->dsr = ch->m_dcd; + } else { + ch->dcd = ch->m_dcd; + ch->dsr = ch->m_dsr; } - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - /* ----------------------------------------------------------------- - The below routine generally sets up parity, baud, flow control - issues, etc.... It effect both control flags and input flags. - ------------------------------------------------------------------- */ + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); - epcaparam(tty,ch); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - break; + /* + * The below routine generally sets up parity, baud, flow + * control issues, etc.... It effect both control flags and + * input flags. + */ + epcaparam(tty,ch); + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + break; + + case DIGI_GETFLOW: + case DIGI_GETAFLOW: + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); + if (cmd == DIGI_GETFLOW) { + dflow.startc = readb(&bc->startc); + dflow.stopc = readb(&bc->stopc); + } else { + dflow.startc = readb(&bc->startca); + dflow.stopc = readb(&bc->stopca); + } + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + + if (copy_to_user(argp, &dflow, sizeof(dflow))) + return -EFAULT; + break; + + case DIGI_SETAFLOW: + case DIGI_SETFLOW: + if (cmd == DIGI_SETFLOW) { + startc = ch->startc; + stopc = ch->stopc; + } else { + startc = ch->startca; + stopc = ch->stopca; + } + + if (copy_from_user(&dflow, argp, sizeof(dflow))) + return -EFAULT; - case DIGI_GETFLOW: - case DIGI_GETAFLOW: + if (dflow.startc != startc || dflow.stopc != stopc) { /* Begin if setflow toggled */ spin_lock_irqsave(&epca_lock, flags); globalwinon(ch); - if (cmd == DIGI_GETFLOW) { - dflow.startc = readb(&bc->startc); - dflow.stopc = readb(&bc->stopc); - } else { - dflow.startc = readb(&bc->startca); - dflow.stopc = readb(&bc->stopca); - } - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - if (copy_to_user(argp, &dflow, sizeof(dflow))) - return -EFAULT; - break; - - case DIGI_SETAFLOW: - case DIGI_SETFLOW: if (cmd == DIGI_SETFLOW) { - startc = ch->startc; - stopc = ch->stopc; + ch->fepstartc = ch->startc = dflow.startc; + ch->fepstopc = ch->stopc = dflow.stopc; + fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1); } else { - startc = ch->startca; - stopc = ch->stopca; + ch->fepstartca = ch->startca = dflow.startc; + ch->fepstopca = ch->stopca = dflow.stopc; + fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1); } - if (copy_from_user(&dflow, argp, sizeof(dflow))) - return -EFAULT; + if (ch->statusflags & TXSTOPPED) + pc_start(tty); - if (dflow.startc != startc || dflow.stopc != stopc) { /* Begin if setflow toggled */ - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - - if (cmd == DIGI_SETFLOW) { - ch->fepstartc = ch->startc = dflow.startc; - ch->fepstopc = ch->stopc = dflow.stopc; - fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1); - } else { - ch->fepstartca = ch->startca = dflow.startc; - ch->fepstopca = ch->stopca = dflow.stopc; - fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1); - } - - if (ch->statusflags & TXSTOPPED) - pc_start(tty); - - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - } /* End if setflow toggled */ - break; - default: - return -ENOIOCTLCMD; - } /* End switch cmd */ + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + } /* End if setflow toggled */ + break; + default: + return -ENOIOCTLCMD; + } return 0; -} /* End pc_ioctl */ - -/* --------------------- Begin pc_set_termios ----------------------- */ +} static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ /* Begin pc_set_termios */ - +{ struct channel *ch; unsigned long flags; - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ if ((ch = verifyChannel(tty)) != NULL) { /* Begin if channel valid */ spin_lock_irqsave(&epca_lock, flags); globalwinon(ch); @@ -2554,47 +2372,40 @@ static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios) wake_up_interruptible(&ch->open_wait); } /* End if channel valid */ - -} /* End pc_set_termios */ - -/* --------------------- Begin do_softint ----------------------- */ +} static void do_softint(struct work_struct *work) -{ /* Begin do_softint */ +{ struct channel *ch = container_of(work, struct channel, tqueue); /* Called in response to a modem change event */ - if (ch && ch->magic == EPCA_MAGIC) { /* Begin EPCA_MAGIC */ + if (ch && ch->magic == EPCA_MAGIC) { struct tty_struct *tty = ch->tty; if (tty && tty->driver_data) { - if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) { /* Begin if clear_bit */ + if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) { tty_hangup(tty); /* FIXME: module removal race here - AKPM */ wake_up_interruptible(&ch->open_wait); ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; - } /* End if clear_bit */ + } } - } /* End EPCA_MAGIC */ -} /* End do_softint */ - -/* ------------------------------------------------------------ - pc_stop and pc_start provide software flow control to the - routine and the pc_ioctl routine. ----------------------------------------------------------------- */ - -/* --------------------- Begin pc_stop ----------------------- */ + } +} +/* + * pc_stop and pc_start provide software flow control to the routine and the + * pc_ioctl routine. + */ static void pc_stop(struct tty_struct *tty) -{ /* Begin pc_stop */ - +{ struct channel *ch; unsigned long flags; - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ - if ((ch = verifyChannel(tty)) != NULL) { /* Begin if valid channel */ + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + if ((ch = verifyChannel(tty)) != NULL) { spin_lock_irqsave(&epca_lock, flags); - if ((ch->statusflags & TXSTOPPED) == 0) { /* Begin if transmit stop requested */ + if ((ch->statusflags & TXSTOPPED) == 0) { /* Begin if transmit stop requested */ globalwinon(ch); /* STOP transmitting now !! */ fepcmd(ch, PAUSETX, 0, 0, 0, 0); @@ -2602,19 +2413,17 @@ static void pc_stop(struct tty_struct *tty) memoff(ch); } /* End if transmit stop requested */ spin_unlock_irqrestore(&epca_lock, flags); - } /* End if valid channel */ -} /* End pc_stop */ - -/* --------------------- Begin pc_start ----------------------- */ + } +} static void pc_start(struct tty_struct *tty) -{ /* Begin pc_start */ +{ struct channel *ch; - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ - if ((ch = verifyChannel(tty)) != NULL) { /* Begin if channel valid */ + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + if ((ch = verifyChannel(tty)) != NULL) { unsigned long flags; spin_lock_irqsave(&epca_lock, flags); /* Just in case output was resumed because of a change in Digi-flow */ @@ -2630,28 +2439,25 @@ static void pc_start(struct tty_struct *tty) memoff(ch); } /* End transmit resume requested */ spin_unlock_irqrestore(&epca_lock, flags); - } /* End if channel valid */ -} /* End pc_start */ - -/* ------------------------------------------------------------------ - The below routines pc_throttle and pc_unthrottle are used - to slow (And resume) the receipt of data into the kernels - receive buffers. The exact occurrence of this depends on the - size of the kernels receive buffer and what the 'watermarks' - are set to for that buffer. See the n_ttys.c file for more - details. -______________________________________________________________________ */ -/* --------------------- Begin throttle ----------------------- */ - -static void pc_throttle(struct tty_struct * tty) -{ /* Begin pc_throttle */ + } +} + +/* + * The below routines pc_throttle and pc_unthrottle are used to slow (And + * resume) the receipt of data into the kernels receive buffers. The exact + * occurrence of this depends on the size of the kernels receive buffer and + * what the 'watermarks' are set to for that buffer. See the n_ttys.c file for + * more details. + */ +static void pc_throttle(struct tty_struct *tty) +{ struct channel *ch; unsigned long flags; - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ - if ((ch = verifyChannel(tty)) != NULL) { /* Begin if channel valid */ + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + if ((ch = verifyChannel(tty)) != NULL) { spin_lock_irqsave(&epca_lock, flags); if ((ch->statusflags & RXSTOPPED) == 0) { globalwinon(ch); @@ -2660,20 +2466,18 @@ static void pc_throttle(struct tty_struct * tty) memoff(ch); } spin_unlock_irqrestore(&epca_lock, flags); - } /* End if channel valid */ -} /* End pc_throttle */ - -/* --------------------- Begin unthrottle ----------------------- */ + } +} static void pc_unthrottle(struct tty_struct *tty) -{ /* Begin pc_unthrottle */ +{ struct channel *ch; unsigned long flags; - /* --------------------------------------------------------- - verifyChannel returns the channel from the tty struct - if it is valid. This serves as a sanity check. - ------------------------------------------------------------- */ - if ((ch = verifyChannel(tty)) != NULL) { /* Begin if channel valid */ + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + if ((ch = verifyChannel(tty)) != NULL) { /* Just in case output was resumed because of a change in Digi-flow */ spin_lock_irqsave(&epca_lock, flags); if (ch->statusflags & RXSTOPPED) { @@ -2683,151 +2487,143 @@ static void pc_unthrottle(struct tty_struct *tty) memoff(ch); } spin_unlock_irqrestore(&epca_lock, flags); - } /* End if channel valid */ -} /* End pc_unthrottle */ - -/* --------------------- Begin digi_send_break ----------------------- */ + } +} void digi_send_break(struct channel *ch, int msec) -{ /* Begin digi_send_break */ +{ unsigned long flags; spin_lock_irqsave(&epca_lock, flags); globalwinon(ch); - /* -------------------------------------------------------------------- - Maybe I should send an infinite break here, schedule() for - msec amount of time, and then stop the break. This way, - the user can't screw up the FEP by causing digi_send_break() - to be called (i.e. via an ioctl()) more than once in msec amount - of time. Try this for now... - ------------------------------------------------------------------------ */ + /* + * Maybe I should send an infinite break here, schedule() for msec + * amount of time, and then stop the break. This way, the user can't + * screw up the FEP by causing digi_send_break() to be called (i.e. via + * an ioctl()) more than once in msec amount of time. + * Try this for now... + */ fepcmd(ch, SENDBREAK, msec, 0, 10, 0); memoff(ch); spin_unlock_irqrestore(&epca_lock, flags); -} /* End digi_send_break */ - -/* --------------------- Begin setup_empty_event ----------------------- */ +} /* Caller MUST hold the lock */ - static void setup_empty_event(struct tty_struct *tty, struct channel *ch) -{ /* Begin setup_empty_event */ - +{ struct board_chan __iomem *bc = ch->brdchan; globalwinon(ch); ch->statusflags |= EMPTYWAIT; - /* ------------------------------------------------------------------ - When set the iempty flag request a event to be generated when the - transmit buffer is empty (If there is no BREAK in progress). - --------------------------------------------------------------------- */ + /* + * When set the iempty flag request a event to be generated when the + * transmit buffer is empty (If there is no BREAK in progress). + */ writeb(1, &bc->iempty); memoff(ch); -} /* End setup_empty_event */ +} -/* ---------------------- Begin epca_setup -------------------------- */ void epca_setup(char *str, int *ints) -{ /* Begin epca_setup */ +{ struct board_info board; int index, loop, last; char *temp, *t2; unsigned len; - /* ---------------------------------------------------------------------- - If this routine looks a little strange it is because it is only called - if a LILO append command is given to boot the kernel with parameters. - In this way, we can provide the user a method of changing his board - configuration without rebuilding the kernel. - ----------------------------------------------------------------------- */ - if (!liloconfig) - liloconfig = 1; + /* + * If this routine looks a little strange it is because it is only + * called if a LILO append command is given to boot the kernel with + * parameters. In this way, we can provide the user a method of + * changing his board configuration without rebuilding the kernel. + */ + if (!liloconfig) + liloconfig = 1; memset(&board, 0, sizeof(board)); /* Assume the data is int first, later we can change it */ /* I think that array position 0 of ints holds the number of args */ for (last = 0, index = 1; index <= ints[0]; index++) - switch(index) - { /* Begin parse switch */ - case 1: - board.status = ints[index]; - /* --------------------------------------------------------- - We check for 2 (As opposed to 1; because 2 is a flag - instructing the driver to ignore epcaconfig.) For this - reason we check for 2. - ------------------------------------------------------------ */ - if (board.status == 2) { /* Begin ignore epcaconfig as well as lilo cmd line */ - nbdevs = 0; - num_cards = 0; - return; - } /* End ignore epcaconfig as well as lilo cmd line */ - - if (board.status > 2) { - printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n", board.status); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_STATUS; - return; - } - last = index; - break; - case 2: - board.type = ints[index]; - if (board.type >= PCIXEM) { - printk(KERN_ERR "epca_setup: Invalid board type 0x%x\n", board.type); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_TYPE; - return; - } - last = index; - break; - case 3: - board.altpin = ints[index]; - if (board.altpin > 1) { - printk(KERN_ERR "epca_setup: Invalid board altpin 0x%x\n", board.altpin); - invalid_lilo_config = 1; - setup_error_code |= INVALID_ALTPIN; - return; - } - last = index; - break; - - case 4: - board.numports = ints[index]; - if (board.numports < 2 || board.numports > 256) { - printk(KERN_ERR "epca_setup: Invalid board numports 0x%x\n", board.numports); - invalid_lilo_config = 1; - setup_error_code |= INVALID_NUM_PORTS; - return; - } - nbdevs += board.numports; - last = index; - break; - - case 5: - board.port = ints[index]; - if (ints[index] <= 0) { - printk(KERN_ERR "epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port); - invalid_lilo_config = 1; - setup_error_code |= INVALID_PORT_BASE; - return; - } - last = index; - break; - - case 6: - board.membase = ints[index]; - if (ints[index] <= 0) { - printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n",(unsigned int)board.membase); - invalid_lilo_config = 1; - setup_error_code |= INVALID_MEM_BASE; - return; - } - last = index; - break; + switch (index) { /* Begin parse switch */ + case 1: + board.status = ints[index]; + /* + * We check for 2 (As opposed to 1; because 2 is a flag + * instructing the driver to ignore epcaconfig.) For + * this reason we check for 2. + */ + if (board.status == 2) { /* Begin ignore epcaconfig as well as lilo cmd line */ + nbdevs = 0; + num_cards = 0; + return; + } /* End ignore epcaconfig as well as lilo cmd line */ + + if (board.status > 2) { + printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n", board.status); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_STATUS; + return; + } + last = index; + break; + case 2: + board.type = ints[index]; + if (board.type >= PCIXEM) { + printk(KERN_ERR "epca_setup: Invalid board type 0x%x\n", board.type); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_TYPE; + return; + } + last = index; + break; + case 3: + board.altpin = ints[index]; + if (board.altpin > 1) { + printk(KERN_ERR "epca_setup: Invalid board altpin 0x%x\n", board.altpin); + invalid_lilo_config = 1; + setup_error_code |= INVALID_ALTPIN; + return; + } + last = index; + break; + + case 4: + board.numports = ints[index]; + if (board.numports < 2 || board.numports > 256) { + printk(KERN_ERR "epca_setup: Invalid board numports 0x%x\n", board.numports); + invalid_lilo_config = 1; + setup_error_code |= INVALID_NUM_PORTS; + return; + } + nbdevs += board.numports; + last = index; + break; - default: - printk(KERN_ERR "<Error> - epca_setup: Too many integer parms\n"); + case 5: + board.port = ints[index]; + if (ints[index] <= 0) { + printk(KERN_ERR "epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port); + invalid_lilo_config = 1; + setup_error_code |= INVALID_PORT_BASE; return; + } + last = index; + break; + + case 6: + board.membase = ints[index]; + if (ints[index] <= 0) { + printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n",(unsigned int)board.membase); + invalid_lilo_config = 1; + setup_error_code |= INVALID_MEM_BASE; + return; + } + last = index; + break; + + default: + printk(KERN_ERR "<Error> - epca_setup: Too many integer parms\n"); + return; } /* End parse switch */ @@ -2844,120 +2640,121 @@ void epca_setup(char *str, int *ints) /* Set index to the number of args + 1 */ index = last + 1; - switch(index) - { - case 1: - len = strlen(str); - if (strncmp("Disable", str, len) == 0) - board.status = 0; - else if (strncmp("Enable", str, len) == 0) - board.status = 1; - else { - printk(KERN_ERR "epca_setup: Invalid status %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_STATUS; - return; - } - last = index; - break; - - case 2: - for(loop = 0; loop < EPCA_NUM_TYPES; loop++) - if (strcmp(board_desc[loop], str) == 0) - break; - /* --------------------------------------------------------------- - If the index incremented above refers to a legitamate board - type set it here. - ------------------------------------------------------------------*/ - if (index < EPCA_NUM_TYPES) - board.type = loop; - else { - printk(KERN_ERR "epca_setup: Invalid board type: %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_TYPE; - return; - } - last = index; - break; - - case 3: - len = strlen(str); - if (strncmp("Disable", str, len) == 0) - board.altpin = 0; - else if (strncmp("Enable", str, len) == 0) - board.altpin = 1; - else { - printk(KERN_ERR "epca_setup: Invalid altpin %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_ALTPIN; - return; - } - last = index; - break; - - case 4: - t2 = str; - while (isdigit(*t2)) - t2++; - - if (*t2) { - printk(KERN_ERR "epca_setup: Invalid port count %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_NUM_PORTS; - return; - } + switch (index) { + case 1: + len = strlen(str); + if (strncmp("Disable", str, len) == 0) + board.status = 0; + else if (strncmp("Enable", str, len) == 0) + board.status = 1; + else { + printk(KERN_ERR "epca_setup: Invalid status %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_STATUS; + return; + } + last = index; + break; - /* ------------------------------------------------------------ - There is not a man page for simple_strtoul but the code can be - found in vsprintf.c. The first argument is the string to - translate (To an unsigned long obviously), the second argument - can be the address of any character variable or a NULL. If a - variable is given, the end pointer of the string will be stored - in that variable; if a NULL is given the end pointer will - not be returned. The last argument is the base to use. If - a 0 is indicated, the routine will attempt to determine the - proper base by looking at the values prefix (A '0' for octal, - a 'x' for hex, etc ... If a value is given it will use that - value as the base. - ---------------------------------------------------------------- */ - board.numports = simple_strtoul(str, NULL, 0); - nbdevs += board.numports; - last = index; - break; - - case 5: - t2 = str; - while (isxdigit(*t2)) - t2++; - - if (*t2) { - printk(KERN_ERR "epca_setup: Invalid i/o address %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_PORT_BASE; - return; - } + case 2: + for (loop = 0; loop < EPCA_NUM_TYPES; loop++) + if (strcmp(board_desc[loop], str) == 0) + break; + /* + * If the index incremented above refers to a + * legitamate board type set it here. + */ + if (index < EPCA_NUM_TYPES) + board.type = loop; + else { + printk(KERN_ERR "epca_setup: Invalid board type: %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_TYPE; + return; + } + last = index; + break; - board.port = simple_strtoul(str, NULL, 16); - last = index; - break; + case 3: + len = strlen(str); + if (strncmp("Disable", str, len) == 0) + board.altpin = 0; + else if (strncmp("Enable", str, len) == 0) + board.altpin = 1; + else { + printk(KERN_ERR "epca_setup: Invalid altpin %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_ALTPIN; + return; + } + last = index; + break; - case 6: - t2 = str; - while (isxdigit(*t2)) - t2++; + case 4: + t2 = str; + while (isdigit(*t2)) + t2++; - if (*t2) { - printk(KERN_ERR "epca_setup: Invalid memory base %s\n",str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_MEM_BASE; - return; - } - board.membase = simple_strtoul(str, NULL, 16); - last = index; - break; - default: - printk(KERN_ERR "epca: Too many string parms\n"); + if (*t2) { + printk(KERN_ERR "epca_setup: Invalid port count %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_NUM_PORTS; + return; + } + + /* + * There is not a man page for simple_strtoul but the + * code can be found in vsprintf.c. The first argument + * is the string to translate (To an unsigned long + * obviously), the second argument can be the address + * of any character variable or a NULL. If a variable + * is given, the end pointer of the string will be + * stored in that variable; if a NULL is given the end + * pointer will not be returned. The last argument is + * the base to use. If a 0 is indicated, the routine + * will attempt to determine the proper base by looking + * at the values prefix (A '0' for octal, a 'x' for + * hex, etc ... If a value is given it will use that + * value as the base. + */ + board.numports = simple_strtoul(str, NULL, 0); + nbdevs += board.numports; + last = index; + break; + + case 5: + t2 = str; + while (isxdigit(*t2)) + t2++; + + if (*t2) { + printk(KERN_ERR "epca_setup: Invalid i/o address %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_PORT_BASE; + return; + } + + board.port = simple_strtoul(str, NULL, 16); + last = index; + break; + + case 6: + t2 = str; + while (isxdigit(*t2)) + t2++; + + if (*t2) { + printk(KERN_ERR "epca_setup: Invalid memory base %s\n",str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_MEM_BASE; return; + } + board.membase = simple_strtoul(str, NULL, 16); + last = index; + break; + default: + printk(KERN_ERR "epca: Too many string parms\n"); + return; } str = temp; } /* End while there is a string arg */ @@ -2966,19 +2763,16 @@ void epca_setup(char *str, int *ints) printk(KERN_ERR "epca: Insufficient parms specified\n"); return; } - + /* I should REALLY validate the stuff here */ /* Copies our local copy of board into boards */ memcpy((void *)&boards[num_cards],(void *)&board, sizeof(board)); /* Does this get called once per lilo arg are what ? */ - printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n", - num_cards, board_desc[board.type], + printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n", + num_cards, board_desc[board.type], board.numports, (int)board.port, (unsigned int) board.membase); num_cards++; -} /* End epca_setup */ - - -/* ------------------------ Begin init_PCI --------------------------- */ +} enum epic_board_types { brd_xr = 0, @@ -2987,7 +2781,6 @@ enum epic_board_types { brd_xrj, }; - /* indexed directly by epic_board_types enum */ static struct { unsigned char board_type; @@ -2999,7 +2792,7 @@ static struct { { PCIXRJ, 2, }, }; -static int __devinit epca_init_one (struct pci_dev *pdev, +static int __devinit epca_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int board_num = -1; @@ -3013,7 +2806,7 @@ static int __devinit epca_init_one (struct pci_dev *pdev, board_idx = board_num + num_cards; if (board_idx >= MAXBOARDS) goto err_out; - + addr = pci_resource_start (pdev, epca_info_tbl[info_idx].bar_idx); if (!addr) { printk (KERN_ERR PFX "PCI region #%d not available (size 0)\n", @@ -3053,15 +2846,15 @@ static int __devinit epca_init_one (struct pci_dev *pdev, goto err_out_free_memregion; } - /* -------------------------------------------------------------- - I don't know what the below does, but the hardware guys say - its required on everything except PLX (In this case XRJ). - ---------------------------------------------------------------- */ + /* + * I don't know what the below does, but the hardware guys say its + * required on everything except PLX (In this case XRJ). + */ if (info_idx != brd_xrj) { - pci_write_config_byte(pdev, 0x40, 0); + pci_write_config_byte(pdev, 0x40, 0); pci_write_config_byte(pdev, 0x46, 0); } - + return 0; err_out_free_memregion: @@ -3086,7 +2879,7 @@ static struct pci_device_id epca_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, epca_pci_tbl); int __init init_PCI (void) -{ /* Begin init_PCI */ +{ memset (&epca_driver, 0, sizeof (epca_driver)); epca_driver.name = "epca"; epca_driver.id_table = epca_pci_tbl; diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 83c1151ec7a2..8252f8668538 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -69,6 +69,8 @@ static struct task_struct *hvc_task; /* Picks up late kicks after list walk but before schedule() */ static int hvc_kicked; +static int hvc_init(void); + #ifdef CONFIG_MAGIC_SYSRQ static int sysrq_pressed; #endif @@ -754,6 +756,13 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, struct hvc_struct *hp; int i; + /* We wait until a driver actually comes along */ + if (!hvc_driver) { + int err = hvc_init(); + if (err) + return ERR_PTR(err); + } + hp = kmalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size, GFP_KERNEL); if (!hp) @@ -829,16 +838,18 @@ int __devexit hvc_remove(struct hvc_struct *hp) return 0; } -/* Driver initialization. Follow console initialization. This is where the TTY - * interfaces start to become available. */ -static int __init hvc_init(void) +/* Driver initialization: called as soon as someone uses hvc_alloc(). */ +static int hvc_init(void) { struct tty_driver *drv; + int err; /* We need more than hvc_count adapters due to hotplug additions. */ drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); - if (!drv) - return -ENOMEM; + if (!drv) { + err = -ENOMEM; + goto out; + } drv->owner = THIS_MODULE; drv->driver_name = "hvc"; @@ -854,30 +865,43 @@ static int __init hvc_init(void) * added later. */ hvc_task = kthread_run(khvcd, NULL, "khvcd"); if (IS_ERR(hvc_task)) { - panic("Couldn't create kthread for console.\n"); - put_tty_driver(drv); - return -EIO; + printk(KERN_ERR "Couldn't create kthread for console.\n"); + err = PTR_ERR(hvc_task); + goto put_tty; } - if (tty_register_driver(drv)) - panic("Couldn't register hvc console driver\n"); + err = tty_register_driver(drv); + if (err) { + printk(KERN_ERR "Couldn't register hvc console driver\n"); + goto stop_thread; + } + /* FIXME: This mb() seems completely random. Remove it. */ mb(); hvc_driver = drv; return 0; + +put_tty: + put_tty_driver(hvc_driver); +stop_thread: + kthread_stop(hvc_task); + hvc_task = NULL; +out: + return err; } -module_init(hvc_init); /* This isn't particularly necessary due to this being a console driver * but it is nice to be thorough. */ static void __exit hvc_exit(void) { - kthread_stop(hvc_task); + if (hvc_driver) { + kthread_stop(hvc_task); - tty_unregister_driver(hvc_driver); - /* return tty_struct instances allocated in hvc_init(). */ - put_tty_driver(hvc_driver); - unregister_console(&hvc_con_driver); + tty_unregister_driver(hvc_driver); + /* return tty_struct instances allocated in hvc_init(). */ + put_tty_driver(hvc_driver); + unregister_console(&hvc_con_driver); + } } module_exit(hvc_exit); diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index bd94d5f9e62b..2124dce38f2b 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c @@ -619,11 +619,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) ip2config.irq[i] = pci_dev_i->irq; } else { // ann error ip2config.addr[i] = 0; - if (status == PCIBIOS_DEVICE_NOT_FOUND) { - printk( KERN_ERR "IP2: PCI board %d not found\n", i ); - } else { - printk( KERN_ERR "IP2: PCI error 0x%x \n", status ); - } + printk(KERN_ERR "IP2: PCI board %d not found\n", i); } } #else @@ -646,10 +642,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { if ( ip2config.addr[i] ) { - pB = kmalloc( sizeof(i2eBordStr), GFP_KERNEL); - if ( pB != NULL ) { + pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); + if (pB) { i2BoardPtrTable[i] = pB; - memset( pB, 0, sizeof(i2eBordStr) ); iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer ); iiReset( pB ); } else { diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 6a01dd9e43f8..8435fba73daf 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -4136,7 +4136,7 @@ static __exit void cleanup_ipmi(void) del_timer_sync(&ipmi_timer); #ifdef CONFIG_PROC_FS - remove_proc_entry(proc_ipmi_root->name, &proc_root); + remove_proc_entry(proc_ipmi_root->name, NULL); #endif /* CONFIG_PROC_FS */ driver_unregister(&ipmidriver); diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index d95f316afb5a..212276affa1f 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -38,6 +38,7 @@ #include <linux/kbd_kern.h> #include <linux/kbd_diacr.h> #include <linux/vt_kern.h> +#include <linux/consolemap.h> #include <linux/sysrq.h> #include <linux/input.h> #include <linux/reboot.h> @@ -403,9 +404,12 @@ static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch) return d; if (kbd->kbdmode == VC_UNICODE) - to_utf8(vc, conv_8bit_to_uni(d)); - else if (d < 0x100) - put_queue(vc, d); + to_utf8(vc, d); + else { + int c = conv_uni_to_8bit(d); + if (c != -1) + put_queue(vc, c); + } return ch; } @@ -417,9 +421,12 @@ static void fn_enter(struct vc_data *vc) { if (diacr) { if (kbd->kbdmode == VC_UNICODE) - to_utf8(vc, conv_8bit_to_uni(diacr)); - else if (diacr < 0x100) - put_queue(vc, diacr); + to_utf8(vc, diacr); + else { + int c = conv_uni_to_8bit(diacr); + if (c != -1) + put_queue(vc, c); + } diacr = 0; } put_queue(vc, 13); @@ -627,9 +634,12 @@ static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag) return; } if (kbd->kbdmode == VC_UNICODE) - to_utf8(vc, conv_8bit_to_uni(value)); - else if (value < 0x100) - put_queue(vc, value); + to_utf8(vc, value); + else { + int c = conv_uni_to_8bit(value); + if (c != -1) + put_queue(vc, c); + } } /* @@ -646,7 +656,12 @@ static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag) static void k_self(struct vc_data *vc, unsigned char value, char up_flag) { - k_unicode(vc, value, up_flag); + unsigned int uni; + if (kbd->kbdmode == VC_UNICODE) + uni = value; + else + uni = conv_8bit_to_uni(value); + k_unicode(vc, uni, up_flag); } static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) @@ -1366,7 +1381,7 @@ int __init kbd_init(void) kbd_table[i].lockstate = KBD_DEFLOCK; kbd_table[i].slockstate = 0; kbd_table[i].modeflags = KBD_DEFMODE; - kbd_table[i].kbdmode = VC_XLATE; + kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE; } error = input_register_handler(&kbd_handler); diff --git a/drivers/char/lp.c b/drivers/char/lp.c index c59e2a0996cc..81674d7c56c7 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -144,7 +144,7 @@ static unsigned int lp_count = 0; static struct class *lp_class; #ifdef CONFIG_LP_CONSOLE -static struct parport *console_registered; // initially NULL +static struct parport *console_registered; #endif /* CONFIG_LP_CONSOLE */ #undef LP_DEBUG @@ -749,8 +749,8 @@ static struct console lpcons = { /* --- initialisation code ------------------------------------- */ static int parport_nr[LP_NO] = { [0 ... LP_NO-1] = LP_PARPORT_UNSPEC }; -static char *parport[LP_NO] = { NULL, }; -static int reset = 0; +static char *parport[LP_NO]; +static int reset; module_param_array(parport, charp, NULL, 0); module_param(reset, bool, 0); @@ -758,10 +758,10 @@ module_param(reset, bool, 0); #ifndef MODULE static int __init lp_setup (char *str) { - static int parport_ptr; // initially zero + static int parport_ptr; int x; - if (get_option (&str, &x)) { + if (get_option(&str, &x)) { if (x == 0) { /* disable driver on "lp=" or "lp=0" */ parport_nr[0] = LP_PARPORT_OFF; @@ -807,7 +807,7 @@ static int lp_register(int nr, struct parport *port) #ifdef CONFIG_LP_CONSOLE if (!nr) { if (port->modes & PARPORT_MODE_SAFEININT) { - register_console (&lpcons); + register_console(&lpcons); console_registered = port; printk (KERN_INFO "lp%d: console ready\n", CONSOLE_LP); } else @@ -823,8 +823,7 @@ static void lp_attach (struct parport *port) { unsigned int i; - switch (parport_nr[0]) - { + switch (parport_nr[0]) { case LP_PARPORT_UNSPEC: case LP_PARPORT_AUTO: if (parport_nr[0] == LP_PARPORT_AUTO && @@ -855,7 +854,7 @@ static void lp_detach (struct parport *port) /* Write this some day. */ #ifdef CONFIG_LP_CONSOLE if (console_registered == port) { - unregister_console (&lpcons); + unregister_console(&lpcons); console_registered = NULL; } #endif /* CONFIG_LP_CONSOLE */ diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c index 7ee5d9444926..3c5802ae1716 100644 --- a/drivers/char/mbcs.c +++ b/drivers/char/mbcs.c @@ -22,7 +22,6 @@ #include <linux/delay.h> #include <linux/device.h> #include <linux/mm.h> -#include <linux/fs.h> #include <linux/uio.h> #include <asm/io.h> #include <asm/uaccess.h> diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 64551ab6be03..0e937f64a789 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -893,6 +893,11 @@ static struct class *mem_class; static int __init chr_dev_init(void) { int i; + int err; + + err = bdi_init(&zero_bdi); + if (err) + return err; if (register_chrdev(MEM_MAJOR,"mem",&memory_fops)) printk("unable to get major %d for memory devs\n", MEM_MAJOR); diff --git a/drivers/char/mxser.h b/drivers/char/mxser.h index 9fe28497eae9..1f4aa45ec004 100644 --- a/drivers/char/mxser.h +++ b/drivers/char/mxser.h @@ -30,8 +30,7 @@ #define TTY_THRESHOLD_THROTTLE 128 -#define LO_WATER (TTY_FLIPBUF_SIZE) -#define HI_WATER (TTY_FLIPBUF_SIZE*2*3/4) +#define HI_WATER 768 // added by James. 03-11-2004. #define MOXA_SDS_GETICOUNTER (MOXA + 68) diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index e8332f305d72..82bcfb9c839a 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c @@ -229,7 +229,7 @@ static void n_hdlc_release(struct n_hdlc *n_hdlc) wake_up_interruptible (&tty->read_wait); wake_up_interruptible (&tty->write_wait); - if (tty != NULL && tty->disc_data == n_hdlc) + if (tty->disc_data == n_hdlc) tty->disc_data = NULL; /* Break the tty->n_hdlc link */ /* Release transmit and receive buffers */ diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 84ac64fc48a1..efe2f5c55b91 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -66,7 +66,6 @@ #include <linux/poll.h> #include <linux/major.h> #include <linux/ppdev.h> -#include <linux/device.h> #include <asm/uaccess.h> #define PP_VERSION "ppdev: user-space parallel port driver" diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index fdc256b380b8..905d1f51a7bf 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c @@ -81,13 +81,9 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/delay.h> - #include <linux/netdevice.h> - #include <linux/vmalloc.h> #include <linux/init.h> - -#include <linux/delay.h> #include <linux/ioctl.h> #include <asm/system.h> diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 39cc318011ea..78d14935f2b8 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -36,6 +36,7 @@ #include <linux/kexec.h> #include <linux/irq.h> #include <linux/hrtimer.h> +#include <linux/oom.h> #include <asm/ptrace.h> #include <asm/irq_regs.h> @@ -107,12 +108,12 @@ static void sysrq_handle_unraw(int key, struct tty_struct *tty) struct kbd_struct *kbd = &kbd_table[fg_console]; if (kbd) - kbd->kbdmode = VC_XLATE; + kbd->kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE; } static struct sysrq_key_op sysrq_unraw_op = { .handler = sysrq_handle_unraw, .help_msg = "unRaw", - .action_msg = "Keyboard mode set to XLATE", + .action_msg = "Keyboard mode set to system default", .enable_mask = SYSRQ_ENABLE_KEYBOARD, }; #else diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 23fa18a6654c..a8e808461377 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -435,17 +435,12 @@ module_param(interrupts, bool, 0444); MODULE_PARM_DESC(interrupts, "Enable interrupts"); static int tpm_tis_init(struct device *dev, resource_size_t start, - resource_size_t len) + resource_size_t len, unsigned int irq) { u32 vendor, intfcaps, intmask; int rc, i; struct tpm_chip *chip; - if (!start) - start = TIS_MEM_BASE; - if (!len) - len = TIS_MEM_LEN; - if (!(chip = tpm_register_hardware(dev, &tpm_tis))) return -ENODEV; @@ -512,7 +507,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, iowrite32(intmask, chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality)); - if (interrupts) { + if (interrupts) + chip->vendor.irq = irq; + if (interrupts && !chip->vendor.irq) { chip->vendor.irq = ioread8(chip->vendor.iobase + TPM_INT_VECTOR(chip->vendor.locality)); @@ -597,10 +594,17 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, const struct pnp_device_id *pnp_id) { resource_size_t start, len; + unsigned int irq = 0; + start = pnp_mem_start(pnp_dev, 0); len = pnp_mem_len(pnp_dev, 0); - return tpm_tis_init(&pnp_dev->dev, start, len); + if (pnp_irq_valid(pnp_dev, 0)) + irq = pnp_irq(pnp_dev, 0); + else + interrupts = 0; + + return tpm_tis_init(&pnp_dev->dev, start, len, irq); } static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg) @@ -660,7 +664,7 @@ static int __init init_tis(void) return rc; if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0))) return PTR_ERR(pdev); - if((rc=tpm_tis_init(&pdev->dev, 0, 0)) != 0) { + if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) { platform_device_unregister(pdev); driver_unregister(&tis_drv); } diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 3ee73cf64bd2..745d552620bf 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -206,8 +206,6 @@ speed_t tty_termios_input_baud_rate(struct ktermios *termios) EXPORT_SYMBOL(tty_termios_input_baud_rate); -#ifdef BOTHER - /** * tty_termios_encode_baud_rate * @termios: ktermios structure holding user requested state @@ -225,6 +223,9 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate); * * Locking: Caller should hold termios lock. This is already held * when calling this function from the driver termios handler. + * + * The ifdefs deal with platforms whose owners have yet to update them + * and will all go away once this is done. */ void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud) @@ -234,9 +235,13 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed int iclose = ibaud/50, oclose = obaud/50; int ibinput = 0; + if (obaud == 0) /* CD dropped */ + ibaud = 0; /* Clear ibaud to be sure */ + termios->c_ispeed = ibaud; termios->c_ospeed = obaud; +#ifdef BOTHER /* If the user asked for a precise weird speed give a precise weird answer. If they asked for a Bfoo speed they many have problems digesting non-exact replies so fuzz a bit */ @@ -247,32 +252,60 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed iclose = 0; if ((termios->c_cflag >> IBSHIFT) & CBAUD) ibinput = 1; /* An input speed was specified */ - +#endif termios->c_cflag &= ~CBAUD; + /* + * Our goal is to find a close match to the standard baud rate + * returned. Walk the baud rate table and if we get a very close + * match then report back the speed as a POSIX Bxxxx value by + * preference + */ + do { if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) { termios->c_cflag |= baud_bits[i]; ofound = i; } if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) { - /* For the case input == output don't set IBAUD bits if the user didn't do so */ - if (ofound != i || ibinput) + if (ofound == i && !ibinput) + ifound = i; +#ifdef IBSHIFT + else { + ifound = i; termios->c_cflag |= (baud_bits[i] << IBSHIFT); - ifound = i; + } +#endif } } while (++i < n_baud_table); + + /* + * If we found no match then use BOTHER if provided or warn + * the user their platform maintainer needs to wake up if not. + */ +#ifdef BOTHER if (ofound == -1) termios->c_cflag |= BOTHER; /* Set exact input bits only if the input and output differ or the user already did */ if (ifound == -1 && (ibaud != obaud || ibinput)) termios->c_cflag |= (BOTHER << IBSHIFT); +#else + if (ifound == -1 || ofound == -1) { + static int warned; + if (!warned++) + printk(KERN_WARNING "tty: Unable to return correct " + "speed data as your architecture needs updating.\n"); + } +#endif } - EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); -#endif +void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) +{ + tty_termios_encode_baud_rate(tty->termios, ibaud, obaud); +} +EXPORT_SYMBOL_GPL(tty_encode_baud_rate); /** * tty_get_baud_rate - get tty bit rates @@ -304,6 +337,29 @@ speed_t tty_get_baud_rate(struct tty_struct *tty) EXPORT_SYMBOL(tty_get_baud_rate); /** + * tty_termios_copy_hw - copy hardware settings + * @new: New termios + * @old: Old termios + * + * Propogate the hardware specific terminal setting bits from + * the old termios structure to the new one. This is used in cases + * where the hardware does not support reconfiguration or as a helper + * in some cases where only minimal reconfiguration is supported + */ + +void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old) +{ + /* The bits a dumb device handles in software. Smart devices need + to always provide a set_termios method */ + new->c_cflag &= HUPCL | CREAD | CLOCAL; + new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL); + new->c_ispeed = old->c_ispeed; + new->c_ospeed = old->c_ospeed; +} + +EXPORT_SYMBOL(tty_termios_copy_hw); + +/** * change_termios - update termios values * @tty: tty to update * @new_termios: desired new value @@ -340,13 +396,12 @@ static void change_termios(struct tty_struct * tty, struct ktermios * new_termio tty->erasing = 0; } - + /* This bit should be in the ldisc code */ if (canon_change && !L_ICANON(tty) && tty->read_cnt) /* Get characters left over from canonical mode. */ wake_up_interruptible(&tty->read_wait); /* See if packet mode change of state. */ - if (tty->link && tty->link->packet) { int old_flow = ((old_termios.c_iflag & IXON) && (old_termios.c_cc[VSTOP] == '\023') && @@ -366,6 +421,8 @@ static void change_termios(struct tty_struct * tty, struct ktermios * new_termio if (tty->driver->set_termios) (*tty->driver->set_termios)(tty, &old_termios); + else + tty_termios_copy_hw(tty->termios, &old_termios); ld = tty_ldisc_ref(tty); if (ld != NULL) { @@ -440,6 +497,11 @@ static int set_termios(struct tty_struct * tty, void __user *arg, int opt) } change_termios(tty, &tmp_termios); + + /* FIXME: Arguably if tmp_termios == tty->termios AND the + actual requested termios was not tmp_termios then we may + want to return an error as no user requested change has + succeeded */ return 0; } diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 0d56f8fc105c..645ad9808982 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -158,7 +158,11 @@ static void blank_screen_t(unsigned long dummy); static void set_palette(struct vc_data *vc); static int printable; /* Is console ready for printing? */ -static int default_utf8; +#ifdef CONFIG_VT_UNICODE +int default_utf8 = 1; +#else +int default_utf8; +#endif module_param(default_utf8, int, S_IRUGO | S_IWUSR); /* diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index f69a8258095c..e6f89e8b9258 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -23,6 +23,7 @@ #include <linux/major.h> #include <linux/fs.h> #include <linux/console.h> +#include <linux/consolemap.h> #include <linux/signal.h> #include <linux/timex.h> @@ -582,10 +583,27 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, case KDGKBDIACR: { struct kbdiacrs __user *a = up; + struct kbdiacr diacr; + int i; if (put_user(accent_table_size, &a->kb_cnt)) return -EFAULT; - if (copy_to_user(a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr))) + for (i = 0; i < accent_table_size; i++) { + diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr); + diacr.base = conv_uni_to_8bit(accent_table[i].base); + diacr.result = conv_uni_to_8bit(accent_table[i].result); + if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) + return -EFAULT; + } + return 0; + } + case KDGKBDIACRUC: + { + struct kbdiacrsuc __user *a = up; + + if (put_user(accent_table_size, &a->kb_cnt)) + return -EFAULT; + if (copy_to_user(a->kbdiacruc, accent_table, accent_table_size*sizeof(struct kbdiacruc))) return -EFAULT; return 0; } @@ -593,6 +611,30 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, case KDSKBDIACR: { struct kbdiacrs __user *a = up; + struct kbdiacr diacr; + unsigned int ct; + int i; + + if (!perm) + return -EPERM; + if (get_user(ct,&a->kb_cnt)) + return -EFAULT; + if (ct >= MAX_DIACR) + return -EINVAL; + accent_table_size = ct; + for (i = 0; i < ct; i++) { + if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) + return -EFAULT; + accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr); + accent_table[i].base = conv_8bit_to_uni(diacr.base); + accent_table[i].result = conv_8bit_to_uni(diacr.result); + } + return 0; + } + + case KDSKBDIACRUC: + { + struct kbdiacrsuc __user *a = up; unsigned int ct; if (!perm) @@ -602,7 +644,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, if (ct >= MAX_DIACR) return -EINVAL; accent_table_size = ct; - if (copy_from_user(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr))) + if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc))) return -EFAULT; return 0; } @@ -1083,7 +1125,7 @@ int vt_waitactive(int vt) void reset_vc(struct vc_data *vc) { vc->vc_mode = KD_TEXT; - kbd_table[vc->vc_num].kbdmode = VC_XLATE; + kbd_table[vc->vc_num].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE; vc->vt_mode.mode = VT_AUTO; vc->vt_mode.waitv = 0; vc->vt_mode.relsig = 0; diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index 5a1d426744d6..e5c62b75f36f 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -1446,21 +1446,20 @@ static struct platform_driver iop_adma_driver = { static int __init iop_adma_init (void) { - /* it's currently unsafe to unload this module */ - /* if forced, worst case is that rmmod hangs */ - __unsafe(THIS_MODULE); - return platform_driver_register(&iop_adma_driver); } +/* it's currently unsafe to unload this module */ +#if 0 static void __exit iop_adma_exit (void) { platform_driver_unregister(&iop_adma_driver); return; } +module_exit(iop_adma_exit); +#endif module_init(iop_adma_init); -module_exit(iop_adma_exit); MODULE_AUTHOR("Intel Corporation"); MODULE_DESCRIPTION("IOP ADMA Engine Driver"); diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c index d9c92c5e0077..66436bae11ac 100644 --- a/drivers/i2c/chips/menelaus.c +++ b/drivers/i2c/chips/menelaus.c @@ -49,8 +49,6 @@ #define DRIVER_NAME "menelaus" -#define pr_err(fmt, arg...) printk(KERN_ERR DRIVER_NAME ": ", ## arg); - #define MENELAUS_I2C_ADDRESS 0x72 #define MENELAUS_REV 0x01 @@ -155,7 +153,7 @@ static int menelaus_write_reg(int reg, u8 value) int val = i2c_smbus_write_byte_data(the_menelaus->client, reg, value); if (val < 0) { - pr_err("write error"); + pr_err(DRIVER_NAME ": write error"); return val; } @@ -167,7 +165,7 @@ static int menelaus_read_reg(int reg) int val = i2c_smbus_read_byte_data(the_menelaus->client, reg); if (val < 0) - pr_err("read error"); + pr_err(DRIVER_NAME ": read error"); return val; } @@ -1177,7 +1175,7 @@ static int menelaus_probe(struct i2c_client *client) /* If a true probe check the device */ rev = menelaus_read_reg(MENELAUS_REV); if (rev < 0) { - pr_err("device not found"); + pr_err(DRIVER_NAME ": device not found"); err = -ENODEV; goto fail1; } @@ -1258,7 +1256,7 @@ static int __init menelaus_init(void) res = i2c_add_driver(&menelaus_i2c_driver); if (res < 0) { - pr_err("driver registration failed\n"); + pr_err(DRIVER_NAME ": driver registration failed\n"); return res; } diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 0f7a55d35ea7..3f2d68cff764 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h @@ -107,7 +107,7 @@ struct ehca_sport { struct ehca_shca { struct ib_device ib_device; - struct ibmebus_dev *ibmebus_dev; + struct of_device *ofdev; u8 num_ports; int hw_level; struct list_head shca_list; diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c index 1d41faa7a337..b4ac617a70e6 100644 --- a/drivers/infiniband/hw/ehca/ehca_eq.c +++ b/drivers/infiniband/hw/ehca/ehca_eq.c @@ -123,7 +123,7 @@ int ehca_create_eq(struct ehca_shca *shca, /* register interrupt handlers and initialize work queues */ if (type == EHCA_EQ) { - ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_eq, + ret = ibmebus_request_irq(eq->ist, ehca_interrupt_eq, IRQF_DISABLED, "ehca_eq", (void *)shca); if (ret < 0) @@ -131,7 +131,7 @@ int ehca_create_eq(struct ehca_shca *shca, tasklet_init(&eq->interrupt_task, ehca_tasklet_eq, (long)shca); } else if (type == EHCA_NEQ) { - ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_neq, + ret = ibmebus_request_irq(eq->ist, ehca_interrupt_neq, IRQF_DISABLED, "ehca_neq", (void *)shca); if (ret < 0) @@ -171,7 +171,7 @@ int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq) u64 h_ret; spin_lock_irqsave(&eq->spinlock, flags); - ibmebus_free_irq(NULL, eq->ist, (void *)shca); + ibmebus_free_irq(eq->ist, (void *)shca); h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq); diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 403467f66fe6..a3409fdb307c 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -404,7 +404,7 @@ int ehca_init_device(struct ehca_shca *shca) shca->ib_device.node_type = RDMA_NODE_IB_CA; shca->ib_device.phys_port_cnt = shca->num_ports; shca->ib_device.num_comp_vectors = 1; - shca->ib_device.dma_device = &shca->ibmebus_dev->ofdev.dev; + shca->ib_device.dma_device = &shca->ofdev->dev; shca->ib_device.query_device = ehca_query_device; shca->ib_device.query_port = ehca_query_port; shca->ib_device.query_gid = ehca_query_gid; @@ -658,7 +658,7 @@ static struct attribute_group ehca_dev_attr_grp = { .attrs = ehca_dev_attrs }; -static int __devinit ehca_probe(struct ibmebus_dev *dev, +static int __devinit ehca_probe(struct of_device *dev, const struct of_device_id *id) { struct ehca_shca *shca; @@ -666,16 +666,16 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, struct ib_pd *ibpd; int ret; - handle = of_get_property(dev->ofdev.node, "ibm,hca-handle", NULL); + handle = of_get_property(dev->node, "ibm,hca-handle", NULL); if (!handle) { ehca_gen_err("Cannot get eHCA handle for adapter: %s.", - dev->ofdev.node->full_name); + dev->node->full_name); return -ENODEV; } if (!(*handle)) { ehca_gen_err("Wrong eHCA handle for adapter: %s.", - dev->ofdev.node->full_name); + dev->node->full_name); return -ENODEV; } @@ -686,9 +686,9 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, } mutex_init(&shca->modify_mutex); - shca->ibmebus_dev = dev; + shca->ofdev = dev; shca->ipz_hca_handle.handle = *handle; - dev->ofdev.dev.driver_data = shca; + dev->dev.driver_data = shca; ret = ehca_sense_attributes(shca); if (ret < 0) { @@ -764,7 +764,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, } } - ret = sysfs_create_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp); + ret = sysfs_create_group(&dev->dev.kobj, &ehca_dev_attr_grp); if (ret) /* only complain; we can live without attributes */ ehca_err(&shca->ib_device, "Cannot create device attributes ret=%d", ret); @@ -814,12 +814,12 @@ probe1: return -EINVAL; } -static int __devexit ehca_remove(struct ibmebus_dev *dev) +static int __devexit ehca_remove(struct of_device *dev) { - struct ehca_shca *shca = dev->ofdev.dev.driver_data; + struct ehca_shca *shca = dev->dev.driver_data; int ret; - sysfs_remove_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp); + sysfs_remove_group(&dev->dev.kobj, &ehca_dev_attr_grp); if (ehca_open_aqp1 == 1) { int i; @@ -870,11 +870,11 @@ static struct of_device_id ehca_device_table[] = {}, }; -static struct ibmebus_driver ehca_driver = { - .name = "ehca", - .id_table = ehca_device_table, - .probe = ehca_probe, - .remove = ehca_remove, +static struct of_platform_driver ehca_driver = { + .name = "ehca", + .match_table = ehca_device_table, + .probe = ehca_probe, + .remove = ehca_remove, }; void ehca_poll_eqs(unsigned long data) diff --git a/drivers/lguest/lguest.c b/drivers/lguest/lguest.c index ee1c6d05c3d3..4a579c840301 100644 --- a/drivers/lguest/lguest.c +++ b/drivers/lguest/lguest.c @@ -893,7 +893,9 @@ static __init char *lguest_memory_setup(void) /* The Linux bootloader header contains an "e820" memory map: the * Launcher populated the first entry with our memory limit. */ - add_memory_region(E820_MAP->addr, E820_MAP->size, E820_MAP->type); + add_memory_region(boot_params.e820_map[0].addr, + boot_params.e820_map[0].size, + boot_params.e820_map[0].type); /* This string is for the boot messages. */ return "LGUEST"; diff --git a/drivers/md/md.c b/drivers/md/md.c index 0dc563d76b39..c059ae6f37e5 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2714,7 +2714,7 @@ action_show(mddev_t *mddev, char *page) { char *type = "idle"; if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || - test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) { + (!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))) { if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) type = "reshape"; else if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { @@ -2833,6 +2833,12 @@ sync_max_store(mddev_t *mddev, const char *buf, size_t len) static struct md_sysfs_entry md_sync_max = __ATTR(sync_speed_max, S_IRUGO|S_IWUSR, sync_max_show, sync_max_store); +static ssize_t +degraded_show(mddev_t *mddev, char *page) +{ + return sprintf(page, "%d\n", mddev->degraded); +} +static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded); static ssize_t sync_speed_show(mddev_t *mddev, char *page) @@ -2976,6 +2982,7 @@ static struct attribute *md_redundancy_attrs[] = { &md_suspend_lo.attr, &md_suspend_hi.attr, &md_bitmap.attr, + &md_degraded.attr, NULL, }; static struct attribute_group md_redundancy_group = { @@ -5770,26 +5777,47 @@ static int __init md_init(void) * Searches all registered partitions for autorun RAID arrays * at boot time. */ -static dev_t detected_devices[128]; -static int dev_cnt; + +static LIST_HEAD(all_detected_devices); +struct detected_devices_node { + struct list_head list; + dev_t dev; +}; void md_autodetect_dev(dev_t dev) { - if (dev_cnt >= 0 && dev_cnt < 127) - detected_devices[dev_cnt++] = dev; + struct detected_devices_node *node_detected_dev; + + node_detected_dev = kzalloc(sizeof(*node_detected_dev), GFP_KERNEL); + if (node_detected_dev) { + node_detected_dev->dev = dev; + list_add_tail(&node_detected_dev->list, &all_detected_devices); + } else { + printk(KERN_CRIT "md: md_autodetect_dev: kzalloc failed" + ", skipping dev(%d,%d)\n", MAJOR(dev), MINOR(dev)); + } } static void autostart_arrays(int part) { mdk_rdev_t *rdev; - int i; + struct detected_devices_node *node_detected_dev; + dev_t dev; + int i_scanned, i_passed; - printk(KERN_INFO "md: Autodetecting RAID arrays.\n"); + i_scanned = 0; + i_passed = 0; - for (i = 0; i < dev_cnt; i++) { - dev_t dev = detected_devices[i]; + printk(KERN_INFO "md: Autodetecting RAID arrays.\n"); + while (!list_empty(&all_detected_devices) && i_scanned < INT_MAX) { + i_scanned++; + node_detected_dev = list_entry(all_detected_devices.next, + struct detected_devices_node, list); + list_del(&node_detected_dev->list); + dev = node_detected_dev->dev; + kfree(node_detected_dev); rdev = md_import_device(dev,0, 90); if (IS_ERR(rdev)) continue; @@ -5799,8 +5827,11 @@ static void autostart_arrays(int part) continue; } list_add(&rdev->same_set, &pending_raid_disks); + i_passed++; } - dev_cnt = 0; + + printk(KERN_INFO "md: Scanned %d and added %d devices.\n", + i_scanned, i_passed); autorun_devices(part); } diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index e79e1a538d44..c111105fc2dc 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -472,7 +472,7 @@ bad_map: bio_io_error(bio); return 0; } - + static void raid0_status (struct seq_file *seq, mddev_t *mddev) { #undef MD_DEBUG @@ -480,18 +480,18 @@ static void raid0_status (struct seq_file *seq, mddev_t *mddev) int j, k, h; char b[BDEVNAME_SIZE]; raid0_conf_t *conf = mddev_to_conf(mddev); - + h = 0; for (j = 0; j < conf->nr_strip_zones; j++) { seq_printf(seq, " z%d", j); if (conf->hash_table[h] == conf->strip_zone+j) - seq_printf("(h%d)", h++); + seq_printf(seq, "(h%d)", h++); seq_printf(seq, "=["); for (k = 0; k < conf->strip_zone[j].nb_dev; k++) - seq_printf (seq, "%s/", bdevname( + seq_printf(seq, "%s/", bdevname( conf->strip_zone[j].dev[k]->bdev,b)); - seq_printf (seq, "] zo=%d do=%d s=%d\n", + seq_printf(seq, "] zo=%d do=%d s=%d\n", conf->strip_zone[j].zone_offset, conf->strip_zone[j].dev_offset, conf->strip_zone[j].size); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 0bcefad82413..16775a0df7f6 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1214,7 +1214,8 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) j = 0; if (j >= 0) mddev->resync_mismatches += r1_bio->sectors; - if (j < 0 || test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) { + if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery) + && test_bit(BIO_UPTODATE, &sbio->bi_flags))) { sbio->bi_end_io = NULL; rdev_dec_pending(conf->mirrors[i].rdev, mddev); } else { diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 8c83ee3b0920..ce8f1a34ed21 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c @@ -41,8 +41,6 @@ struct i2o_driver i2o_exec_driver; -static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind); - /* global wait list for POST WAIT */ static LIST_HEAD(i2o_exec_wait_list); @@ -369,6 +367,53 @@ static int i2o_exec_remove(struct device *dev) return 0; }; +#ifdef CONFIG_I2O_LCT_NOTIFY_ON_CHANGES +/** + * i2o_exec_lct_notify - Send a asynchronus LCT NOTIFY request + * @c: I2O controller to which the request should be send + * @change_ind: change indicator + * + * This function sends a LCT NOTIFY request to the I2O controller with + * the change indicator change_ind. If the change_ind == 0 the controller + * replies immediately after the request. If change_ind > 0 the reply is + * send after change indicator of the LCT is > change_ind. + */ +static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) +{ + i2o_status_block *sb = c->status_block.virt; + struct device *dev; + struct i2o_message *msg; + + mutex_lock(&c->lct_lock); + + dev = &c->pdev->dev; + + if (i2o_dma_realloc + (dev, &c->dlct, le32_to_cpu(sb->expected_lct_size), GFP_KERNEL)) + return -ENOMEM; + + msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); + if (IS_ERR(msg)) + return PTR_ERR(msg); + + msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6); + msg->u.head[1] = cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | + ADAPTER_TID); + msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context); + msg->u.s.tcntxt = cpu_to_le32(0x00000000); + msg->body[0] = cpu_to_le32(0xffffffff); + msg->body[1] = cpu_to_le32(change_ind); + msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len); + msg->body[3] = cpu_to_le32(c->dlct.phys); + + i2o_msg_post(c, msg); + + mutex_unlock(&c->lct_lock); + + return 0; +} +#endif + /** * i2o_exec_lct_modified - Called on LCT NOTIFY reply * @_work: work struct for a specific controller @@ -525,51 +570,6 @@ int i2o_exec_lct_get(struct i2o_controller *c) return rc; } -/** - * i2o_exec_lct_notify - Send a asynchronus LCT NOTIFY request - * @c: I2O controller to which the request should be send - * @change_ind: change indicator - * - * This function sends a LCT NOTIFY request to the I2O controller with - * the change indicator change_ind. If the change_ind == 0 the controller - * replies immediately after the request. If change_ind > 0 the reply is - * send after change indicator of the LCT is > change_ind. - */ -static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) -{ - i2o_status_block *sb = c->status_block.virt; - struct device *dev; - struct i2o_message *msg; - - mutex_lock(&c->lct_lock); - - dev = &c->pdev->dev; - - if (i2o_dma_realloc - (dev, &c->dlct, le32_to_cpu(sb->expected_lct_size), GFP_KERNEL)) - return -ENOMEM; - - msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6); - msg->u.head[1] = cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | - ADAPTER_TID); - msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context); - msg->u.s.tcntxt = cpu_to_le32(0x00000000); - msg->body[0] = cpu_to_le32(0xffffffff); - msg->body[1] = cpu_to_le32(change_ind); - msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len); - msg->body[3] = cpu_to_le32(c->dlct.phys); - - i2o_msg_post(c, msg); - - mutex_unlock(&c->lct_lock); - - return 0; -}; - /* Exec OSM driver struct */ struct i2o_driver i2o_exec_driver = { .name = OSM_NAME, diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 73e248fb2ff1..346c44eff95e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -203,4 +203,16 @@ config THINKPAD_ACPI_BAY If you are not sure, say Y here. +config ATMEL_SSC + tristate "Device driver for Atmel SSC peripheral" + depends on AVR32 || ARCH_AT91 + ---help--- + This option enables device driver support for Atmel Syncronized + Serial Communication peripheral (SSC). + + The SSC peripheral supports a wide variety of serial frame based + communications, i.e. I2S, SPI, etc. + + If unsure, say N. + endif # MISC_DEVICES diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b5ce0e3dba86..a24c61475c2f 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o +obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c new file mode 100644 index 000000000000..058ccac700d0 --- /dev/null +++ b/drivers/misc/atmel-ssc.c @@ -0,0 +1,174 @@ +/* + * Atmel SSC driver + * + * Copyright (C) 2007 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/platform_device.h> +#include <linux/list.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/atmel-ssc.h> + +/* Serialize access to ssc_list and user count */ +static DEFINE_SPINLOCK(user_lock); +static LIST_HEAD(ssc_list); + +struct ssc_device *ssc_request(unsigned int ssc_num) +{ + int ssc_valid = 0; + struct ssc_device *ssc; + + spin_lock(&user_lock); + list_for_each_entry(ssc, &ssc_list, list) { + if (ssc->pdev->id == ssc_num) { + ssc_valid = 1; + break; + } + } + + if (!ssc_valid) { + spin_unlock(&user_lock); + dev_dbg(&ssc->pdev->dev, "could not find requested device\n"); + return ERR_PTR(-ENODEV); + } + + if (ssc->user) { + spin_unlock(&user_lock); + dev_dbg(&ssc->pdev->dev, "module busy\n"); + return ERR_PTR(-EBUSY); + } + ssc->user++; + spin_unlock(&user_lock); + + clk_enable(ssc->clk); + + return ssc; +} +EXPORT_SYMBOL(ssc_request); + +void ssc_free(struct ssc_device *ssc) +{ + spin_lock(&user_lock); + if (ssc->user) { + ssc->user--; + clk_disable(ssc->clk); + } else { + dev_dbg(&ssc->pdev->dev, "device already free\n"); + } + spin_unlock(&user_lock); +} +EXPORT_SYMBOL(ssc_free); + +static int __init ssc_probe(struct platform_device *pdev) +{ + int retval = 0; + struct resource *regs; + struct ssc_device *ssc; + + ssc = kzalloc(sizeof(struct ssc_device), GFP_KERNEL); + if (!ssc) { + dev_dbg(&pdev->dev, "out of memory\n"); + retval = -ENOMEM; + goto out; + } + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_dbg(&pdev->dev, "no mmio resource defined\n"); + retval = -ENXIO; + goto out_free; + } + + ssc->clk = clk_get(&pdev->dev, "pclk"); + if (IS_ERR(ssc->clk)) { + dev_dbg(&pdev->dev, "no pclk clock defined\n"); + retval = -ENXIO; + goto out_free; + } + + ssc->pdev = pdev; + ssc->regs = ioremap(regs->start, regs->end - regs->start + 1); + if (!ssc->regs) { + dev_dbg(&pdev->dev, "ioremap failed\n"); + retval = -EINVAL; + goto out_clk; + } + + /* disable all interrupts */ + clk_enable(ssc->clk); + ssc_writel(ssc->regs, IDR, ~0UL); + ssc_readl(ssc->regs, SR); + clk_disable(ssc->clk); + + ssc->irq = platform_get_irq(pdev, 0); + if (!ssc->irq) { + dev_dbg(&pdev->dev, "could not get irq\n"); + retval = -ENXIO; + goto out_unmap; + } + + spin_lock(&user_lock); + list_add_tail(&ssc->list, &ssc_list); + spin_unlock(&user_lock); + + platform_set_drvdata(pdev, ssc); + + dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n", + ssc->regs, ssc->irq); + + goto out; + +out_unmap: + iounmap(ssc->regs); +out_clk: + clk_put(ssc->clk); +out_free: + kfree(ssc); +out: + return retval; +} + +static int __devexit ssc_remove(struct platform_device *pdev) +{ + struct ssc_device *ssc = platform_get_drvdata(pdev); + + spin_lock(&user_lock); + iounmap(ssc->regs); + clk_put(ssc->clk); + list_del(&ssc->list); + kfree(ssc); + spin_unlock(&user_lock); + + return 0; +} + +static struct platform_driver ssc_driver = { + .remove = __devexit_p(ssc_remove), + .driver = { + .name = "ssc", + }, +}; + +static int __init ssc_init(void) +{ + return platform_driver_probe(&ssc_driver, ssc_probe); +} +module_init(ssc_init); + +static void __exit ssc_exit(void) +{ + platform_driver_unregister(&ssc_driver); +} +module_exit(ssc_exit); + +MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); +MODULE_DESCRIPTION("SSC driver for Atmel AVR32 and AT91"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 1297732f4db9..880fa3690352 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -933,8 +933,7 @@ write_error: * @cache: the lock tree entry slab cache * @flags: constructor flags */ -static void ltree_entry_ctor(void *obj, struct kmem_cache *cache, - unsigned long flags) +static void ltree_entry_ctor(struct kmem_cache *cache, void *obj) { struct ltree_entry *le = obj; diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index ac21526b6de8..b557bb44a36f 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -388,7 +388,7 @@ struct ehea_port_res { #define EHEA_MAX_PORTS 16 struct ehea_adapter { u64 handle; - struct ibmebus_dev *ebus_dev; + struct of_device *ofdev; struct ehea_port *port[EHEA_MAX_PORTS]; struct ehea_eq *neq; /* notification event queue */ struct tasklet_struct neq_tasklet; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 2ba57e6ace4d..fe5ffac7ac57 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -98,10 +98,10 @@ struct work_struct ehea_rereg_mr_task; struct semaphore dlpar_mem_lock; -static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, +static int __devinit ehea_probe_adapter(struct of_device *dev, const struct of_device_id *id); -static int __devexit ehea_remove(struct ibmebus_dev *dev); +static int __devexit ehea_remove(struct of_device *dev); static struct of_device_id ehea_device_table[] = { { @@ -111,9 +111,9 @@ static struct of_device_id ehea_device_table[] = { {}, }; -static struct ibmebus_driver ehea_driver = { +static struct of_platform_driver ehea_driver = { .name = "ehea", - .id_table = ehea_device_table, + .match_table = ehea_device_table, .probe = ehea_probe_adapter, .remove = ehea_remove, }; @@ -1044,7 +1044,7 @@ static int ehea_reg_interrupts(struct net_device *dev) snprintf(port->int_aff_name, EHEA_IRQ_NAME_SIZE - 1, "%s-aff", dev->name); - ret = ibmebus_request_irq(NULL, port->qp_eq->attr.ist1, + ret = ibmebus_request_irq(port->qp_eq->attr.ist1, ehea_qp_aff_irq_handler, IRQF_DISABLED, port->int_aff_name, port); if (ret) { @@ -1062,7 +1062,7 @@ static int ehea_reg_interrupts(struct net_device *dev) pr = &port->port_res[i]; snprintf(pr->int_send_name, EHEA_IRQ_NAME_SIZE - 1, "%s-queue%d", dev->name, i); - ret = ibmebus_request_irq(NULL, pr->eq->attr.ist1, + ret = ibmebus_request_irq(pr->eq->attr.ist1, ehea_recv_irq_handler, IRQF_DISABLED, pr->int_send_name, pr); @@ -1083,11 +1083,11 @@ out: out_free_req: while (--i >= 0) { u32 ist = port->port_res[i].eq->attr.ist1; - ibmebus_free_irq(NULL, ist, &port->port_res[i]); + ibmebus_free_irq(ist, &port->port_res[i]); } out_free_qpeq: - ibmebus_free_irq(NULL, port->qp_eq->attr.ist1, port); + ibmebus_free_irq(port->qp_eq->attr.ist1, port); i = port->num_def_qps; goto out; @@ -1104,14 +1104,14 @@ static void ehea_free_interrupts(struct net_device *dev) for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { pr = &port->port_res[i]; - ibmebus_free_irq(NULL, pr->eq->attr.ist1, pr); + ibmebus_free_irq(pr->eq->attr.ist1, pr); if (netif_msg_intr(port)) ehea_info("free send irq for res %d with handle 0x%X", i, pr->eq->attr.ist1); } /* associated events */ - ibmebus_free_irq(NULL, port->qp_eq->attr.ist1, port); + ibmebus_free_irq(port->qp_eq->attr.ist1, port); if (netif_msg_intr(port)) ehea_info("associated event interrupt for handle 0x%X freed", port->qp_eq->attr.ist1); @@ -2832,7 +2832,7 @@ static struct device *ehea_register_port(struct ehea_port *port, int ret; port->ofdev.node = of_node_get(dn); - port->ofdev.dev.parent = &port->adapter->ebus_dev->ofdev.dev; + port->ofdev.dev.parent = &port->adapter->ofdev->dev; port->ofdev.dev.bus = &ibmebus_bus_type; sprintf(port->ofdev.dev.bus_id, "port%d", port_name_cnt++); @@ -3011,7 +3011,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) const u32 *dn_log_port_id; int i = 0; - lhea_dn = adapter->ebus_dev->ofdev.node; + lhea_dn = adapter->ofdev->node; while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", @@ -3051,7 +3051,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, struct device_node *eth_dn = NULL; const u32 *dn_log_port_id; - lhea_dn = adapter->ebus_dev->ofdev.node; + lhea_dn = adapter->ofdev->node; while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", @@ -3157,31 +3157,31 @@ static ssize_t ehea_remove_port(struct device *dev, static DEVICE_ATTR(probe_port, S_IWUSR, NULL, ehea_probe_port); static DEVICE_ATTR(remove_port, S_IWUSR, NULL, ehea_remove_port); -int ehea_create_device_sysfs(struct ibmebus_dev *dev) +int ehea_create_device_sysfs(struct of_device *dev) { - int ret = device_create_file(&dev->ofdev.dev, &dev_attr_probe_port); + int ret = device_create_file(&dev->dev, &dev_attr_probe_port); if (ret) goto out; - ret = device_create_file(&dev->ofdev.dev, &dev_attr_remove_port); + ret = device_create_file(&dev->dev, &dev_attr_remove_port); out: return ret; } -void ehea_remove_device_sysfs(struct ibmebus_dev *dev) +void ehea_remove_device_sysfs(struct of_device *dev) { - device_remove_file(&dev->ofdev.dev, &dev_attr_probe_port); - device_remove_file(&dev->ofdev.dev, &dev_attr_remove_port); + device_remove_file(&dev->dev, &dev_attr_probe_port); + device_remove_file(&dev->dev, &dev_attr_remove_port); } -static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, +static int __devinit ehea_probe_adapter(struct of_device *dev, const struct of_device_id *id) { struct ehea_adapter *adapter; const u64 *adapter_handle; int ret; - if (!dev || !dev->ofdev.node) { + if (!dev || !dev->node) { ehea_error("Invalid ibmebus device probed"); return -EINVAL; } @@ -3189,36 +3189,36 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); if (!adapter) { ret = -ENOMEM; - dev_err(&dev->ofdev.dev, "no mem for ehea_adapter\n"); + dev_err(&dev->dev, "no mem for ehea_adapter\n"); goto out; } list_add(&adapter->list, &adapter_list); - adapter->ebus_dev = dev; + adapter->ofdev = dev; - adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle", + adapter_handle = of_get_property(dev->node, "ibm,hea-handle", NULL); if (adapter_handle) adapter->handle = *adapter_handle; if (!adapter->handle) { - dev_err(&dev->ofdev.dev, "failed getting handle for adapter" - " '%s'\n", dev->ofdev.node->full_name); + dev_err(&dev->dev, "failed getting handle for adapter" + " '%s'\n", dev->node->full_name); ret = -ENODEV; goto out_free_ad; } adapter->pd = EHEA_PD_ID; - dev->ofdev.dev.driver_data = adapter; + dev->dev.driver_data = adapter; /* initialize adapter and ports */ /* get adapter properties */ ret = ehea_sense_adapter_attr(adapter); if (ret) { - dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret); + dev_err(&dev->dev, "sense_adapter_attr failed: %d", ret); goto out_free_ad; } @@ -3226,18 +3226,18 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1); if (!adapter->neq) { ret = -EIO; - dev_err(&dev->ofdev.dev, "NEQ creation failed"); + dev_err(&dev->dev, "NEQ creation failed"); goto out_free_ad; } tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet, (unsigned long)adapter); - ret = ibmebus_request_irq(NULL, adapter->neq->attr.ist1, + ret = ibmebus_request_irq(adapter->neq->attr.ist1, ehea_interrupt_neq, IRQF_DISABLED, "ehea_neq", adapter); if (ret) { - dev_err(&dev->ofdev.dev, "requesting NEQ IRQ failed"); + dev_err(&dev->dev, "requesting NEQ IRQ failed"); goto out_kill_eq; } @@ -3247,7 +3247,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, ret = ehea_setup_ports(adapter); if (ret) { - dev_err(&dev->ofdev.dev, "setup_ports failed"); + dev_err(&dev->dev, "setup_ports failed"); goto out_rem_dev_sysfs; } @@ -3258,7 +3258,7 @@ out_rem_dev_sysfs: ehea_remove_device_sysfs(dev); out_free_irq: - ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter); + ibmebus_free_irq(adapter->neq->attr.ist1, adapter); out_kill_eq: ehea_destroy_eq(adapter->neq); @@ -3269,9 +3269,9 @@ out: return ret; } -static int __devexit ehea_remove(struct ibmebus_dev *dev) +static int __devexit ehea_remove(struct of_device *dev) { - struct ehea_adapter *adapter = dev->ofdev.dev.driver_data; + struct ehea_adapter *adapter = dev->dev.driver_data; int i; for (i = 0; i < EHEA_MAX_PORTS; i++) @@ -3284,7 +3284,7 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev) flush_scheduled_work(); - ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter); + ibmebus_free_irq(adapter->neq->attr.ist1, adapter); tasklet_kill(&adapter->neq_tasklet); ehea_destroy_eq(adapter->neq); diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h index a897beee7d5d..e1d05c0f47eb 100644 --- a/drivers/net/spider_net.h +++ b/drivers/net/spider_net.h @@ -494,7 +494,4 @@ struct spider_net_card { struct spider_net_descr darray[0]; }; -#define pr_err(fmt,arg...) \ - printk(KERN_ERR fmt ,##arg) - #endif diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index f201bd673137..519b4ff79f7f 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -269,6 +269,13 @@ config AT91_CF Say Y here to support the CompactFlash controller on AT91 chips. Or choose M to compile the driver as a module named "at91_cf". +config ELECTRA_CF + tristate "Electra CompactFlash Controller" + depends on PCMCIA && PPC_PASEMI + help + Say Y here to support the CompactFlash controller on the + PA Semi Electra eval board. + config PCCARD_NONSTATIC tristate diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index dc7a4cb5d270..6f6478ba7174 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o obj-$(CONFIG_OMAP_CF) += omap_cf.o obj-$(CONFIG_AT91_CF) += at91_cf.o +obj-$(CONFIG_ELECTRA_CF) += electra_cf.o sa11xx_core-y += soc_common.o sa11xx_base.o pxa2xx_core-y += soc_common.o pxa2xx_base.o diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c new file mode 100644 index 000000000000..0a6cea1316b4 --- /dev/null +++ b/drivers/pcmcia/electra_cf.c @@ -0,0 +1,377 @@ +/* + * Copyright (C) 2007 PA Semi, Inc + * + * Maintained by: Olof Johansson <olof@lixom.net> + * + * Based on drivers/pcmcia/omap_cf.c + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/platform_device.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/vmalloc.h> + +#include <pcmcia/ss.h> +#include <asm/of_platform.h> + +static const char driver_name[] = "electra-cf"; + +struct electra_cf_socket { + struct pcmcia_socket socket; + + struct timer_list timer; + unsigned present:1; + unsigned active:1; + + struct of_device *ofdev; + unsigned long mem_phys; + void __iomem * mem_base; + unsigned long mem_size; + void __iomem * io_virt; + unsigned int io_base; + unsigned int io_size; + u_int irq; + struct resource iomem; + void __iomem * gpio_base; + int gpio_detect; + int gpio_vsense; + int gpio_3v; + int gpio_5v; +}; + +#define POLL_INTERVAL (2 * HZ) + + +static int electra_cf_present(struct electra_cf_socket *cf) +{ + unsigned int gpio; + + gpio = in_le32(cf->gpio_base+0x40); + return !(gpio & (1 << cf->gpio_detect)); +} + +static int electra_cf_ss_init(struct pcmcia_socket *s) +{ + return 0; +} + +/* the timer is primarily to kick this socket's pccardd */ +static void electra_cf_timer(unsigned long _cf) +{ + struct electra_cf_socket *cf = (void *) _cf; + int present = electra_cf_present(cf); + + if (present != cf->present) { + cf->present = present; + pcmcia_parse_events(&cf->socket, SS_DETECT); + } + + if (cf->active) + mod_timer(&cf->timer, jiffies + POLL_INTERVAL); +} + +static irqreturn_t electra_cf_irq(int irq, void *_cf) +{ + electra_cf_timer((unsigned long)_cf); + return IRQ_HANDLED; +} + +static int electra_cf_get_status(struct pcmcia_socket *s, u_int *sp) +{ + struct electra_cf_socket *cf; + + if (!sp) + return -EINVAL; + + cf = container_of(s, struct electra_cf_socket, socket); + + /* NOTE CF is always 3VCARD */ + if (electra_cf_present(cf)) { + *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD; + + s->pci_irq = cf->irq; + } else + *sp = 0; + return 0; +} + +static int electra_cf_set_socket(struct pcmcia_socket *sock, + struct socket_state_t *s) +{ + unsigned int gpio; + unsigned int vcc; + struct electra_cf_socket *cf; + + cf = container_of(sock, struct electra_cf_socket, socket); + + /* "reset" means no power in our case */ + vcc = (s->flags & SS_RESET) ? 0 : s->Vcc; + + switch (vcc) { + case 0: + gpio = 0; + break; + case 33: + gpio = (1 << cf->gpio_3v); + break; + case 5: + gpio = (1 << cf->gpio_5v); + break; + default: + return -EINVAL; + } + + gpio |= 1 << (cf->gpio_3v + 16); /* enwr */ + gpio |= 1 << (cf->gpio_5v + 16); /* enwr */ + out_le32(cf->gpio_base+0x90, gpio); + + pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n", + driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask); + + return 0; +} + +static int electra_cf_set_io_map(struct pcmcia_socket *s, + struct pccard_io_map *io) +{ + return 0; +} + +static int electra_cf_set_mem_map(struct pcmcia_socket *s, + struct pccard_mem_map *map) +{ + struct electra_cf_socket *cf; + + if (map->card_start) + return -EINVAL; + cf = container_of(s, struct electra_cf_socket, socket); + map->static_start = cf->mem_phys; + map->flags &= MAP_ACTIVE|MAP_ATTRIB; + if (!(map->flags & MAP_ATTRIB)) + map->static_start += 0x800; + return 0; +} + +static struct pccard_operations electra_cf_ops = { + .init = electra_cf_ss_init, + .get_status = electra_cf_get_status, + .set_socket = electra_cf_set_socket, + .set_io_map = electra_cf_set_io_map, + .set_mem_map = electra_cf_set_mem_map, +}; + +static int __devinit electra_cf_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + struct device *device = &ofdev->dev; + struct device_node *np = ofdev->node; + struct electra_cf_socket *cf; + struct resource mem, io; + int status; + const unsigned int *prop; + int err; + struct vm_struct *area; + + err = of_address_to_resource(np, 0, &mem); + if (err) + return -EINVAL; + + err = of_address_to_resource(np, 1, &io); + if (err) + return -EINVAL; + + cf = kzalloc(sizeof *cf, GFP_KERNEL); + if (!cf) + return -ENOMEM; + + setup_timer(&cf->timer, electra_cf_timer, (unsigned long)cf); + cf->irq = NO_IRQ; + + cf->ofdev = ofdev; + cf->mem_phys = mem.start; + cf->mem_size = PAGE_ALIGN(mem.end - mem.start); + cf->mem_base = ioremap(cf->mem_phys, cf->mem_size); + cf->io_size = PAGE_ALIGN(io.end - io.start); + + area = __get_vm_area(cf->io_size, 0, PHB_IO_BASE, PHB_IO_END); + if (area == NULL) + return -ENOMEM; + + cf->io_virt = (void __iomem *)(area->addr); + + cf->gpio_base = ioremap(0xfc103000, 0x1000); + dev_set_drvdata(device, cf); + + if (!cf->mem_base || !cf->io_virt || !cf->gpio_base || + (__ioremap_at(io.start, cf->io_virt, cf->io_size, + _PAGE_NO_CACHE | _PAGE_GUARDED) == NULL)) { + dev_err(device, "can't ioremap ranges\n"); + status = -ENOMEM; + goto fail1; + } + + + cf->io_base = (unsigned long)cf->io_virt - VMALLOC_END; + + cf->iomem.start = (unsigned long)cf->mem_base; + cf->iomem.end = (unsigned long)cf->mem_base + (mem.end - mem.start); + cf->iomem.flags = IORESOURCE_MEM; + + cf->irq = irq_of_parse_and_map(np, 0); + + status = request_irq(cf->irq, electra_cf_irq, IRQF_SHARED, + driver_name, cf); + if (status < 0) { + dev_err(device, "request_irq failed\n"); + goto fail1; + } + + cf->socket.pci_irq = cf->irq; + + prop = of_get_property(np, "card-detect-gpio", NULL); + if (!prop) + goto fail1; + cf->gpio_detect = *prop; + + prop = of_get_property(np, "card-vsense-gpio", NULL); + if (!prop) + goto fail1; + cf->gpio_vsense = *prop; + + prop = of_get_property(np, "card-3v-gpio", NULL); + if (!prop) + goto fail1; + cf->gpio_3v = *prop; + + prop = of_get_property(np, "card-5v-gpio", NULL); + if (!prop) + goto fail1; + cf->gpio_5v = *prop; + + cf->socket.io_offset = cf->io_base; + + /* reserve chip-select regions */ + if (!request_mem_region(cf->mem_phys, cf->mem_size, driver_name)) { + status = -ENXIO; + dev_err(device, "Can't claim memory region\n"); + goto fail1; + } + + if (!request_region(cf->io_base, cf->io_size, driver_name)) { + status = -ENXIO; + dev_err(device, "Can't claim I/O region\n"); + goto fail2; + } + + cf->socket.owner = THIS_MODULE; + cf->socket.dev.parent = &ofdev->dev; + cf->socket.ops = &electra_cf_ops; + cf->socket.resource_ops = &pccard_static_ops; + cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP | + SS_CAP_MEM_ALIGN; + cf->socket.map_size = 0x800; + + status = pcmcia_register_socket(&cf->socket); + if (status < 0) { + dev_err(device, "pcmcia_register_socket failed\n"); + goto fail3; + } + + dev_info(device, "at mem 0x%lx io 0x%lx irq %d\n", + cf->mem_phys, io.start, cf->irq); + + cf->active = 1; + electra_cf_timer((unsigned long)cf); + return 0; + +fail3: + release_region(cf->io_base, cf->io_size); +fail2: + release_mem_region(cf->mem_phys, cf->mem_size); +fail1: + if (cf->irq != NO_IRQ) + free_irq(cf->irq, cf); + + if (cf->io_virt) + __iounmap_at(cf->io_virt, cf->io_size); + if (cf->mem_base) + iounmap(cf->mem_base); + if (cf->gpio_base) + iounmap(cf->gpio_base); + device_init_wakeup(&ofdev->dev, 0); + kfree(cf); + return status; + +} + +static int __devexit electra_cf_remove(struct of_device *ofdev) +{ + struct device *device = &ofdev->dev; + struct electra_cf_socket *cf; + + cf = dev_get_drvdata(device); + + cf->active = 0; + pcmcia_unregister_socket(&cf->socket); + free_irq(cf->irq, cf); + del_timer_sync(&cf->timer); + + __iounmap_at(cf->io_virt, cf->io_size); + iounmap(cf->mem_base); + iounmap(cf->gpio_base); + release_mem_region(cf->mem_phys, cf->mem_size); + release_region(cf->io_base, cf->io_size); + + kfree(cf); + + return 0; +} + +static struct of_device_id electra_cf_match[] = { + { + .compatible = "electra-cf", + }, + {}, +}; + +static struct of_platform_driver electra_cf_driver = { + .name = (char *)driver_name, + .match_table = electra_cf_match, + .probe = electra_cf_probe, + .remove = electra_cf_remove, +}; + +static int __init electra_cf_init(void) +{ + return of_register_platform_driver(&electra_cf_driver); +} +module_init(electra_cf_init); + +static void __exit electra_cf_exit(void) +{ + of_unregister_platform_driver(&electra_cf_driver); +} +module_exit(electra_cf_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>"); +MODULE_DESCRIPTION("PA Semi Electra CF driver"); diff --git a/drivers/pnp/Makefile b/drivers/pnp/Makefile index a381a92fd1b6..26f5abc9c3f7 100644 --- a/drivers/pnp/Makefile +++ b/drivers/pnp/Makefile @@ -7,3 +7,7 @@ obj-y := core.o card.o driver.o resource.o manager.o support.o interface.o quir obj-$(CONFIG_PNPACPI) += pnpacpi/ obj-$(CONFIG_PNPBIOS) += pnpbios/ obj-$(CONFIG_ISAPNP) += isapnp/ + +ifeq ($(CONFIG_PNP_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index 6c0440c20e31..da1c9909eb44 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -104,10 +104,6 @@ int pnp_add_card_id(struct pnp_id *id, struct pnp_card *card) { struct pnp_id *ptr; - if (!id) - return -EINVAL; - if (!card) - return -EINVAL; id->next = NULL; ptr = card->id; while (ptr && ptr->next) @@ -124,8 +120,6 @@ static void pnp_free_card_ids(struct pnp_card *card) struct pnp_id *id; struct pnp_id *next; - if (!card) - return; id = card->id; while (id) { next = id->next; @@ -197,42 +191,39 @@ int pnp_add_card(struct pnp_card *card) int error; struct list_head *pos, *temp; - if (!card || !card->protocol) - return -EINVAL; - sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number, card->number); card->dev.parent = &card->protocol->dev; card->dev.bus = NULL; card->dev.release = &pnp_release_card; error = device_register(&card->dev); + if (error) { + dev_err(&card->dev, "could not register (err=%d)\n", error); + return error; + } - if (error == 0) { - pnp_interface_attach_card(card); - spin_lock(&pnp_lock); - list_add_tail(&card->global_list, &pnp_cards); - list_add_tail(&card->protocol_list, &card->protocol->cards); - spin_unlock(&pnp_lock); - - /* we wait until now to add devices in order to ensure the drivers - * will be able to use all of the related devices on the card - * without waiting any unresonable length of time */ - list_for_each(pos, &card->devices) { - struct pnp_dev *dev = card_to_pnp_dev(pos); - __pnp_add_device(dev); - } + pnp_interface_attach_card(card); + spin_lock(&pnp_lock); + list_add_tail(&card->global_list, &pnp_cards); + list_add_tail(&card->protocol_list, &card->protocol->cards); + spin_unlock(&pnp_lock); - /* match with card drivers */ - list_for_each_safe(pos, temp, &pnp_card_drivers) { - struct pnp_card_driver *drv = - list_entry(pos, struct pnp_card_driver, - global_list); - card_probe(card, drv); - } - } else - pnp_err("sysfs failure, card '%s' will be unavailable", - card->dev.bus_id); - return error; + /* we wait until now to add devices in order to ensure the drivers + * will be able to use all of the related devices on the card + * without waiting an unreasonable length of time */ + list_for_each(pos, &card->devices) { + struct pnp_dev *dev = card_to_pnp_dev(pos); + __pnp_add_device(dev); + } + + /* match with card drivers */ + list_for_each_safe(pos, temp, &pnp_card_drivers) { + struct pnp_card_driver *drv = + list_entry(pos, struct pnp_card_driver, + global_list); + card_probe(card, drv); + } + return 0; } /** @@ -243,8 +234,6 @@ void pnp_remove_card(struct pnp_card *card) { struct list_head *pos, *temp; - if (!card) - return; device_unregister(&card->dev); spin_lock(&pnp_lock); list_del(&card->global_list); @@ -263,8 +252,6 @@ void pnp_remove_card(struct pnp_card *card) */ int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev) { - if (!card || !dev || !dev->protocol) - return -EINVAL; dev->dev.parent = &card->dev; dev->card_link = NULL; snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%02x:%02x.%02x", @@ -304,14 +291,15 @@ struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, struct pnp_card *card; if (!clink || !id) - goto done; + return NULL; + card = clink->card; drv = clink->driver; if (!from) { pos = card->devices.next; } else { if (from->card != card) - goto done; + return NULL; pos = from->card_list.next; } while (pos != &card->devices) { @@ -321,7 +309,6 @@ struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, pos = pos->next; } -done: return NULL; found: @@ -348,8 +335,6 @@ void pnp_release_card_device(struct pnp_dev *dev) { struct pnp_card_driver *drv = dev->card_link->driver; - if (!drv) - return; drv->link.remove = &card_remove; device_release_driver(&dev->dev); drv->link.remove = &card_remove_first; diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c index d5964feb14de..7d366ca672d3 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c @@ -125,9 +125,11 @@ int __pnp_add_device(struct pnp_dev *dev) spin_unlock(&pnp_lock); ret = device_register(&dev->dev); - if (ret == 0) - pnp_interface_attach_device(dev); - return ret; + if (ret) + return ret; + + pnp_interface_attach_device(dev); + return 0; } /* @@ -138,12 +140,30 @@ int __pnp_add_device(struct pnp_dev *dev) */ int pnp_add_device(struct pnp_dev *dev) { + int ret; + if (dev->card) return -EINVAL; + dev->dev.parent = &dev->protocol->dev; sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number, dev->number); - return __pnp_add_device(dev); + ret = __pnp_add_device(dev); + if (ret) + return ret; + +#ifdef CONFIG_PNP_DEBUG + { + struct pnp_id *id; + + dev_printk(KERN_DEBUG, &dev->dev, "%s device, IDs", + dev->protocol->name); + for (id = dev->id; id; id = id->next) + printk(" %s", id->id); + printk(" (%s)\n", dev->active ? "active" : "disabled"); + } +#endif + return 0; } void __pnp_remove_device(struct pnp_dev *dev) diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index 2fa64a6b25c8..a262762c5b88 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -86,9 +86,6 @@ static int pnp_device_probe(struct device *dev) pnp_dev = to_pnp_dev(dev); pnp_drv = to_pnp_driver(dev->driver); - pnp_dbg("match found with the PnP device '%s' and the driver '%s'", - dev->bus_id, pnp_drv->name); - error = pnp_device_attach(pnp_dev); if (error < 0) return error; @@ -116,6 +113,8 @@ static int pnp_device_probe(struct device *dev) error = 0; } else goto fail; + + dev_dbg(dev, "driver attached\n"); return error; fail: diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index e0ee28a88da3..31548044fdde 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -327,8 +327,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, if (dev->status & PNP_ATTACHED) { retval = -EBUSY; - pnp_info("Device %s cannot be configured because it is in use.", - dev->dev.bus_id); + dev_info(&dev->dev, "in use; can't configure\n"); goto done; } diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index ea3eac2404ca..c6b3d4e63ccc 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -22,8 +22,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) unsigned long *flags; if (idx >= PNP_MAX_PORT) { - pnp_err - ("More than 4 ports is incompatible with pnp specifications."); + dev_err(&dev->dev, "too many I/O port resources\n"); /* pretend we were successful so at least the manager won't try again */ return 1; } @@ -64,8 +63,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) unsigned long *flags; if (idx >= PNP_MAX_MEM) { - pnp_err - ("More than 8 mems is incompatible with pnp specifications."); + dev_err(&dev->dev, "too many memory resources\n"); /* pretend we were successful so at least the manager won't try again */ return 1; } @@ -122,8 +120,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) }; if (idx >= PNP_MAX_IRQ) { - pnp_err - ("More than 2 irqs is incompatible with pnp specifications."); + dev_err(&dev->dev, "too many IRQ resources\n"); /* pretend we were successful so at least the manager won't try again */ return 1; } @@ -161,7 +158,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) return 0; } -static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) +static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) { resource_size_t *start, *end; unsigned long *flags; @@ -173,15 +170,13 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) }; if (idx >= PNP_MAX_DMA) { - pnp_err - ("More than 2 dmas is incompatible with pnp specifications."); - /* pretend we were successful so at least the manager won't try again */ - return 1; + dev_err(&dev->dev, "too many DMA resources\n"); + return; } /* check if this resource has been manually set, if so skip */ if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO)) - return 1; + return; start = &dev->res.dma_resource[idx].start; end = &dev->res.dma_resource[idx].end; @@ -191,19 +186,17 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) *flags |= rule->flags | IORESOURCE_DMA; *flags &= ~IORESOURCE_UNSET; - if (!rule->map) { - *flags |= IORESOURCE_DISABLED; - return 1; /* skip disabled resource requests */ - } - for (i = 0; i < 8; i++) { if (rule->map & (1 << xtab[i])) { *start = *end = xtab[i]; if (pnp_check_dma(dev, idx)) - return 1; + return; } } - return 0; +#ifdef MAX_DMA_CHANNELS + *start = *end = MAX_DMA_CHANNELS; +#endif + *flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; } /** @@ -330,8 +323,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) irq = irq->next; } while (dma) { - if (!pnp_assign_dma(dev, dma, ndma)) - goto fail; + pnp_assign_dma(dev, dma, ndma); ndma++; dma = dma->next; } @@ -367,8 +359,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) irq = irq->next; } while (dma) { - if (!pnp_assign_dma(dev, dma, ndma)) - goto fail; + pnp_assign_dma(dev, dma, ndma); ndma++; dma = dma->next; } @@ -447,8 +438,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev) int i = 1; if (!pnp_can_configure(dev)) { - pnp_dbg("Device %s does not support resource configuration.", - dev->dev.bus_id); + dev_dbg(&dev->dev, "configuration not supported\n"); return -ENODEV; } @@ -465,7 +455,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev) } while (dep); } - pnp_err("Unable to assign resources to device %s.", dev->dev.bus_id); + dev_err(&dev->dev, "unable to assign resources\n"); return -EBUSY; } @@ -478,17 +468,16 @@ int pnp_auto_config_dev(struct pnp_dev *dev) int pnp_start_dev(struct pnp_dev *dev) { if (!pnp_can_write(dev)) { - pnp_dbg("Device %s does not support activation.", - dev->dev.bus_id); + dev_dbg(&dev->dev, "activation not supported\n"); return -EINVAL; } if (dev->protocol->set(dev, &dev->res) < 0) { - pnp_err("Failed to activate device %s.", dev->dev.bus_id); + dev_err(&dev->dev, "activation failed\n"); return -EIO; } - pnp_info("Device %s activated.", dev->dev.bus_id); + dev_info(&dev->dev, "activated\n"); return 0; } @@ -501,16 +490,15 @@ int pnp_start_dev(struct pnp_dev *dev) int pnp_stop_dev(struct pnp_dev *dev) { if (!pnp_can_disable(dev)) { - pnp_dbg("Device %s does not support disabling.", - dev->dev.bus_id); + dev_dbg(&dev->dev, "disabling not supported\n"); return -EINVAL; } if (dev->protocol->disable(dev) < 0) { - pnp_err("Failed to disable device %s.", dev->dev.bus_id); + dev_err(&dev->dev, "disable failed\n"); return -EIO; } - pnp_info("Device %s disabled.", dev->dev.bus_id); + dev_info(&dev->dev, "disabled\n"); return 0; } diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index a5a372222d69..dada89906314 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -130,11 +130,16 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) #ifdef CONFIG_ACPI_SLEEP static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) { - return acpi_bus_set_power((acpi_handle) dev->data, - acpi_pm_device_sleep_state(&dev->dev, - device_may_wakeup - (&dev->dev), - NULL)); + int power_state; + + power_state = acpi_pm_device_sleep_state(&dev->dev, + device_may_wakeup(&dev->dev), + NULL); + if (power_state < 0) + power_state = (state.event == PM_EVENT_ON) ? + ACPI_STATE_D0 : ACPI_STATE_D3; + + return acpi_bus_set_power((acpi_handle) dev->data, power_state); } static int pnpacpi_resume(struct pnp_dev *dev) @@ -166,7 +171,6 @@ static int __init pnpacpi_add_device(struct acpi_device *device) is_exclusive_device(device)) return 0; - pnp_dbg("ACPI device : hid %s", acpi_device_hid(device)); dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL); if (!dev) { pnp_err("Out of memory"); diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 0e3b8d0ff06b..cd0a204d96d1 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -85,6 +85,16 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, if (i >= PNP_MAX_IRQ) return; +#ifdef CONFIG_X86 + if (gsi < 16 && (triggering != ACPI_EDGE_SENSITIVE || + polarity != ACPI_ACTIVE_HIGH)) { + pnp_warn("BIOS BUG: legacy PNP IRQ %d should be edge trigger, " + "active high", gsi); + triggering = ACPI_EDGE_SENSITIVE; + polarity = ACPI_ACTIVE_HIGH; + } +#endif + res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag res->irq_resource[i].flags |= irq_flags(triggering, polarity); irq = acpi_register_gsi(gsi, triggering, polarity); diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index 4e9fd37cff35..e33e03f71084 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c @@ -315,25 +315,31 @@ struct pnp_protocol pnpbios_protocol = { .disable = pnpbios_disable_resources, }; -static int insert_device(struct pnp_dev *dev, struct pnp_bios_node *node) +static int insert_device(struct pnp_bios_node *node) { struct list_head *pos; - struct pnp_dev *pnp_dev; + struct pnp_dev *dev; struct pnp_id *dev_id; char id[8]; /* check if the device is already added */ - dev->number = node->handle; list_for_each(pos, &pnpbios_protocol.devices) { - pnp_dev = list_entry(pos, struct pnp_dev, protocol_list); - if (dev->number == pnp_dev->number) + dev = list_entry(pos, struct pnp_dev, protocol_list); + if (dev->number == node->handle) return -1; } - /* set the initial values for the PnP device */ + dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL); + if (!dev) + return -1; + dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); - if (!dev_id) + if (!dev_id) { + kfree(dev); return -1; + } + + dev->number = node->handle; pnpid32_to_pnpid(node->eisa_id, id); memcpy(dev_id->id, id, 7); pnp_add_id(dev_id, dev); @@ -367,7 +373,6 @@ static void __init build_devlist(void) unsigned int nodes_got = 0; unsigned int devs = 0; struct pnp_bios_node *node; - struct pnp_dev *dev; node = kzalloc(node_info.max_node_size, GFP_KERNEL); if (!node) @@ -388,12 +393,7 @@ static void __init build_devlist(void) break; } nodes_got++; - dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL); - if (!dev) - break; - if (insert_device(dev, node) < 0) - kfree(dev); - else + if (insert_device(node) == 0) devs++; if (nodenum <= thisnodenum) { printk(KERN_ERR diff --git a/drivers/pnp/pnpbios/proc.c b/drivers/pnp/pnpbios/proc.c index 9d9841f24a85..bb19bc957bad 100644 --- a/drivers/pnp/pnpbios/proc.c +++ b/drivers/pnp/pnpbios/proc.c @@ -94,8 +94,9 @@ static int proc_read_escd(char *buf, char **start, off_t pos, /* sanity check */ if (escd_size > MAX_SANE_ESCD_SIZE) { - printk(KERN_ERR - "PnPBIOS: proc_read_escd: ESCD size reported by BIOS read_escd call is too great\n"); + printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size reported by" + " BIOS read_escd call is too great\n"); + kfree(tmpbuf); return -EFBIG; } diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 6b0cf0c2a088..e903b8c2b1fa 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -17,6 +17,7 @@ #include <linux/slab.h> #include <linux/pnp.h> #include <linux/io.h> +#include <linux/kallsyms.h> #include "base.h" static void quirk_awe32_resources(struct pnp_dev *dev) @@ -133,11 +134,18 @@ static struct pnp_fixup pnp_fixups[] = { void pnp_fixup_device(struct pnp_dev *dev) { int i = 0; + void (*quirk)(struct pnp_dev *); while (*pnp_fixups[i].id) { if (compare_pnp_id(dev->id, pnp_fixups[i].id)) { - pnp_dbg("Calling quirk for %s", dev->dev.bus_id); - pnp_fixups[i].quirk_function(dev); + quirk = pnp_fixups[i].quirk_function; + +#ifdef DEBUG + dev_dbg(&dev->dev, "calling quirk 0x%p", quirk); + print_fn_descriptor_symbol(": %s()\n", + (unsigned long) *quirk); +#endif + (*quirk)(dev); } i++; } diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 087fed18628f..41d73a5e9312 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -51,7 +51,7 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev) /* this should never happen but if it does we'll try to continue */ if (dev->independent) - pnp_err("independent resource already registered"); + dev_err(&dev->dev, "independent resource already registered\n"); dev->independent = option; return option; } diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c index a06f980b3ac9..55c4563986b3 100644 --- a/drivers/pnp/system.c +++ b/drivers/pnp/system.c @@ -22,36 +22,39 @@ static const struct pnp_device_id pnp_dev_table[] = { {"", 0} }; -static void reserve_range(const char *pnpid, resource_size_t start, +static void reserve_range(struct pnp_dev *dev, resource_size_t start, resource_size_t end, int port) { - struct resource *res; char *regionid; + const char *pnpid = dev->dev.bus_id; + struct resource *res; regionid = kmalloc(16, GFP_KERNEL); - if (regionid == NULL) + if (!regionid) return; + snprintf(regionid, 16, "pnp %s", pnpid); if (port) res = request_region(start, end - start + 1, regionid); else res = request_mem_region(start, end - start + 1, regionid); - if (res == NULL) - kfree(regionid); - else + if (res) res->flags &= ~IORESOURCE_BUSY; + else + kfree(regionid); + /* * Failures at this point are usually harmless. pci quirks for * example do reserve stuff they know about too, so we may well * have double reservations. */ - printk(KERN_INFO "pnp: %s: %s range 0x%llx-0x%llx %s reserved\n", - pnpid, port ? "ioport" : "iomem", - (unsigned long long)start, (unsigned long long)end, - NULL != res ? "has been" : "could not be"); + dev_info(&dev->dev, "%s range 0x%llx-0x%llx %s reserved\n", + port ? "ioport" : "iomem", + (unsigned long long) start, (unsigned long long) end, + res ? "has been" : "could not be"); } -static void reserve_resources_of_dev(const struct pnp_dev *dev) +static void reserve_resources_of_dev(struct pnp_dev *dev) { int i; @@ -73,7 +76,7 @@ static void reserve_resources_of_dev(const struct pnp_dev *dev) if (pnp_port_end(dev, i) < pnp_port_start(dev, i)) continue; /* invalid */ - reserve_range(dev->dev.bus_id, pnp_port_start(dev, i), + reserve_range(dev, pnp_port_start(dev, i), pnp_port_end(dev, i), 1); } @@ -81,7 +84,7 @@ static void reserve_resources_of_dev(const struct pnp_dev *dev) if (!pnp_mem_valid(dev, i)) continue; - reserve_range(dev->dev.bus_id, pnp_mem_start(dev, i), + reserve_range(dev, pnp_mem_start(dev, i), pnp_mem_end(dev, i), 0); } } diff --git a/drivers/s390/char/defkeymap.c b/drivers/s390/char/defkeymap.c index 564baca01b7c..389346cda6c8 100644 --- a/drivers/s390/char/defkeymap.c +++ b/drivers/s390/char/defkeymap.c @@ -150,7 +150,7 @@ char *func_table[MAX_NR_FUNC] = { NULL, }; -struct kbdiacr accent_table[MAX_DIACR] = { +struct kbdiacruc accent_table[MAX_DIACR] = { {'^', 'c', '\003'}, {'^', 'd', '\004'}, {'^', 'z', '\032'}, {'^', '\012', '\000'}, }; diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index f62f9a4e8950..cee4d4e42429 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -11,6 +11,7 @@ #include <linux/sched.h> #include <linux/sysrq.h> +#include <linux/consolemap.h> #include <linux/kbd_kern.h> #include <linux/kbd_diacr.h> #include <asm/uaccess.h> @@ -82,11 +83,11 @@ kbd_alloc(void) { if (!kbd->fn_handler) goto out_func; kbd->accent_table = - kmalloc(sizeof(struct kbdiacr)*MAX_DIACR, GFP_KERNEL); + kmalloc(sizeof(struct kbdiacruc)*MAX_DIACR, GFP_KERNEL); if (!kbd->accent_table) goto out_fn_handler; memcpy(kbd->accent_table, accent_table, - sizeof(struct kbdiacr)*MAX_DIACR); + sizeof(struct kbdiacruc)*MAX_DIACR); kbd->accent_table_size = accent_table_size; return kbd; @@ -183,8 +184,8 @@ kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc) * Otherwise, conclude that DIACR was not combining after all, * queue it and return CH. */ -static unsigned char -handle_diacr(struct kbd_data *kbd, unsigned char ch) +static unsigned int +handle_diacr(struct kbd_data *kbd, unsigned int ch) { int i, d; @@ -460,7 +461,6 @@ int kbd_ioctl(struct kbd_data *kbd, struct file *file, unsigned int cmd, unsigned long arg) { - struct kbdiacrs __user *a; void __user *argp; int ct, perm; @@ -481,17 +481,40 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file, case KDSKBSENT: return do_kdgkb_ioctl(kbd, argp, cmd, perm); case KDGKBDIACR: - a = argp; + { + struct kbdiacrs __user *a = argp; + struct kbdiacr diacr; + int i; if (put_user(kbd->accent_table_size, &a->kb_cnt)) return -EFAULT; + for (i = 0; i < kbd->accent_table_size; i++) { + diacr.diacr = kbd->accent_table[i].diacr; + diacr.base = kbd->accent_table[i].base; + diacr.result = kbd->accent_table[i].result; + if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) + return -EFAULT; + } + return 0; + } + case KDGKBDIACRUC: + { + struct kbdiacrsuc __user *a = argp; + ct = kbd->accent_table_size; - if (copy_to_user(a->kbdiacr, kbd->accent_table, - ct * sizeof(struct kbdiacr))) + if (put_user(ct, &a->kb_cnt)) + return -EFAULT; + if (copy_to_user(a->kbdiacruc, kbd->accent_table, + ct * sizeof(struct kbdiacruc))) return -EFAULT; return 0; + } case KDSKBDIACR: - a = argp; + { + struct kbdiacrs __user *a = argp; + struct kbdiacr diacr; + int i; + if (!perm) return -EPERM; if (get_user(ct, &a->kb_cnt)) @@ -499,10 +522,31 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file, if (ct >= MAX_DIACR) return -EINVAL; kbd->accent_table_size = ct; - if (copy_from_user(kbd->accent_table, a->kbdiacr, - ct * sizeof(struct kbdiacr))) + for (i = 0; i < ct; i++) { + if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) + return -EFAULT; + kbd->accent_table[i].diacr = diacr.diacr; + kbd->accent_table[i].base = diacr.base; + kbd->accent_table[i].result = diacr.result; + } + return 0; + } + case KDSKBDIACRUC: + { + struct kbdiacrsuc __user *a = argp; + + if (!perm) + return -EPERM; + if (get_user(ct, &a->kb_cnt)) + return -EFAULT; + if (ct >= MAX_DIACR) + return -EINVAL; + kbd->accent_table_size = ct; + if (copy_from_user(kbd->accent_table, a->kbdiacruc, + ct * sizeof(struct kbdiacruc))) return -EFAULT; return 0; + } default: return -ENOIOCTLCMD; } diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h index f7bf45c6bf0d..5ccfe9cf126d 100644 --- a/drivers/s390/char/keyboard.h +++ b/drivers/s390/char/keyboard.h @@ -25,9 +25,9 @@ struct kbd_data { unsigned short **key_maps; char **func_table; fn_handler_fn **fn_handler; - struct kbdiacr *accent_table; + struct kbdiacruc *accent_table; unsigned int accent_table_size; - unsigned char diacr; + unsigned int diacr; unsigned short sysrq; }; diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index 281f23a371b2..94ec66372508 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c @@ -500,13 +500,11 @@ void jsm_input(struct jsm_channel *ch) { struct jsm_board *bd; struct tty_struct *tp; - struct tty_ldisc *ld; u32 rmask; u16 head; u16 tail; int data_len; unsigned long lock_flags; - int flip_len = 0; int len = 0; int n = 0; int s = 0; @@ -574,45 +572,13 @@ void jsm_input(struct jsm_channel *ch) jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start 2\n"); - /* - * If the rxbuf is empty and we are not throttled, put as much - * as we can directly into the linux TTY buffer. - * - */ - flip_len = TTY_FLIPBUF_SIZE; - - len = min(data_len, flip_len); - len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); - ld = tty_ldisc_ref(tp); - - /* - * If we were unable to get a reference to the ld, - * don't flush our buffer, and act like the ld doesn't - * have any space to put the data right now. - */ - if (!ld) { - len = 0; - } else { - /* - * If ld doesn't have a pointer to a receive_buf function, - * flush the data, then act like the ld doesn't have any - * space to put the data right now. - */ - if (!ld->receive_buf) { - ch->ch_r_head = ch->ch_r_tail; - len = 0; - } - } - - if (len <= 0) { + if (data_len <= 0) { spin_unlock_irqrestore(&ch->ch_lock, lock_flags); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n"); - if (ld) - tty_ldisc_deref(ld); return; } - len = tty_buffer_request_room(tp, len); + len = tty_buffer_request_room(tp, data_len); n = len; /* @@ -647,7 +613,7 @@ void jsm_input(struct jsm_channel *ch) else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE) tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_FRAME); else - tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL); + tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL); } } else { tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ; @@ -666,9 +632,6 @@ void jsm_input(struct jsm_channel *ch) /* Tell the tty layer its okay to "eat" the data now */ tty_flip_buffer_push(tp); - if (ld) - tty_ldisc_deref(ld); - jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); } diff --git a/drivers/tc/.gitignore b/drivers/tc/.gitignore deleted file mode 100644 index acc0e1e6a650..000000000000 --- a/drivers/tc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -lk201-map.c diff --git a/drivers/tc/Makefile b/drivers/tc/Makefile index c899246bd362..623b21063228 100644 --- a/drivers/tc/Makefile +++ b/drivers/tc/Makefile @@ -5,18 +5,3 @@ # Object file lists. obj-$(CONFIG_TC) += tc.o tc-driver.o -obj-$(CONFIG_VT) += lk201.o lk201-map.o lk201-remap.o - -$(obj)/lk201-map.o: $(obj)/lk201-map.c - -# Uncomment if you're changing the keymap and have an appropriate -# loadkeys version for the map. By default, we'll use the shipped -# versions. -# GENERATE_KEYMAP := 1 - -ifdef GENERATE_KEYMAP - -$(obj)/lk201-map.c: $(obj)/%.c: $(src)/%.map - loadkeys --mktable $< > $@ - -endif diff --git a/drivers/tc/lk201-map.c_shipped b/drivers/tc/lk201-map.c_shipped deleted file mode 100644 index a9df8f5bf62b..000000000000 --- a/drivers/tc/lk201-map.c_shipped +++ /dev/null @@ -1,265 +0,0 @@ - -/* Do not edit this file! It was automatically generated by */ -/* loadkeys --mktable defkeymap.map > defkeymap.c */ - -#include <linux/types.h> -#include <linux/keyboard.h> -#include <linux/kd.h> - -u_short plain_map[NR_KEYS] = { - 0xf200, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, - 0xf107, 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf11b, - 0xf11c, 0xf110, 0xf111, 0xf112, 0xf113, 0xf060, 0xf031, 0xf032, - 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, 0xf038, 0xf039, 0xf030, - 0xf02d, 0xf03d, 0xf07f, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf009, 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, - 0xfb79, 0xfb75, 0xfb69, 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, - 0xf117, 0xf118, 0xf119, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf702, - 0xf207, 0xfb61, 0xfb73, 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, - 0xfb6b, 0xfb6c, 0xf03b, 0xf027, 0xf05c, 0xf603, 0xf304, 0xf305, - 0xf306, 0xf200, 0xf700, 0xf03e, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, - 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf200, 0xf601, - 0xf600, 0xf602, 0xf301, 0xf302, 0xf303, 0xf30e, 0xf200, 0xf703, - 0xf020, 0xf200, 0xf200, 0xf300, 0xf310, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short shift_map[NR_KEYS] = { - 0xf200, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, - 0xf107, 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf203, - 0xf11c, 0xf110, 0xf111, 0xf112, 0xf113, 0xf07e, 0xf021, 0xf040, - 0xf023, 0xf024, 0xf025, 0xf05e, 0xf026, 0xf02a, 0xf028, 0xf029, - 0xf05f, 0xf02b, 0xf07f, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf009, 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, - 0xfb59, 0xfb55, 0xfb49, 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, - 0xf117, 0xf20b, 0xf20a, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf702, - 0xf207, 0xfb41, 0xfb53, 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, - 0xfb4b, 0xfb4c, 0xf03a, 0xf022, 0xf07c, 0xf603, 0xf304, 0xf305, - 0xf306, 0xf200, 0xf700, 0xf03c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, - 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf200, 0xf601, - 0xf600, 0xf602, 0xf301, 0xf302, 0xf303, 0xf30e, 0xf200, 0xf703, - 0xf020, 0xf200, 0xf200, 0xf300, 0xf310, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short altgr_map[NR_KEYS] = { - 0xf200, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, - 0xf107, 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf202, - 0xf11c, 0xf110, 0xf111, 0xf112, 0xf113, 0xf200, 0xf200, 0xf040, - 0xf200, 0xf024, 0xf200, 0xf200, 0xf07b, 0xf05b, 0xf05d, 0xf07d, - 0xf05c, 0xf200, 0xf200, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, - 0xfb79, 0xfb75, 0xfb69, 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, - 0xf117, 0xf118, 0xf119, 0xf911, 0xf912, 0xf913, 0xf30b, 0xf702, - 0xf207, 0xf914, 0xfb73, 0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, - 0xfb6b, 0xfb6c, 0xf200, 0xf200, 0xf200, 0xf603, 0xf90e, 0xf90f, - 0xf910, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76, - 0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf601, - 0xf600, 0xf602, 0xf90b, 0xf90c, 0xf90d, 0xf30e, 0xf200, 0xf703, - 0xf200, 0xf200, 0xf200, 0xf90a, 0xf310, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short ctrl_map[NR_KEYS] = { - 0xf200, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, - 0xf107, 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf204, - 0xf11c, 0xf110, 0xf111, 0xf112, 0xf113, 0xf81b, 0xf200, 0xf000, - 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, 0xf07f, 0xf200, 0xf200, - 0xf01f, 0xf200, 0xf008, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, - 0xf019, 0xf015, 0xf009, 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, - 0xf117, 0xf118, 0xf119, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf702, - 0xf207, 0xf001, 0xf013, 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, - 0xf00b, 0xf00c, 0xf200, 0xf007, 0xf01c, 0xf603, 0xf304, 0xf305, - 0xf306, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, - 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf200, 0xf601, - 0xf600, 0xf602, 0xf301, 0xf302, 0xf303, 0xf30e, 0xf200, 0xf703, - 0xf000, 0xf200, 0xf200, 0xf300, 0xf310, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short shift_ctrl_map[NR_KEYS] = { - 0xf200, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, - 0xf107, 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf200, - 0xf11c, 0xf110, 0xf111, 0xf112, 0xf113, 0xf200, 0xf200, 0xf000, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf01f, 0xf200, 0xf200, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, - 0xf019, 0xf015, 0xf009, 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, - 0xf117, 0xf118, 0xf119, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf702, - 0xf207, 0xf001, 0xf013, 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, - 0xf00b, 0xf00c, 0xf200, 0xf200, 0xf200, 0xf603, 0xf304, 0xf305, - 0xf306, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, - 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf601, - 0xf600, 0xf602, 0xf301, 0xf302, 0xf303, 0xf30e, 0xf200, 0xf703, - 0xf200, 0xf200, 0xf200, 0xf300, 0xf310, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short alt_map[NR_KEYS] = { - 0xf200, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, 0xf505, 0xf506, - 0xf507, 0xf508, 0xf509, 0xf50a, 0xf50b, 0xf50c, 0xf50d, 0xf200, - 0xf11c, 0xf510, 0xf511, 0xf512, 0xf513, 0xf01b, 0xf831, 0xf832, - 0xf833, 0xf834, 0xf835, 0xf836, 0xf837, 0xf838, 0xf839, 0xf830, - 0xf82d, 0xf83d, 0xf87f, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf809, 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, - 0xf879, 0xf875, 0xf869, 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, - 0xf117, 0xf118, 0xf119, 0xf907, 0xf908, 0xf909, 0xf30b, 0xf702, - 0xf207, 0xf861, 0xf873, 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, - 0xf86b, 0xf86c, 0xf83b, 0xf827, 0xf85c, 0xf603, 0xf904, 0xf905, - 0xf906, 0xf200, 0xf700, 0xf200, 0xf87a, 0xf878, 0xf863, 0xf876, - 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf200, 0xf210, - 0xf600, 0xf211, 0xf901, 0xf902, 0xf903, 0xf30e, 0xf200, 0xf703, - 0xf820, 0xf200, 0xf200, 0xf900, 0xf310, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short ctrl_alt_map[NR_KEYS] = { - 0xf200, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, 0xf505, 0xf506, - 0xf507, 0xf508, 0xf509, 0xf50a, 0xf50b, 0xf50c, 0xf50d, 0xf200, - 0xf11c, 0xf510, 0xf511, 0xf512, 0xf513, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf114, 0xf115, 0xf20c, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, - 0xf819, 0xf815, 0xf809, 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, - 0xf117, 0xf118, 0xf119, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf702, - 0xf207, 0xf801, 0xf813, 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, - 0xf80b, 0xf80c, 0xf200, 0xf200, 0xf200, 0xf603, 0xf304, 0xf305, - 0xf306, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816, - 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf601, - 0xf600, 0xf602, 0xf301, 0xf302, 0xf303, 0xf30e, 0xf200, 0xf703, - 0xf200, 0xf200, 0xf200, 0xf300, 0xf20c, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -ushort *key_maps[MAX_NR_KEYMAPS] = { - plain_map, shift_map, altgr_map, 0, - ctrl_map, shift_ctrl_map, 0, 0, - alt_map, 0, 0, 0, - ctrl_alt_map, 0 -}; - -unsigned int keymap_count = 7; - - -/* - * Philosophy: most people do not define more strings, but they who do - * often want quite a lot of string space. So, we statically allocate - * the default and allocate dynamically in chunks of 512 bytes. - */ - -char func_buf[] = { - '\033', '[', '[', 'A', 0, - '\033', '[', '[', 'B', 0, - '\033', '[', '[', 'C', 0, - '\033', '[', '[', 'D', 0, - '\033', '[', '[', 'E', 0, - '\033', '[', '1', '7', '~', 0, - '\033', '[', '1', '8', '~', 0, - '\033', '[', '1', '9', '~', 0, - '\033', '[', '2', '0', '~', 0, - '\033', '[', '2', '1', '~', 0, - '\033', '[', '2', '3', '~', 0, - '\033', '[', '2', '4', '~', 0, - '\033', '[', '2', '5', '~', 0, - '\033', '[', '2', '6', '~', 0, - '\033', '[', '2', '8', '~', 0, - '\033', '[', '2', '9', '~', 0, - '\033', '[', '3', '1', '~', 0, - '\033', '[', '3', '2', '~', 0, - '\033', '[', '3', '3', '~', 0, - '\033', '[', '3', '4', '~', 0, - '\033', '[', '1', '~', 0, - '\033', '[', '2', '~', 0, - '\033', '[', '3', '~', 0, - '\033', '[', '4', '~', 0, - '\033', '[', '5', '~', 0, - '\033', '[', '6', '~', 0, - '\033', '[', 'M', 0, - '\033', '[', 'P', 0, -}; - - -char *funcbufptr = func_buf; -int funcbufsize = sizeof(func_buf); -int funcbufleft = 0; /* space left */ - -char *func_table[MAX_NR_FUNC] = { - func_buf + 0, - func_buf + 5, - func_buf + 10, - func_buf + 15, - func_buf + 20, - func_buf + 25, - func_buf + 31, - func_buf + 37, - func_buf + 43, - func_buf + 49, - func_buf + 55, - func_buf + 61, - func_buf + 67, - func_buf + 73, - func_buf + 79, - func_buf + 85, - func_buf + 91, - func_buf + 97, - func_buf + 103, - func_buf + 109, - func_buf + 115, - func_buf + 120, - func_buf + 125, - func_buf + 130, - func_buf + 135, - func_buf + 140, - func_buf + 145, - 0, - 0, - func_buf + 149, - 0, -}; - -struct kbdiacr accent_table[MAX_DIACR] = { - {'`', 'A', 'À'}, {'`', 'a', 'à'}, - {'\'', 'A', 'Á'}, {'\'', 'a', 'á'}, - {'^', 'A', 'Â'}, {'^', 'a', 'â'}, - {'~', 'A', 'Ã'}, {'~', 'a', 'ã'}, - {'"', 'A', 'Ä'}, {'"', 'a', 'ä'}, - {'O', 'A', 'Å'}, {'o', 'a', 'å'}, - {'0', 'A', 'Å'}, {'0', 'a', 'å'}, - {'A', 'A', 'Å'}, {'a', 'a', 'å'}, - {'A', 'E', 'Æ'}, {'a', 'e', 'æ'}, - {',', 'C', 'Ç'}, {',', 'c', 'ç'}, - {'`', 'E', 'È'}, {'`', 'e', 'è'}, - {'\'', 'E', 'É'}, {'\'', 'e', 'é'}, - {'^', 'E', 'Ê'}, {'^', 'e', 'ê'}, - {'"', 'E', 'Ë'}, {'"', 'e', 'ë'}, - {'`', 'I', 'Ì'}, {'`', 'i', 'ì'}, - {'\'', 'I', 'Í'}, {'\'', 'i', 'í'}, - {'^', 'I', 'Î'}, {'^', 'i', 'î'}, - {'"', 'I', 'Ï'}, {'"', 'i', 'ï'}, - {'-', 'D', 'Ð'}, {'-', 'd', 'ð'}, - {'~', 'N', 'Ñ'}, {'~', 'n', 'ñ'}, - {'`', 'O', 'Ò'}, {'`', 'o', 'ò'}, - {'\'', 'O', 'Ó'}, {'\'', 'o', 'ó'}, - {'^', 'O', 'Ô'}, {'^', 'o', 'ô'}, - {'~', 'O', 'Õ'}, {'~', 'o', 'õ'}, - {'"', 'O', 'Ö'}, {'"', 'o', 'ö'}, - {'/', 'O', 'Ø'}, {'/', 'o', 'ø'}, - {'`', 'U', 'Ù'}, {'`', 'u', 'ù'}, - {'\'', 'U', 'Ú'}, {'\'', 'u', 'ú'}, - {'^', 'U', 'Û'}, {'^', 'u', 'û'}, - {'"', 'U', 'Ü'}, {'"', 'u', 'ü'}, - {'\'', 'Y', 'Ý'}, {'\'', 'y', 'ý'}, - {'T', 'H', 'Þ'}, {'t', 'h', 'þ'}, - {'s', 's', 'ß'}, {'"', 'y', 'ÿ'}, - {'s', 'z', 'ß'}, {'i', 'j', 'ÿ'}, -}; - -unsigned int accent_table_size = 68; diff --git a/drivers/tc/lk201-map.map b/drivers/tc/lk201-map.map deleted file mode 100644 index 2c636b4b7823..000000000000 --- a/drivers/tc/lk201-map.map +++ /dev/null @@ -1,356 +0,0 @@ -# Default kernel keymap. This uses 7 modifier combinations. -keymaps 0-2,4-5,8,12 -# Change the above line into -# keymaps 0-2,4-6,8,12 -# in case you want the entries -# altgr control keycode 83 = Boot -# altgr control keycode 111 = Boot -# below. -# -# In fact AltGr is used very little, and one more keymap can -# be saved by mapping AltGr to Alt (and adapting a few entries): -# keycode 100 = Alt -# -keycode 0x15 = grave tilde - alt keycode 0x15 = Escape - control keycode 0x15 = Meta_Escape -keycode 0x16 = one exclam - alt keycode 0x16 = Meta_one -keycode 0x17 = two at at - control keycode 0x17 = nul - shift control keycode 0x17 = nul - alt keycode 0x17 = Meta_two -keycode 0x18 = three numbersign - control keycode 0x18 = Escape - alt keycode 0x18 = Meta_three -keycode 0x19 = four dollar dollar - control keycode 0x19 = Control_backslash - alt keycode 0x19 = Meta_four -keycode 0x1a = five percent - control keycode 0x1a = Control_bracketright - alt keycode 0x1a = Meta_five -keycode 0x1b = six asciicircum - control keycode 0x1b = Control_asciicircum - alt keycode 0x1b = Meta_six -keycode 0x1c = seven ampersand braceleft - control keycode 0x1c = Control_underscore - alt keycode 0x1c = Meta_seven -keycode 0x1d = eight asterisk bracketleft - control keycode 0x1d = Delete - alt keycode 0x1d = Meta_eight -keycode 0x1e = nine parenleft bracketright - alt keycode 0x1e = Meta_nine -keycode 0x1f = zero parenright braceright - alt keycode 0x1f = Meta_zero -keycode 0x20 = minus underscore backslash - control keycode 0x20 = Control_underscore - shift control keycode 0x20 = Control_underscore - alt keycode 0x20 = Meta_minus -keycode 0x21 = equal plus - alt keycode 0x21 = Meta_equal -keycode 0x22 = Delete Delete - control keycode 0x22 = BackSpace - alt keycode 0x22 = Meta_Delete -keycode 0x2a = Tab Tab - alt keycode 0x2a = Meta_Tab -keycode 0x2b = q -keycode 0x2c = w -keycode 0x2d = e - altgr keycode 0x2d = Hex_E -keycode 0x2e = r -keycode 0x2f = t -keycode 0x30 = y -keycode 0x31 = u -keycode 0x32 = i -keycode 0x33 = o -keycode 0x34 = p -keycode 0x35 = bracketleft braceleft - control keycode 0x35 = Escape - alt keycode 0x35 = Meta_bracketleft -keycode 0x36 = bracketright braceright asciitilde - control keycode 0x36 = Control_bracketright - alt keycode 0x36 = Meta_bracketright -keycode 0x37 = Return - alt keycode 0x37 = Meta_Control_m -keycode 0x3f = Control -keycode 0x41 = a - altgr keycode 0x41 = Hex_A -keycode 0x42 = s -keycode 0x43 = d - altgr keycode 0x43 = Hex_D -keycode 0x44 = f - altgr keycode 0x44 = Hex_F -keycode 0x45 = g -keycode 0x46 = h -keycode 0x47 = j -keycode 0x48 = k -keycode 0x49 = l -keycode 0x4a = semicolon colon - alt keycode 0x4a = Meta_semicolon -keycode 0x4b = apostrophe quotedbl - control keycode 0x4b = Control_g - alt keycode 0x4b = Meta_apostrophe -# keycode 41 = grave asciitilde -# control keycode 41 = nul -# alt keycode 41 = Meta_grave -keycode 0x52 = Shift -keycode 0x4c = backslash bar - control keycode 0x4c = Control_backslash - alt keycode 0x4c = Meta_backslash -keycode 0x53 = greater less -keycode 0x54 = z -keycode 0x55 = x -keycode 0x56 = c - altgr keycode 0x56 = Hex_C -keycode 0x57 = v -keycode 0x58 = b - altgr keycode 0x58 = Hex_B -keycode 0x59 = n -keycode 0x5a = m -keycode 0x5b = comma less - alt keycode 0x5b = Meta_comma -keycode 0x5c = period greater - control keycode 0x5c = Compose - alt keycode 0x5c = Meta_period -keycode 0x5d = slash question - control keycode 0x5d = Delete - alt keycode 0x5d = Meta_slash - -keycode 0x67 = Alt -keycode 0x68 = space space - control keycode 0x68 = nul - alt keycode 0x68 = Meta_space -keycode 0x40 = Caps_Lock -keycode 0x01 = F1 - control keycode 0x01 = F1 - alt keycode 0x01 = Console_1 - control alt keycode 0x01 = Console_1 -keycode 0x02 = F2 - control keycode 0x02 = F2 - alt keycode 0x02 = Console_2 - control alt keycode 0x02 = Console_2 -keycode 0x03 = F3 - control keycode 0x03 = F3 - alt keycode 0x03 = Console_3 - control alt keycode 0x03 = Console_3 -keycode 0x04 = F4 - control keycode 0x04 = F4 - alt keycode 0x04 = Console_4 - control alt keycode 0x04 = Console_4 -keycode 0x05 = F5 - control keycode 0x05 = F5 - alt keycode 0x05 = Console_5 - control alt keycode 0x05 = Console_5 -keycode 0x06 = F6 - control keycode 0x06 = F6 - alt keycode 0x06 = Console_6 - control alt keycode 0x06 = Console_6 -keycode 0x07 = F7 - control keycode 0x07 = F7 - alt keycode 0x07 = Console_7 - control alt keycode 0x07 = Console_7 -keycode 0x08 = F8 - control keycode 0x08 = F8 - alt keycode 0x08 = Console_8 - control alt keycode 0x08 = Console_8 -keycode 0x09 = F9 - control keycode 0x09 = F9 - alt keycode 0x09 = Console_9 - control alt keycode 0x09 = Console_9 -keycode 0x0a = F10 - control keycode 0x0a = F10 - alt keycode 0x0a = Console_10 - control alt keycode 0x0a = Console_10 -keycode 0x0b = F11 - control keycode 0x0b = F11 - alt keycode 0x0b = Console_11 - control alt keycode 0x0b = Console_11 -keycode 0x0c = F12 - control keycode 0x0c = F12 - alt keycode 0x0c = Console_12 - control alt keycode 0x0c = Console_12 -keycode 0x0d = F13 - control keycode 0x0d = F13 - alt keycode 0x0d = Console_13 - control alt keycode 0x0d = Console_13 -keycode 0x0e = F14 - control keycode 0x0e = F14 - alt keycode 0x0e = Console_14 - control alt keycode 0x0e = Console_14 - -keycode 0x11 = F17 - control keycode 0x11 = F17 - alt keycode 0x11 = Console_17 - control alt keycode 0x11 = Console_17 -keycode 0x12 = F18 - control keycode 0x12 = F18 - alt keycode 0x12 = Console_18 - control alt keycode 0x12 = Console_18 -keycode 0x13 = F19 - control keycode 0x13 = F19 - alt keycode 0x13 = Console_19 - control alt keycode 0x13 = Console_19 -keycode 0x14 = F20 - control keycode 0x14 = F20 - alt keycode 0x14 = Console_20 - control alt keycode 0x14 = Console_20 - - -keycode 0x3b = KP_7 - alt keycode 0x3b = Ascii_7 - altgr keycode 0x3b = Hex_7 -keycode 0x3c = KP_8 - alt keycode 0x3c = Ascii_8 - altgr keycode 0x3c = Hex_8 -keycode 0x3d = KP_9 - alt keycode 0x3d = Ascii_9 - altgr keycode 0x3d = Hex_9 -keycode 0x3e = KP_Subtract -keycode 0x4e = KP_4 - alt keycode 0x4e = Ascii_4 - altgr keycode 0x4e = Hex_4 -keycode 0x4f = KP_5 - alt keycode 0x4f = Ascii_5 - altgr keycode 0x4f = Hex_5 -keycode 0x50 = KP_6 - alt keycode 0x50 = Ascii_6 - altgr keycode 0x50 = Hex_6 -keycode 0x62 = KP_1 - alt keycode 0x62 = Ascii_1 - altgr keycode 0x62 = Hex_1 -keycode 0x63 = KP_2 - alt keycode 0x63 = Ascii_2 - altgr keycode 0x63 = Hex_2 -keycode 0x64 = KP_3 - alt keycode 0x64 = Ascii_3 - altgr keycode 0x64 = Hex_3 -keycode 0x6b = KP_0 - alt keycode 0x6b = Ascii_0 - altgr keycode 0x6b = Hex_0 -keycode 0x6c = KP_Period -# altgr control keycode 0x6c = Boot - control alt keycode 0x6c = Boot -keycode 0x65 = KP_Enter - -keycode 0x3f = Control - -# keycode 100 = AltGr - -keycode 0x23 = Find -keycode 0x4d = Up -keycode 0x39 = Prior - shift keycode 0x39 = Scroll_Backward -keycode 0x5f = Left - alt keycode 0x5f = Decr_Console -keycode 0x61 = Right - alt keycode 0x61 = Incr_Console -keycode 0x38 = Select -keycode 0x60 = Down -keycode 0x3a = Next - shift keycode 0x3a = Scroll_Forward -keycode 0x24 = Insert -keycode 0x25 = Remove -# altgr control keycode 0x25 = Boot - control alt keycode 0x25 = Boot - -keycode 0x0f = Help Show_Memory Show_Registers - control keycode 0x0f = Show_State - -keycode 0x10 = Do - -string F1 = "\033[[A" -string F2 = "\033[[B" -string F3 = "\033[[C" -string F4 = "\033[[D" -string F5 = "\033[[E" -string F6 = "\033[17~" -string F7 = "\033[18~" -string F8 = "\033[19~" -string F9 = "\033[20~" -string F10 = "\033[21~" -string F11 = "\033[23~" -string F12 = "\033[24~" -string F13 = "\033[25~" -string F14 = "\033[26~" -string F15 = "\033[28~" -string F16 = "\033[29~" -string F17 = "\033[31~" -string F18 = "\033[32~" -string F19 = "\033[33~" -string F20 = "\033[34~" -string Find = "\033[1~" -string Insert = "\033[2~" -string Remove = "\033[3~" -string Select = "\033[4~" -string Prior = "\033[5~" -string Next = "\033[6~" -string Macro = "\033[M" -string Pause = "\033[P" -compose '`' 'A' to 'À' -compose '`' 'a' to 'à' -compose '\'' 'A' to 'Á' -compose '\'' 'a' to 'á' -compose '^' 'A' to 'Â' -compose '^' 'a' to 'â' -compose '~' 'A' to 'Ã' -compose '~' 'a' to 'ã' -compose '"' 'A' to 'Ä' -compose '"' 'a' to 'ä' -compose 'O' 'A' to 'Å' -compose 'o' 'a' to 'å' -compose '0' 'A' to 'Å' -compose '0' 'a' to 'å' -compose 'A' 'A' to 'Å' -compose 'a' 'a' to 'å' -compose 'A' 'E' to 'Æ' -compose 'a' 'e' to 'æ' -compose ',' 'C' to 'Ç' -compose ',' 'c' to 'ç' -compose '`' 'E' to 'È' -compose '`' 'e' to 'è' -compose '\'' 'E' to 'É' -compose '\'' 'e' to 'é' -compose '^' 'E' to 'Ê' -compose '^' 'e' to 'ê' -compose '"' 'E' to 'Ë' -compose '"' 'e' to 'ë' -compose '`' 'I' to 'Ì' -compose '`' 'i' to 'ì' -compose '\'' 'I' to 'Í' -compose '\'' 'i' to 'í' -compose '^' 'I' to 'Î' -compose '^' 'i' to 'î' -compose '"' 'I' to 'Ï' -compose '"' 'i' to 'ï' -compose '-' 'D' to 'Ð' -compose '-' 'd' to 'ð' -compose '~' 'N' to 'Ñ' -compose '~' 'n' to 'ñ' -compose '`' 'O' to 'Ò' -compose '`' 'o' to 'ò' -compose '\'' 'O' to 'Ó' -compose '\'' 'o' to 'ó' -compose '^' 'O' to 'Ô' -compose '^' 'o' to 'ô' -compose '~' 'O' to 'Õ' -compose '~' 'o' to 'õ' -compose '"' 'O' to 'Ö' -compose '"' 'o' to 'ö' -compose '/' 'O' to 'Ø' -compose '/' 'o' to 'ø' -compose '`' 'U' to 'Ù' -compose '`' 'u' to 'ù' -compose '\'' 'U' to 'Ú' -compose '\'' 'u' to 'ú' -compose '^' 'U' to 'Û' -compose '^' 'u' to 'û' -compose '"' 'U' to 'Ü' -compose '"' 'u' to 'ü' -compose '\'' 'Y' to 'Ý' -compose '\'' 'y' to 'ý' -compose 'T' 'H' to 'Þ' -compose 't' 'h' to 'þ' -compose 's' 's' to 'ß' -compose '"' 'y' to 'ÿ' -compose 's' 'z' to 'ß' -compose 'i' 'j' to 'ÿ' diff --git a/drivers/tc/lk201-remap.c b/drivers/tc/lk201-remap.c deleted file mode 100644 index d39098c2720e..000000000000 --- a/drivers/tc/lk201-remap.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Keyboard mappings for DEC LK201/401/501 keyboards - * - * 17.05.99 Michael Engel (engel@unix-ag.org) - * - * DEC US keyboards generate keycodes in the range 0x55 - 0xfb - * - * This conflicts with Linux scancode conventions which define - * 0x00-0x7f as "normal" and 0x80-0xff as "shifted" scancodes, so we - * have to remap the keycodes to 0x00-0x7f with the scancodeRemap - * array. The generated scancode is simply the number of the key counted - * from the left upper to the right lower corner of the keyboard ... - * - * These scancodes are then being remapped (I hope ;-)) with the - * lk501*map[] arrays which define scancode -> Linux code mapping - * - * Oh man is this horrible ;-) - * - * Scancodes with dual labels exist for keyboards as follows: - * - * code: left label / right label - * - * 0x73: LKx01, LK421 / LK443, LK444 - * 0x74: LKx01, LK421 / LK443, LK444 - * 0x7c: LKx01, LK421 / LK443, LK444 - * 0x8a: LKx01, LK421 / LK443, LK444 - * 0x8b: LKx01, LK421 / LK443, LK444 - * 0x8c: LKx01, LK421 / LK443, LK444 - * 0x8d: LKx01, LK421 / LK443, LK444 - * 0x8e: LKx01, LK421 / LK443, LK444 - * 0x8f: LKx01, LK421 / LK443, LK444 - * 0x9c: LKx01, LK421 / LK443, LK444 - * 0xa1: LKx01, LK421 / LK443, LK444 - * 0xa2: LKx01, LK421 / LK443, LK444 - * 0xa3: LKx01, LK421 / LK443, LK444 - * 0xa4: LKx01, LK421 / LK443, LK444 - * 0xad: LK421 / LK443, LK444 - * 0xc9: LKx01, LK421, LK443 / LK444 - * 0xf7: LKx01, LK443 / LK444 - */ - -unsigned char scancodeRemap[256] = { -/* ----- */ -/* 0 */ 0, 0, 0, 0, -/* ----- */ -/* 4 */ 0, 0, 0, 0, -/* ----- */ -/* 8 */ 0, 0, 0, 0, -/* ----- */ -/* c */ 0, 0, 0, 0, -/* ----- */ -/* 10 */ 0, 0, 0, 0, -/* ----- */ -/* 14 */ 0, 0, 0, 0, -/* ----- */ -/* 18 */ 0, 0, 0, 0, -/* ----- */ -/* 1c */ 0, 0, 0, 0, -/* ----- */ -/* 20 */ 0, 0, 0, 0, -/* ----- */ -/* 24 */ 0, 0, 0, 0, -/* ----- */ -/* 28 */ 0, 0, 0, 0, -/* ----- */ -/* 2c */ 0, 0, 0, 0, -/* ----- */ -/* 30 */ 0, 0, 0, 0, -/* ----- */ -/* 34 */ 0, 0, 0, 0, -/* ----- */ -/* 38 */ 0, 0, 0, 0, -/* ----- */ -/* 3c */ 0, 0, 0, 0, -/* ----- */ -/* 40 */ 0, 0, 0, 0, -/* ----- */ -/* 44 */ 0, 0, 0, 0, -/* ----- */ -/* 48 */ 0, 0, 0, 0, -/* ----- */ -/* 4c */ 0, 0, 0, 0, -/* ----- */ -/* 50 */ 0, 0, 0, 0, -/* ----- ESC F1 F2 */ -/* 54 */ 0, 0, 0x01, 0x02, -/* ----- F3 F4 F5 */ -/* 58 */ 0x03, 0x04, 0x05, 0, -/* ----- */ -/* 5c */ 0, 0, 0, 0, -/* ----- */ -/* 60 */ 0, 0, 0, 0, -/* ----- F6 F7 F8 F9 */ -/* 64 */ 0x06, 0x07, 0x08, 0x09, -/* ----- F10 */ -/* 68 */ 0x0a, 0, 0, 0, -/* ----- */ -/* 6c */ 0, 0, 0, 0, -/* ----- F11 F12 F13/PRNT SCRN */ -/* 70 */ 0, 0x0b, 0x0c, 0x0d, -/* ----- F14/SCRL LCK */ -/* 74 */ 0x0e, 0, 0, 0, -/* ----- */ -/* 78 */ 0, 0, 0, 0, -/* ----- HELP/PAUSE DO */ -/* 7c */ 0x0f, 0x10, 0, 0, -/* ----- F17 F18 F19 F20 */ -/* 80 */ 0x11, 0x12, 0x13, 0x14, -/* ----- */ -/* 84 */ 0, 0, 0, 0, -/* ----- FIND/INSERT INSERT/HOME */ -/* 88 */ 0, 0, 0x23, 0x24, -/* ----- REMOVE/PG UP SELECT/DELETE PREVIOUS/END NEXT/PG DN */ -/* 8c */ 0x25, 0x38, 0x39, 0x3a, -/* ----- KP 0 */ -/* 90 */ 0, 0, 0x6b, 0, -/* ----- KP . KP ENTER KP 1 KP 2 */ -/* 94 */ 0x6c, 0x65, 0x62, 0x63, -/* ----- KP 3 KP 4 KP 5 KP 6 */ -/* 98 */ 0x64, 0x4e, 0x4f, 0x50, -/* ----- KP ,/KP + KP 7 KP 8 KP 9 */ -/* 9c */ 0x51, 0x3b, 0x3c, 0x3d, -/* ----- KP - KP F1/NUM LCK KP F2/KP / KP F3/KP * */ -/* a0 */ 0x3e, 0x26, 0x27, 0x28, -/* ----- KP F4/KP - LEFT */ -/* a4 */ 0x29, 0, 0, 0x5f, -/* ----- RIGHT DOWN UP SHIFT Rt */ -/* a8 */ 0x61, 0x60, 0x4d, 0x5e, -/* ----- ALT COMP Rt/CTRL Rt SHIFT CONTROL */ -/* ac */ 0, 0, 0x52, 0x3f, -/* ----- CAPS COMPOSE ALT Rt */ -/* b0 */ 0x40, 0x67, 0, 0, -/* ----- */ -/* b4 */ 0, 0, 0, 0, -/* ----- */ -/* b8 */ 0, 0, 0, 0, -/* ----- BKSP RET TAB ` */ -/* bc */ 0x22, 0x37, 0x2a, 0x15, -/* ----- 1 q a z */ -/* c0 */ 0x16, 0x2b, 0x41, 0x54, -/* ----- 2 w s */ -/* c4 */ 0, 0x17, 0x2c, 0x42, -/* ----- x </\\ 3 */ -/* c8 */ 0x55, 0x53, 0, 0x18, -/* ----- e d c */ -/* cc */ 0x2d, 0x43, 0x56, 0, -/* ----- 4 r f v */ -/* d0 */ 0x19, 0x2e, 0x44, 0x57, -/* ----- SPACE 5 t */ -/* d4 */ 0x68, 0, 0x1a, 0x2f, -/* ----- g b 6 */ -/* d8 */ 0x45, 0x58, 0, 0x1b, -/* ----- y h n */ -/* dc */ 0x30, 0x46, 0x59, 0, -/* ----- 7 u j m */ -/* e0 */ 0x1c, 0x31, 0x47, 0x5a, -/* ----- 8 i k */ -/* e4 */ 0, 0x1d, 0x32, 0x48, -/* ----- , 9 o */ -/* e8 */ 0x5b, 0, 0x1e, 0x33, -/* ----- l . 0 */ -/* ec */ 0x49, 0x5c, 0, 0x1f, -/* ----- p ; / */ -/* f0 */ 0x34, 0, 0x4a, 0x5d, -/* ----- = ] \\/\' */ -/* f4 */ 0, 0x21, 0x36, 0x4c, -/* ----- - [ \' */ -/* f8 */ 0, 0x20, 0x35, 0x4b, -/* ----- */ -/* fc */ 0, 0, 0, 0, -}; - diff --git a/drivers/tc/lk201.c b/drivers/tc/lk201.c deleted file mode 100644 index a90c255f079d..000000000000 --- a/drivers/tc/lk201.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999-2002 Harald Koerfgen <hkoerfg@web.de> - * Copyright (C) 2001, 2002, 2003, 2004 Maciej W. Rozycki - */ - - -#include <linux/errno.h> -#include <linux/tty.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/kbd_ll.h> -#include <linux/kbd_kern.h> -#include <linux/vt_kern.h> - -#include <asm/keyboard.h> -#include <asm/dec/tc.h> -#include <asm/dec/machtype.h> -#include <asm/dec/serial.h> - -#include "lk201.h" - -/* - * Only handle DECstations that have an LK201 interface. - * Maxine uses LK501 at the Access.Bus and various DECsystems - * have no keyboard interface at all. - */ -#define LK_IFACE (mips_machtype == MACH_DS23100 || \ - mips_machtype == MACH_DS5000_200 || \ - mips_machtype == MACH_DS5000_1XX || \ - mips_machtype == MACH_DS5000_2X0) -/* - * These use the Z8530 SCC. Others use the DZ11. - */ -#define LK_IFACE_ZS (mips_machtype == MACH_DS5000_1XX || \ - mips_machtype == MACH_DS5000_2X0) - -/* Simple translation table for the SysRq keys */ - -#ifdef CONFIG_MAGIC_SYSRQ -/* - * Actually no translation at all, at least until we figure out - * how to define SysRq for LK201 and friends. --macro - */ -unsigned char lk201_sysrq_xlate[128]; -unsigned char *kbd_sysrq_xlate = lk201_sysrq_xlate; - -unsigned char kbd_sysrq_key = -1; -#endif - -#define KEYB_LINE 3 - -static int __init lk201_init(void *); -static void __init lk201_info(void *); -static void lk201_rx_char(unsigned char, unsigned char); - -static struct dec_serial_hook lk201_hook = { - .init_channel = lk201_init, - .init_info = lk201_info, - .rx_char = NULL, - .poll_rx_char = NULL, - .poll_tx_char = NULL, - .cflags = B4800 | CS8 | CSTOPB | CLOCAL, -}; - -/* - * This is used during keyboard initialisation - */ -static unsigned char lk201_reset_string[] = { - LK_CMD_SET_DEFAULTS, - LK_CMD_MODE(LK_MODE_RPT_DOWN, 1), - LK_CMD_MODE(LK_MODE_RPT_DOWN, 2), - LK_CMD_MODE(LK_MODE_RPT_DOWN, 3), - LK_CMD_MODE(LK_MODE_RPT_DOWN, 4), - LK_CMD_MODE(LK_MODE_DOWN_UP, 5), - LK_CMD_MODE(LK_MODE_DOWN_UP, 6), - LK_CMD_MODE(LK_MODE_RPT_DOWN, 7), - LK_CMD_MODE(LK_MODE_RPT_DOWN, 8), - LK_CMD_MODE(LK_MODE_RPT_DOWN, 9), - LK_CMD_MODE(LK_MODE_RPT_DOWN, 10), - LK_CMD_MODE(LK_MODE_RPT_DOWN, 11), - LK_CMD_MODE(LK_MODE_RPT_DOWN, 12), - LK_CMD_MODE(LK_MODE_DOWN, 13), - LK_CMD_MODE(LK_MODE_RPT_DOWN, 14), - LK_CMD_DIS_KEYCLK, - LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4), -}; - -static void *lk201_handle; - -static int lk201_send(unsigned char ch) -{ - if (lk201_hook.poll_tx_char(lk201_handle, ch)) { - printk(KERN_ERR "lk201: transmit timeout\n"); - return -EIO; - } - return 0; -} - -static inline int lk201_get_id(void) -{ - return lk201_send(LK_CMD_REQ_ID); -} - -static int lk201_reset(void) -{ - int i, r; - - for (i = 0; i < sizeof(lk201_reset_string); i++) { - r = lk201_send(lk201_reset_string[i]); - if (r < 0) - return r; - } - return 0; -} - -static void lk201_report(unsigned char id[6]) -{ - char *report = "lk201: keyboard attached, "; - - switch (id[2]) { - case LK_STAT_PWRUP_OK: - printk(KERN_INFO "%sself-test OK\n", report); - break; - case LK_STAT_PWRUP_KDOWN: - /* The keyboard will resend the power-up ID - after all keys are released, so we don't - bother handling the error specially. Still - there may be a short-circuit inside. - */ - printk(KERN_ERR "%skey down (stuck?), code: 0x%02x\n", - report, id[3]); - break; - case LK_STAT_PWRUP_ERROR: - printk(KERN_ERR "%sself-test failure\n", report); - break; - default: - printk(KERN_ERR "%sunknown error: 0x%02x\n", - report, id[2]); - } -} - -static void lk201_id(unsigned char id[6]) -{ - /* - * Report whether there is an LK201 or an LK401 - * The LK401 has ALT keys... - */ - switch (id[4]) { - case 1: - printk(KERN_INFO "lk201: LK201 detected\n"); - break; - case 2: - printk(KERN_INFO "lk201: LK401 detected\n"); - break; - case 3: - printk(KERN_INFO "lk201: LK443 detected\n"); - break; - case 4: - printk(KERN_INFO "lk201: LK421 detected\n"); - break; - default: - printk(KERN_WARNING - "lk201: unknown keyboard detected, ID %d\n", id[4]); - printk(KERN_WARNING "lk201: ... please report to " - "<linux-mips@linux-mips.org>\n"); - } -} - -#define DEFAULT_KEYB_REP_DELAY (250/5) /* [5ms] */ -#define DEFAULT_KEYB_REP_RATE 30 /* [cps] */ - -static struct kbd_repeat kbdrate = { - DEFAULT_KEYB_REP_DELAY, - DEFAULT_KEYB_REP_RATE -}; - -static void parse_kbd_rate(struct kbd_repeat *r) -{ - if (r->delay <= 0) - r->delay = kbdrate.delay; - if (r->rate <= 0) - r->rate = kbdrate.rate; - - if (r->delay < 5) - r->delay = 5; - if (r->delay > 630) - r->delay = 630; - if (r->rate < 12) - r->rate = 12; - if (r->rate > 127) - r->rate = 127; - if (r->rate == 125) - r->rate = 124; -} - -static int write_kbd_rate(struct kbd_repeat *rep) -{ - int delay, rate; - int i; - - delay = rep->delay / 5; - rate = rep->rate; - for (i = 0; i < 4; i++) { - if (lk201_hook.poll_tx_char(lk201_handle, - LK_CMD_RPT_RATE(i))) - return 1; - if (lk201_hook.poll_tx_char(lk201_handle, - LK_PARAM_DELAY(delay))) - return 1; - if (lk201_hook.poll_tx_char(lk201_handle, - LK_PARAM_RATE(rate))) - return 1; - } - return 0; -} - -static int lk201_kbd_rate(struct kbd_repeat *rep) -{ - if (rep == NULL) - return -EINVAL; - - parse_kbd_rate(rep); - - if (write_kbd_rate(rep)) { - memcpy(rep, &kbdrate, sizeof(struct kbd_repeat)); - return -EIO; - } - - memcpy(&kbdrate, rep, sizeof(struct kbd_repeat)); - - return 0; -} - -static void lk201_kd_mksound(unsigned int hz, unsigned int ticks) -{ - if (!ticks) - return; - - /* - * Can't set frequency and we "approximate" - * duration by volume. ;-) - */ - ticks /= HZ / 32; - if (ticks > 7) - ticks = 7; - ticks = 7 - ticks; - - if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_ENB_BELL)) - return; - if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_VOLUME(ticks))) - return; - if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_BELL)) - return; -} - -void kbd_leds(unsigned char leds) -{ - unsigned char l = 0; - - if (!lk201_handle) /* FIXME */ - return; - - /* FIXME -- Only Hold and Lock LEDs for now. --macro */ - if (leds & LED_SCR) - l |= LK_LED_HOLD; - if (leds & LED_CAP) - l |= LK_LED_LOCK; - - if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_ON)) - return; - if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(l))) - return; - if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_OFF)) - return; - if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(~l))) - return; -} - -int kbd_setkeycode(unsigned int scancode, unsigned int keycode) -{ - return -EINVAL; -} - -int kbd_getkeycode(unsigned int scancode) -{ - return -EINVAL; -} - -int kbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode) -{ - *keycode = scancode; - return 1; -} - -char kbd_unexpected_up(unsigned char keycode) -{ - return 0x80; -} - -static void lk201_rx_char(unsigned char ch, unsigned char fl) -{ - static unsigned char id[6]; - static int id_i; - - static int shift_state = 0; - static int prev_scancode; - unsigned char c = scancodeRemap[ch]; - - if (fl != TTY_NORMAL && fl != TTY_OVERRUN) { - printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n", fl); - return; - } - - /* Assume this is a power-up ID. */ - if (ch == LK_STAT_PWRUP_ID && !id_i) { - id[id_i++] = ch; - return; - } - - /* Handle the power-up sequence. */ - if (id_i) { - id[id_i++] = ch; - if (id_i == 4) { - /* OK, the power-up concluded. */ - lk201_report(id); - if (id[2] == LK_STAT_PWRUP_OK) - lk201_get_id(); - else { - id_i = 0; - printk(KERN_ERR "lk201: keyboard power-up " - "error, skipping initialization\n"); - } - } else if (id_i == 6) { - /* We got the ID; report it and start operation. */ - id_i = 0; - lk201_id(id); - lk201_reset(); - } - return; - } - - /* Everything else is a scancode/status response. */ - id_i = 0; - switch (ch) { - case LK_STAT_RESUME_ERR: - case LK_STAT_ERROR: - case LK_STAT_INHIBIT_ACK: - case LK_STAT_TEST_ACK: - case LK_STAT_MODE_KEYDOWN: - case LK_STAT_MODE_ACK: - break; - case LK_KEY_LOCK: - shift_state ^= LK_LOCK; - handle_scancode(c, (shift_state & LK_LOCK) ? 1 : 0); - break; - case LK_KEY_SHIFT: - shift_state ^= LK_SHIFT; - handle_scancode(c, (shift_state & LK_SHIFT) ? 1 : 0); - break; - case LK_KEY_CTRL: - shift_state ^= LK_CTRL; - handle_scancode(c, (shift_state & LK_CTRL) ? 1 : 0); - break; - case LK_KEY_COMP: - shift_state ^= LK_COMP; - handle_scancode(c, (shift_state & LK_COMP) ? 1 : 0); - break; - case LK_KEY_RELEASE: - if (shift_state & LK_SHIFT) - handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0); - if (shift_state & LK_CTRL) - handle_scancode(scancodeRemap[LK_KEY_CTRL], 0); - if (shift_state & LK_COMP) - handle_scancode(scancodeRemap[LK_KEY_COMP], 0); - if (shift_state & LK_LOCK) - handle_scancode(scancodeRemap[LK_KEY_LOCK], 0); - shift_state = 0; - break; - case LK_KEY_REPEAT: - handle_scancode(prev_scancode, 1); - break; - default: - prev_scancode = c; - handle_scancode(c, 1); - break; - } - tasklet_schedule(&keyboard_tasklet); -} - -static void __init lk201_info(void *handle) -{ -} - -static int __init lk201_init(void *handle) -{ - /* First install handlers. */ - lk201_handle = handle; - kbd_rate = lk201_kbd_rate; - kd_mksound = lk201_kd_mksound; - - lk201_hook.rx_char = lk201_rx_char; - - /* Then just issue a reset -- the handlers will do the rest. */ - lk201_send(LK_CMD_POWER_UP); - - return 0; -} - -void __init kbd_init_hw(void) -{ - /* Maxine uses LK501 at the Access.Bus. */ - if (!LK_IFACE) - return; - - printk(KERN_INFO "lk201: DECstation LK keyboard driver v0.05.\n"); - - if (LK_IFACE_ZS) { - /* - * kbd_init_hw() is being called before - * rs_init() so just register the kbd hook - * and let zs_init do the rest :-) - */ - if (!register_dec_serial_hook(KEYB_LINE, &lk201_hook)) - unregister_dec_serial_hook(KEYB_LINE); - } else { - /* - * TODO: modify dz.c to allow similar hooks - * for LK201 handling on DS2100, DS3100, and DS5000/200 - */ - printk(KERN_ERR "lk201: support for DZ11 not yet ready.\n"); - } -} diff --git a/drivers/tc/lk201.h b/drivers/tc/lk201.h deleted file mode 100644 index 99f3203c41b8..000000000000 --- a/drivers/tc/lk201.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Commands to the keyboard processor - */ - -#define LK_PARAM 0x80 /* start/end parameter list */ - -#define LK_CMD_RESUME 0x8b /* resume transmission to the host */ -#define LK_CMD_INHIBIT 0x89 /* stop transmission to the host */ -#define LK_CMD_LEDS_ON 0x13 /* light LEDs */ - /* 1st param: led bitmask */ -#define LK_CMD_LEDS_OFF 0x11 /* turn off LEDs */ - /* 1st param: led bitmask */ -#define LK_CMD_DIS_KEYCLK 0x99 /* disable the keyclick */ -#define LK_CMD_ENB_KEYCLK 0x1b /* enable the keyclick */ - /* 1st param: volume */ -#define LK_CMD_DIS_CTLCLK 0xb9 /* disable the Ctrl keyclick */ -#define LK_CMD_ENB_CTLCLK 0xbb /* enable the Ctrl keyclick */ -#define LK_CMD_SOUND_CLK 0x9f /* emit a keyclick */ -#define LK_CMD_DIS_BELL 0xa1 /* disable the bell */ -#define LK_CMD_ENB_BELL 0x23 /* enable the bell */ - /* 1st param: volume */ -#define LK_CMD_BELL 0xa7 /* emit a bell */ -#define LK_CMD_TMP_NORPT 0xd1 /* disable typematic */ - /* for the currently pressed key */ -#define LK_CMD_ENB_RPT 0xe3 /* enable typematic */ - /* for RPT_DOWN groups */ -#define LK_CMD_DIS_RPT 0xe1 /* disable typematic */ - /* for RPT_DOWN groups */ -#define LK_CMD_RPT_TO_DOWN 0xd9 /* set RPT_DOWN groups to DOWN */ -#define LK_CMD_REQ_ID 0xab /* request the keyboard ID */ -#define LK_CMD_POWER_UP 0xfd /* init power-up sequence */ -#define LK_CMD_TEST_MODE 0xcb /* enter the factory test mode */ -#define LK_CMD_TEST_EXIT 0x80 /* exit the factory test mode */ -#define LK_CMD_SET_DEFAULTS 0xd3 /* set power-up defaults */ - -#define LK_CMD_MODE(m,div) (LK_PARAM|(((div)&0xf)<<3)|(((m)&0x3)<<1)) - /* select the repeat mode */ - /* for the selected key group */ -#define LK_CMD_MODE_AR(m,div) ((((div)&0xf)<<3)|(((m)&0x3)<<1)) - /* select the repeat mode */ - /* and the repeat register */ - /* for the selected key group */ - /* 1st param: register number */ -#define LK_CMD_RPT_RATE(r) (0x78|(((r)&0x3)<<1)) - /* set the delay and repeat rate */ - /* for the selected repeat register */ - /* 1st param: initial delay */ - /* 2nd param: repeat rate */ - -/* there are 4 leds, represent them in the low 4 bits of a byte */ -#define LK_PARAM_LED_MASK(ledbmap) (LK_PARAM|((ledbmap)&0xf)) -#define LK_LED_WAIT 0x1 /* Wait LED */ -#define LK_LED_COMP 0x2 /* Compose LED */ -#define LK_LED_LOCK 0x4 /* Lock LED */ -#define LK_LED_HOLD 0x8 /* Hold Screen LED */ - -/* max volume is 0, lowest is 0x7 */ -#define LK_PARAM_VOLUME(v) (LK_PARAM|((v)&0x7)) - -/* mode set command details, div is a key group number */ -#define LK_MODE_DOWN 0x0 /* make only */ -#define LK_MODE_RPT_DOWN 0x1 /* make and typematic */ -#define LK_MODE_DOWN_UP 0x3 /* make and release */ - -/* there are 4 repeat registers */ -#define LK_PARAM_AR(r) (LK_PARAM|((v)&0x3)) - -/* - * Mappings between key groups and keycodes are as follows: - * - * 1: 0xbf - 0xff -- alphanumeric, - * 2: 0x91 - 0xa5 -- numeric keypad, - * 3: 0xbc -- Backspace, - * 4: 0xbd - 0xbe -- Tab, Return, - * 5: 0xb0 - 0xb2 -- Lock, Compose Character, - * 6: 0xad - 0xaf -- Ctrl, Shift, - * 7: 0xa6 - 0xa8 -- Left Arrow, Right Arrow, - * 8: 0xa9 - 0xac -- Up Arrow, Down Arrow, Right Shift, - * 9: 0x88 - 0x90 -- editor keypad, - * 10: 0x56 - 0x62 -- F1 - F5, - * 11: 0x63 - 0x6e -- F6 - F10, - * 12: 0x6f - 0x7a -- F11 - F14, - * 13: 0x7b - 0x7d -- Help, Do, - * 14: 0x7e - 0x87 -- F17 - F20. - * - * Notes: - * 1. Codes in the 0x00 - 0x40 range are reserved. - * 2. The assignment of the 0x41 - 0x55 range is undiscovered, probably 10. - */ - -/* delay is 5 - 630 ms; 0x00 and 0x7f are reserved */ -#define LK_PARAM_DELAY(t) ((t)&0x7f) - -/* rate is 12 - 127 Hz; 0x00 - 0x0b and 0x7d (power-up!) are reserved */ -#define LK_PARAM_RATE(r) (LK_PARAM|((r)&0x7f)) - -#define LK_SHIFT 1<<0 -#define LK_CTRL 1<<1 -#define LK_LOCK 1<<2 -#define LK_COMP 1<<3 - -#define LK_KEY_SHIFT 0xae -#define LK_KEY_CTRL 0xaf -#define LK_KEY_LOCK 0xb0 -#define LK_KEY_COMP 0xb1 - -#define LK_KEY_RELEASE 0xb3 /* all keys released */ -#define LK_KEY_REPEAT 0xb4 /* repeat the last key */ - -/* status responses */ -#define LK_STAT_RESUME_ERR 0xb5 /* keystrokes lost while inhibited */ -#define LK_STAT_ERROR 0xb6 /* an invalid command received */ -#define LK_STAT_INHIBIT_ACK 0xb7 /* transmission inhibited */ -#define LK_STAT_TEST_ACK 0xb8 /* the factory test mode entered */ -#define LK_STAT_MODE_KEYDOWN 0xb9 /* a key is down on a change */ - /* to the DOWN_UP mode; */ - /* the keycode follows */ -#define LK_STAT_MODE_ACK 0xba /* the mode command succeeded */ - -#define LK_STAT_PWRUP_ID 0x01 /* the power-up response start mark */ -#define LK_STAT_PWRUP_OK 0x00 /* the power-up self test OK */ -#define LK_STAT_PWRUP_KDOWN 0x3d /* a key was down during the test */ -#define LK_STAT_PWRUP_ERROR 0x3e /* keyboard self test failure */ - -extern unsigned char scancodeRemap[256]; diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index c99938d5f78e..69aa68287d3f 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -982,7 +982,6 @@ EXPORT_SYMBOL(usb_altnum_to_altsetting); EXPORT_SYMBOL(__usb_get_extra_descriptor); -EXPORT_SYMBOL(usb_find_device); EXPORT_SYMBOL(usb_get_current_frame_number); EXPORT_SYMBOL(usb_buffer_alloc); diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index ebb04ac4857b..5e3e4e9b6c77 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -87,7 +87,7 @@ struct mon_reader_text { static struct dentry *mon_dir; /* Usually /sys/kernel/debug/usbmon */ -static void mon_text_ctor(void *, struct kmem_cache *, unsigned long); +static void mon_text_ctor(struct kmem_cache *, void *); struct mon_text_ptr { int cnt, limit; @@ -720,7 +720,7 @@ void mon_text_del(struct mon_bus *mbus) /* * Slab interface: constructor. */ -static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sflags) +static void mon_text_ctor(struct kmem_cache *slab, void *mem) { /* * Nothing to initialize. No, really! diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c index 06d1107dbd47..55b952084f0c 100644 --- a/drivers/usb/storage/libusual.c +++ b/drivers/usb/storage/libusual.c @@ -30,7 +30,7 @@ static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS); #define BIAS_NAME_SIZE (sizeof("usb-storage")) static const char *bias_names[3] = { "none", "usb-storage", "ub" }; -static DECLARE_MUTEX_LOCKED(usu_init_notify); +static struct semaphore usu_init_notify; static DECLARE_COMPLETION(usu_end_notify); static atomic_t total_threads = ATOMIC_INIT(0); @@ -204,6 +204,8 @@ static int __init usb_usual_init(void) { int rc; + sema_init(&usu_init_notify, 0); + rc = usb_register(&usu_driver); up(&usu_init_notify); return rc; diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index d9315d99445f..b63860f7beab 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -18,8 +18,8 @@ */ #if defined(__arm__) -#define DUMMY_COLUMNS ORIG_VIDEO_COLS -#define DUMMY_ROWS ORIG_VIDEO_LINES +#define DUMMY_COLUMNS screen_info.orig_video_cols +#define DUMMY_ROWS screen_info.orig_video_lines #elif defined(__hppa__) /* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */ #define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index e9afb7ebd566..f65bcd314d54 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -362,7 +362,7 @@ static const char *vgacon_startup(void) u16 saved1, saved2; volatile u16 *p; - if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB) { + if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB) { no_vga: #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; @@ -372,29 +372,30 @@ static const char *vgacon_startup(void) #endif } - /* SCREEN_INFO initialized? */ - if ((ORIG_VIDEO_MODE == 0) && - (ORIG_VIDEO_LINES == 0) && - (ORIG_VIDEO_COLS == 0)) + /* boot_params.screen_info initialized? */ + if ((screen_info.orig_video_mode == 0) && + (screen_info.orig_video_lines == 0) && + (screen_info.orig_video_cols == 0)) goto no_vga; /* VGA16 modes are not handled by VGACON */ - if ((ORIG_VIDEO_MODE == 0x0D) || /* 320x200/4 */ - (ORIG_VIDEO_MODE == 0x0E) || /* 640x200/4 */ - (ORIG_VIDEO_MODE == 0x10) || /* 640x350/4 */ - (ORIG_VIDEO_MODE == 0x12) || /* 640x480/4 */ - (ORIG_VIDEO_MODE == 0x6A)) /* 800x600/4, 0x6A is very common */ + if ((screen_info.orig_video_mode == 0x0D) || /* 320x200/4 */ + (screen_info.orig_video_mode == 0x0E) || /* 640x200/4 */ + (screen_info.orig_video_mode == 0x10) || /* 640x350/4 */ + (screen_info.orig_video_mode == 0x12) || /* 640x480/4 */ + (screen_info.orig_video_mode == 0x6A)) /* 800x600/4 (VESA) */ goto no_vga; - vga_video_num_lines = ORIG_VIDEO_LINES; - vga_video_num_columns = ORIG_VIDEO_COLS; + vga_video_num_lines = screen_info.orig_video_lines; + vga_video_num_columns = screen_info.orig_video_cols; state.vgabase = NULL; - if (ORIG_VIDEO_MODE == 7) { /* Is this a monochrome display? */ + if (screen_info.orig_video_mode == 7) { + /* Monochrome display */ vga_vram_base = 0xb0000; vga_video_port_reg = VGA_CRT_IM; vga_video_port_val = VGA_CRT_DM; - if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { + if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) { static struct resource ega_console_resource = { .name = "ega", .start = 0x3B0, .end = 0x3BF }; vga_video_type = VIDEO_TYPE_EGAM; @@ -422,12 +423,12 @@ static const char *vgacon_startup(void) vga_vram_base = 0xb8000; vga_video_port_reg = VGA_CRT_IC; vga_video_port_val = VGA_CRT_DC; - if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { + if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) { int i; vga_vram_size = 0x8000; - if (!ORIG_VIDEO_ISVGA) { + if (!screen_info.orig_video_isVGA) { static struct resource ega_console_resource = { .name = "ega", .start = 0x3C0, .end = 0x3DF }; vga_video_type = VIDEO_TYPE_EGAC; @@ -521,14 +522,14 @@ static const char *vgacon_startup(void) || vga_video_type == VIDEO_TYPE_VGAC || vga_video_type == VIDEO_TYPE_EGAM) { vga_hardscroll_enabled = vga_hardscroll_user_enable; - vga_default_font_height = ORIG_VIDEO_POINTS; - vga_video_font_height = ORIG_VIDEO_POINTS; + vga_default_font_height = screen_info.orig_video_points; + vga_video_font_height = screen_info.orig_video_points; /* This may be suboptimal but is a safe bet - go with it */ vga_scan_lines = vga_video_font_height * vga_video_num_lines; } - vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH; + vgacon_xres = screen_info.orig_video_cols * VGA_FONTWIDTH; vgacon_yres = vga_scan_lines; if (!vga_init_done) { @@ -798,7 +799,7 @@ static int vgacon_switch(struct vc_data *c) { int x = c->vc_cols * VGA_FONTWIDTH; int y = c->vc_rows * c->vc_font.height; - int rows = ORIG_VIDEO_LINES * vga_default_font_height/ + int rows = screen_info.orig_video_lines * vga_default_font_height/ c->vc_font.height; /* * We need to save screen size here as it's the only way @@ -818,7 +819,7 @@ static int vgacon_switch(struct vc_data *c) if ((vgacon_xres != x || vgacon_yres != y) && (!(vga_video_num_columns % 2) && - vga_video_num_columns <= ORIG_VIDEO_COLS && + vga_video_num_columns <= screen_info.orig_video_cols && vga_video_num_lines <= rows)) vgacon_doresize(c, c->vc_cols, c->vc_rows); } @@ -1280,8 +1281,8 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font) static int vgacon_resize(struct vc_data *c, unsigned int width, unsigned int height, unsigned int user) { - if (width % 2 || width > ORIG_VIDEO_COLS || - height > (ORIG_VIDEO_LINES * vga_default_font_height)/ + if (width % 2 || width > screen_info.orig_video_cols || + height > (screen_info.orig_video_lines * vga_default_font_height)/ c->vc_font.height) /* let svgatextmode tinker with video timings and return success */ @@ -1313,8 +1314,8 @@ static void vgacon_save_screen(struct vc_data *c) * console initialization routines. */ vga_bootup_console = 1; - c->vc_x = ORIG_X; - c->vc_y = ORIG_Y; + c->vc_x = screen_info.orig_x; + c->vc_y = screen_info.orig_y; } /* We can't copy in more then the size of the video buffer, diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 0428f211f192..e8e38edb9b5b 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -804,7 +804,8 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev, if (bailearly == 1) bailout(dinfo); - if (FIXED_MODE(dinfo) && ORIG_VIDEO_ISVGA != VIDEO_TYPE_VLFB) { + if (FIXED_MODE(dinfo) && + screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) { ERR_MSG("Video mode must be programmed at boot time.\n"); cleanup(dinfo); return -ENODEV; @@ -815,7 +816,7 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev, /* Initialise dinfo and related data. */ /* If an initial mode was programmed at boot time, get its details. */ - if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB) + if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB) get_initial_mode(dinfo); if (bailearly == 3) diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c index 51807b4e26d1..c604d935c188 100644 --- a/drivers/video/omap/lcd_h3.c +++ b/drivers/video/omap/lcd_h3.c @@ -28,8 +28,6 @@ #define MODULE_NAME "omapfb-lcd_h3" -#define pr_err(fmt, args...) printk(KERN_ERR MODULE_NAME ": " fmt, ## args) - static int h3_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) { return 0; @@ -48,7 +46,7 @@ static int h3_panel_enable(struct lcd_panel *panel) if (!r) r = tps65010_set_gpio_out_value(GPIO2, HIGH); if (r) - pr_err("Unable to turn on LCD panel\n"); + pr_err(MODULE_NAME ": Unable to turn on LCD panel\n"); return r; } @@ -62,7 +60,7 @@ static void h3_panel_disable(struct lcd_panel *panel) if (!r) tps65010_set_gpio_out_value(GPIO2, LOW); if (r) - pr_err("Unable to turn off LCD panel\n"); + pr_err(MODULE_NAME ": Unable to turn off LCD panel\n"); } static unsigned long h3_panel_get_caps(struct lcd_panel *panel) diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c index 95604ca43301..5ef119c813e0 100644 --- a/drivers/video/omap/lcd_inn1610.c +++ b/drivers/video/omap/lcd_inn1610.c @@ -27,20 +27,18 @@ #define MODULE_NAME "omapfb-lcd_h3" -#define pr_err(fmt, args...) printk(KERN_ERR MODULE_NAME ": " fmt, ## args) - static int innovator1610_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) { int r = 0; if (omap_request_gpio(14)) { - pr_err("can't request GPIO 14\n"); + pr_err(MODULE_NAME ": can't request GPIO 14\n"); r = -1; goto exit; } if (omap_request_gpio(15)) { - pr_err("can't request GPIO 15\n"); + pr_err(MODULE_NAME ": can't request GPIO 15\n"); omap_free_gpio(14); r = -1; goto exit; diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index 2a14d28c4163..9b3c5923365e 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c @@ -1364,7 +1364,7 @@ static int __init vga16fb_probe(struct platform_device *dev) par = info->par; mutex_init(&par->open_lock); - par->isVGA = ORIG_VIDEO_ISVGA; + par->isVGA = screen_info.orig_video_isVGA; par->palette_blanked = 0; par->vesa_blanked = 0; diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c index d356da5709fc..1550431ccb6a 100644 --- a/drivers/w1/masters/matrox_w1.c +++ b/drivers/w1/masters/matrox_w1.c @@ -33,7 +33,6 @@ #include <linux/slab.h> #include <linux/pci_ids.h> #include <linux/pci.h> -#include <linux/timer.h> #include "../w1.h" #include "../w1_int.h" |