?? isapnp_proc.c
字號(hào):
/* * ISA Plug & Play support * Copyright (c) by Jaroslav Kysela <perex@suse.cz> * * Modified by Ed Okerson <eokerson@quicknet.net> to work with the 2.2.x * series of Linux kernels. 11/17/99 * * 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. * */static void *isapnp_alloc(long size);struct pnp_bus *isapnp_cards;struct pnp_dev *isapnp_devices;struct isapnp_info_buffer { char *buffer; /* pointer to begin of buffer */ char *curr; /* current position in buffer */ unsigned long size; /* current size */ unsigned long len; /* total length of buffer */ int stop; /* stop flag */ int error; /* error code */};typedef struct isapnp_info_buffer isapnp_info_buffer_t;static struct proc_dir_entry *isapnp_proc_entry = NULL;static void isapnp_info_read(isapnp_info_buffer_t *buffer);static void isapnp_info_write(isapnp_info_buffer_t *buffer);int isapnp_printf(isapnp_info_buffer_t * buffer, char *fmt,...){ va_list args; int res; char sbuffer[512]; if (buffer->stop || buffer->error) return 0; va_start(args, fmt); res = vsprintf(sbuffer, fmt, args); va_end(args); if (buffer->size + res >= buffer->len) { buffer->stop = 1; return 0; } strcpy(buffer->curr, sbuffer); buffer->curr += res; buffer->size += res; return res;}static loff_t isapnp_info_entry_lseek(struct file *file, loff_t offset, int orig){ switch (orig) { case 0: /* SEEK_SET */ file->f_pos = offset; return file->f_pos; case 1: /* SEEK_CUR */ file->f_pos += offset; return file->f_pos; case 2: /* SEEK_END */ default: return -EINVAL; } return -ENXIO;}static ssize_t isapnp_info_entry_read(struct file *file, char *buffer, size_t count, loff_t * offset){ isapnp_info_buffer_t *buf; long size = 0, size1; int mode; mode = file->f_flags & O_ACCMODE; if (mode != O_RDONLY) return -EINVAL; buf = (isapnp_info_buffer_t *) file->private_data; if (!buf) return -EIO; if (file->f_pos >= buf->size) return 0; size = buf->size < count ? buf->size : count; size1 = buf->size - file->f_pos; if (size1 < size) size = size1; if (copy_to_user(buffer, buf->buffer + file->f_pos, size)) return -EFAULT; file->f_pos += size; return size;}static ssize_t isapnp_info_entry_write(struct file *file, const char *buffer, size_t count, loff_t * offset){ isapnp_info_buffer_t *buf; long size = 0, size1; int mode; mode = file->f_flags & O_ACCMODE; if (mode != O_WRONLY) return -EINVAL; buf = (isapnp_info_buffer_t *) file->private_data; if (!buf) return -EIO; if (file->f_pos < 0) return -EINVAL; if (file->f_pos >= buf->len) return -ENOMEM; size = buf->len < count ? buf->len : count; size1 = buf->len - file->f_pos; if (size1 < size) size = size1; if (copy_from_user(buf->buffer + file->f_pos, buffer, size)) return -EFAULT; if (buf->size < file->f_pos + size) buf->size = file->f_pos + size; file->f_pos += size; return size;}static int isapnp_info_entry_open(struct inode *inode, struct file *file){ isapnp_info_buffer_t *buffer; int mode; mode = file->f_flags & O_ACCMODE; if (mode != O_RDONLY && mode != O_WRONLY) return -EINVAL; buffer = (isapnp_info_buffer_t *) isapnp_alloc(sizeof(isapnp_info_buffer_t)); if (!buffer) return -ENOMEM; buffer->len = 4 * PAGE_SIZE; buffer->buffer = vmalloc(buffer->len); if (!buffer->buffer) { kfree(buffer); return -ENOMEM; } buffer->curr = buffer->buffer; file->private_data = buffer; MOD_INC_USE_COUNT; if (mode == O_RDONLY) isapnp_info_read(buffer); return 0;}static int isapnp_info_entry_release(struct inode *inode, struct file *file){ isapnp_info_buffer_t *buffer; int mode; if ((buffer = (isapnp_info_buffer_t *) file->private_data) == NULL) return -EINVAL; mode = file->f_flags & O_ACCMODE; if (mode == O_WRONLY) isapnp_info_write(buffer); vfree(buffer->buffer); kfree(buffer); MOD_DEC_USE_COUNT; return 0;}static unsigned int isapnp_info_entry_poll(struct file *file, poll_table * wait){ if (!file->private_data) return 0; return POLLIN | POLLRDNORM;}static int isapnp_info_entry_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ return -EINVAL;}static int isapnp_info_entry_mmap(struct file *file, struct vm_area_struct *vma){ return -ENXIO;}static struct file_operations isapnp_info_entry_operations ={ isapnp_info_entry_lseek, /* lseek */ isapnp_info_entry_read, /* read */ isapnp_info_entry_write, /* write */ NULL, /* readdir */ isapnp_info_entry_poll, /* poll */ isapnp_info_entry_ioctl, /* ioctl - default */ isapnp_info_entry_mmap, /* mmap */ isapnp_info_entry_open, /* open */ NULL, /* flush */ isapnp_info_entry_release, /* release */ NULL, /* can't fsync */ NULL, /* fasync */ NULL, /* check_media_change */ NULL, /* revalidate */ NULL, /* lock */};static struct inode_operations isapnp_info_entry_inode_operations ={ &isapnp_info_entry_operations, /* default sound info directory file-ops */ NULL, /* create */ NULL, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ NULL, /* mkdir */ NULL, /* rmdir */ NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ NULL /* permission */};static int __init isapnp_proc_init(void){ struct proc_dir_entry *p; isapnp_proc_entry = NULL; p = create_proc_entry("isapnp", S_IFREG | S_IRUGO | S_IWUSR, &proc_root); if (!p) return -ENOMEM; p->ops = &isapnp_info_entry_inode_operations; isapnp_proc_entry = p; return 0;}#ifdef MODULEstatic int isapnp_proc_done(void){ if (isapnp_proc_entry) remove_proc_entry("isapnp",&proc_root); return 0;}#endif /* MODULE *//* * */static void isapnp_print_devid(isapnp_info_buffer_t *buffer, unsigned short vendor, unsigned short device){ char tmp[8]; sprintf(tmp, "%c%c%c%x%x%x%x", 'A' + ((vendor >> 2) & 0x3f) - 1, 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1, 'A' + ((vendor >> 8) & 0x1f) - 1, (device >> 4) & 0x0f, device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f); isapnp_printf(buffer, tmp);}static void isapnp_print_compatible(isapnp_info_buffer_t *buffer, struct pnp_dev *dev){ int idx; for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++) { if (dev->vendor_compatible[idx] == 0) continue; isapnp_printf(buffer, " Compatible device "); isapnp_print_devid(buffer, dev->vendor_compatible[idx], dev->device_compatible[idx]); isapnp_printf(buffer, "\n"); }}static void isapnp_print_port(isapnp_info_buffer_t *buffer, char *space, struct isapnp_port *port){ isapnp_printf(buffer, "%sPort 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n", space, port->min, port->max, port->align ? (port->align-1) : 0, port->size, port->flags & ISAPNP_PORT_FLAG_16BITADDR ? 16 : 10);}static void isapnp_print_irq(isapnp_info_buffer_t *buffer, char *space, struct isapnp_irq *irq){ int first = 1, i; isapnp_printf(buffer, "%sIRQ ", space); for (i = 0; i < 16; i++) if (irq->map & (1<<i)) { if (!first) { isapnp_printf(buffer, ","); } else { first = 0; } if (i == 2 || i == 9) isapnp_printf(buffer, "2/9"); else isapnp_printf(buffer, "%i", i); } if (!irq->map) isapnp_printf(buffer, "<none>"); if (irq->flags & IORESOURCE_IRQ_HIGHEDGE) isapnp_printf(buffer, " High-Edge"); if (irq->flags & IORESOURCE_IRQ_LOWEDGE) isapnp_printf(buffer, " Low-Edge"); if (irq->flags & IORESOURCE_IRQ_HIGHLEVEL) isapnp_printf(buffer, " High-Level"); if (irq->flags & IORESOURCE_IRQ_LOWLEVEL) isapnp_printf(buffer, " Low-Level"); isapnp_printf(buffer, "\n");}static void isapnp_print_dma(isapnp_info_buffer_t *buffer, char *space, struct isapnp_dma *dma){ int first = 1, i; char *s; isapnp_printf(buffer, "%sDMA ", space); for (i = 0; i < 8; i++) if (dma->map & (1<<i)) { if (!first) { isapnp_printf(buffer, ","); } else { first = 0; } isapnp_printf(buffer, "%i", i); } if (!dma->map) isapnp_printf(buffer, "<none>"); switch (dma->flags & IORESOURCE_DMA_TYPE_MASK) { case IORESOURCE_DMA_8BIT: s = "8-bit"; break; case IORESOURCE_DMA_8AND16BIT: s = "8-bit&16-bit"; break; default: s = "16-bit"; } isapnp_printf(buffer, " %s", s); if (dma->flags & IORESOURCE_DMA_MASTER) isapnp_printf(buffer, " master"); if (dma->flags & IORESOURCE_DMA_BYTE) isapnp_printf(buffer, " byte-count"); if (dma->flags & IORESOURCE_DMA_WORD) isapnp_printf(buffer, " word-count"); switch (dma->flags & IORESOURCE_DMA_SPEED_MASK) { case IORESOURCE_DMA_TYPEA: s = "type-A"; break; case IORESOURCE_DMA_TYPEB: s = "type-B"; break; case IORESOURCE_DMA_TYPEF: s = "type-F"; break; default: s = "compatible"; break; } isapnp_printf(buffer, " %s\n", s);}static void isapnp_print_mem(isapnp_info_buffer_t *buffer, char *space, struct isapnp_mem *mem){ char *s; isapnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x", space, mem->min, mem->max, mem->align, mem->size); if (mem->flags & IORESOURCE_MEM_WRITEABLE) isapnp_printf(buffer, ", writeable"); if (mem->flags & IORESOURCE_MEM_CACHEABLE) isapnp_printf(buffer, ", cacheable"); if (mem->flags & IORESOURCE_MEM_RANGELENGTH) isapnp_printf(buffer, ", range-length"); if (mem->flags & IORESOURCE_MEM_SHADOWABLE) isapnp_printf(buffer, ", shadowable"); if (mem->flags & IORESOURCE_MEM_EXPANSIONROM) isapnp_printf(buffer, ", expansion ROM"); switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) { case IORESOURCE_MEM_8BIT: s = "8-bit"; break; case IORESOURCE_MEM_8AND16BIT: s = "8-bit&16-bit"; break; default: s = "16-bit"; } isapnp_printf(buffer, ", %s\n", s);}static void isapnp_print_mem32(isapnp_info_buffer_t *buffer, char *space, struct isapnp_mem32 *mem32){ int first = 1, i; isapnp_printf(buffer, "%s32-bit memory ", space); for (i = 0; i < 17; i++) { if (first) { first = 0; } else { isapnp_printf(buffer, ":"); } isapnp_printf(buffer, "%02x", mem32->data[i]); }}static void isapnp_print_resources(isapnp_info_buffer_t *buffer, char *space, struct isapnp_resources *res){ char *s; struct isapnp_port *port; struct isapnp_irq *irq; struct isapnp_dma *dma; struct isapnp_mem *mem; struct isapnp_mem32 *mem32; switch (res->priority) { case ISAPNP_RES_PRIORITY_PREFERRED: s = "preferred"; break; case ISAPNP_RES_PRIORITY_ACCEPTABLE: s = "acceptable"; break; case ISAPNP_RES_PRIORITY_FUNCTIONAL: s = "functional"; break; default: s = "invalid"; } isapnp_printf(buffer, "%sPriority %s\n", space, s); for (port = res->port; port; port = port->next) isapnp_print_port(buffer, space, port); for (irq = res->irq; irq; irq = irq->next) isapnp_print_irq(buffer, space, irq); for (dma = res->dma; dma; dma = dma->next) isapnp_print_dma(buffer, space, dma); for (mem = res->mem; mem; mem = mem->next) isapnp_print_mem(buffer, space, mem); for (mem32 = res->mem32; mem32; mem32 = mem32->next) isapnp_print_mem32(buffer, space, mem32);}static void isapnp_print_configuration(isapnp_info_buffer_t *buffer, struct pnp_dev *dev){ int i, tmp, next; char *space = " "; isapnp_cfg_begin(dev->bus->number, dev->devfn); isapnp_printf(buffer, "%sDevice is %sactive\n", space, isapnp_read_byte(ISAPNP_CFG_ACTIVATE)?"":"not "); for (i = next = 0; i < 8; i++) { tmp = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1)); if (!tmp) continue; if (!next) { isapnp_printf(buffer, "%sActive port ", space); next = 1; } isapnp_printf(buffer, "%s0x%x", i > 0 ? "," : "", tmp); } if (next) isapnp_printf(buffer, "\n");
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -