1 / 24

E/S Driver Impresora

E/S Driver Impresora. Airam Godoy Hernández Jose Yeray Suárez Perdomo. Entrada/Salida(1). Se accede mediante el uso de archivos especiales ( /dev ). Este tipo de archivos tienen tres características: 1.-El número que identifica al controlados

kalani
Télécharger la présentation

E/S Driver Impresora

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. E/SDriver Impresora • Airam Godoy Hernández • Jose Yeray Suárez Perdomo

  2. Entrada/Salida(1) • Se accede mediante el uso de archivos especiales (/dev). • Este tipo de archivos tienen tres características: • 1.-El número que identifica al controlados • 2.-El número que identifica al dispositivo físico • 3.-Modo de funcionamiento • Modo bloque • Modo carácter

  3. Entrada/Salida(2) • Peticiones de acceso manejadas por el controlador • Este interactúa con el dispositivo físico • Primitivas para leer y escribir iguales a las usadas en archivos regulares

  4. Modo bloque • Corresponden a dispositivos estructurados • Se accede proporcionando el número de bloque. • Las E/S se realizan mediante la función del búfer caché. • También puede trabajar en modo carácter. • Implementación más confusa por necesitar más velocidad. • Ejemplo: El diskette, disco duro,…

  5. Modo carácter • Corresponden a dispositivos no estructurados • Pueden ser accedidos como una corriente de bytes, como un fichero. • Se leen y escriben los datos byte a byte. • Se accede de forma secuencial (no permite retrocesos) • Son bastantes transparentes

  6. Driver de impresora • Modo carácter • Puede utilizar dos métodos diferentes para dialogar con el puerto • Interrupciones • Mediante las IRQ • Exploracion • Mediante bucles que comprueba el registro de estado de los puertos • Permite evitar que se produzcan numerosas interrupciones

  7. Estructuras • Se definen mediante descriptores localizados en la tabla lp_table • El tamaño de lp_table es 8 por defecto (#define LP_NO 8) • Cada posicion contiene información de la impresora, mediante lp_struct (struct lp_struct lp_table[LP_NO];) • Se encuentra definida en lp.h • Especifica el tipo de cada uno de los elementos

  8. Struct lp_struct

  9. Struct file_operations • static struct file_operations lp_fops = { • lp_lseek, • NULL, /* lp_read */ • lp_write, • NULL, /* lp_readdir */ • NULL, /* lp_select */ • lp_ioctl, • NULL, /* lp_mmap */ • lp_open, • lp_release};

  10. Funciones de gestión de la impresora con Spolled • La función lp_char_polled • Implementa el envio de un carácter • Efectúa un bucle de espera hasta que la impresora esté disponible de recibir un carácter • Si se envía correctamente devuelve un 1 sino un 0 • La función lp_write_polled • Implementa el envio de una serie carácter • Efectúa un bucle sobre cada carácter a imprimir • Imprime los caracteres llamando a lp_char_polled • Si se produce un error, el proceso se duerme, y se pone su estado a TASK_INTERRUPTIBLE.

  11. Funciones de gestión de la impresora con Interrupciones • La función lp_char_interrupt • Implementa el envio de un carácter • Efectúa un bucle hasta que la impresora esté disponible para recibir un carácter • Si se envía correctamente devuelve un 1 sino un 0 • La función lp_interrupt • Se llama cuando se produce una interrupción • Efectúa una búsqueda en la tabla lp_table para saber quien produjo la interrupción • Lama a wake_up para despertar el proceso en espera en lp_wait_q • La función lp_write_interrupt • Implementa el envio de una serie carácter • Efectúa un bucle sobra cada carácter a imprimir • Imprime los caracteres llamando a lp_char_interrupt • Si se produce un error, el proceso se duerme,se añade a lp_wait_q, y se pone su estado a TASK_INTERRUPTIBLE.

  12. Operaciones de E/S sobre archivo(I) • La función lp_write • implementa la operación sobre el archivo write • Esta llama a la función correspondiente según el modo • La función lp_seek • implementa la operación sobre el archivo lseek • Devuelve el error ESPIPE • La función lp_ioctl • implementa la operación sobre el archivo ioctl • Permite modificar o consultar los parámetros de la impresora

  13. Operaciones de E/S sobre archivo(II) • La función lp_open • implementa la operación sobre el archivo open • Verifica que la impresora existe y que no es usada por otro proceso • Inicializa la impresora • Marca la impresora como ocupada • La función lp_release • implementa la operación sobre el archivo release • Marca la impresora como desocupada

  14. Funciones de inicialización • La función lp_probe • Comprueba la presencia de un puerto paralelo • Inicializa su descriptor • La función lp_init • Se llama al inicializarse el sistema, o en la carga del gestor en forma de módulo • Registra el gestor ( llamada a register_chrdev) , indicando la operaciones asociadas al archivo • Efectúa un bucle de reconocimiento de los puertos posibles (llamada a lp_probe)

  15. Lp_char_polled • Implementa el envio de un carácter • static int lp_char_polled(char lpchar, int minor) • { int status = 0, wait = 0;unsigned long count = 0; • Efectúa un bucle de espera hasta que la impresora esté disponible de recibir un carácter • do { • status = LP_S(minor); • count ++; • } while(!(status & LP_PBUSY) && count < LP_CHAR(minor)); • Si se envía correctamente devuelve un 1 sino un 0 • if (count == LP_CHAR(minor)) return 0; • outb_p(lpchar, LP_B(minor)); • while(wait != LP_WAIT(minor)) wait++; • outb_p(( LP_PSELECP | LP_PINITP | LP_PSTROBE ), ( LP_C( minor ))); • while(wait) wait--; • outb_p(( LP_PSELECP | LP_PINITP ), ( LP_C( minor ))); • return 1;}

  16. Lp_wite_spolled • Implementa el envio de una serie carácter • static int lp_write_polled(struct inode * inode, struct file * file, char * buf, int count) • { int retval; unsigned int minor = MINOR(inode->i_rdev); char c, *temp = buf;+ • temp = buf; • Efectúa un bucle sobra cada carácter a imprimir • while (count > 0) { • c = get_fs_byte(temp); • Imprime los caracteres llamando a lp_char_polled • retval = lp_char_polled(c, minor); • if (retval) { count--; temp++;} • Si se produce un error, el proceso se duerme, y se pone su estado a TASK_INTERRUPTIBLE. • if (!retval) { • current->state = TASK_INTERRUPTIBLE; • current->timeout = jiffies + LP_TIME(minor); • schedule(); • } • return temp-buf;}

  17. Lp_char_interrupt • Implementa el envio de un carácter • static int lp_char_interrupt(char lpchar, int minor) • {int wait = 0; unsigned char status; • Efectúa un bucle, durante el cual, espera que la impresora esté disponible de recibir un carácter • if (!((status = LP_S(minor)) & LP_PACK) || (status & LP_PBUSY) • || !((status = LP_S(minor)) & LP_PACK) || (status & LP_PBUSY) • || !((status = LP_S(minor)) & LP_PACK) || (status & LP_PBUSY)) { • outb_p(lpchar, LP_B(minor)); • while(wait != LP_WAIT(minor)) wait++; • while(wait) wait--; • outb_p(( LP_PSELECP | LP_PINITP ), ( LP_C( minor ))); • return 1; • } • Si se envía correctamente devuelve un 1 sino un 0 • return 0;}

  18. Lp_interrupt • Se llama cuando se produce una interrupción • static void lp_interrupt(int irq) • { struct lp_struct *lp = &lp_table[0]; • struct lp_struct *lp_end = &lp_table[LP_NO]; • Efectúa una búsqueda en la tabla lp_table para saber quien produjo la interrupción • while (irq != lp->irq) { • if (++lp >= lp_end) • return; • } • Lama a wake_up para despertar el proceso en espera en lp_wait_q • wake_up(&lp->lp_wait_q); • }

  19. Lp_wite_interrupt • Implementa el envio de una serie carácter • static int lp_write_interrupt(struct inode * inode, struct file * file, char * buf, int count) • { unsigned int minor = MINOR(inode->i_rdev); unsigned long copy_size; unsigned long total_bytes_written = 0; • unsigned long bytes_written; struct lp_struct *lp = &lp_table[minor]; unsigned char status; • Efectúa un bucle sobra cada carácter a imprimir • do { bytes_written = 0; • copy_size = (count <= LP_BUFFER_SIZE ? count : LP_BUFFER_SIZE); • memcpy_fromfs(lp->lp_buffer, buf, copy_size); • while (copy_size) { • Imprime los caracteres llamando a lp_char_interrupt • if (lp_char_interrupt(lp->lp_buffer[bytes_written], minor)) {--copy_size; ++bytes_written;} • Si se produce un error, el proceso se duerme,se añade a lp_wait_q, y se pone su estado a TASK_INTERRUPTIBLE. • outb_p((LP_PSELECP|LP_PINITP|LP_PINTEN), (LP_C(minor))); • status = LP_S(minor); • current->timeout = jiffies + LP_TIMEOUT_INTERRUPT; • interruptible_sleep_on(&lp->lp_wait_q); • outb_p((LP_PSELECP|LP_PINITP), (LP_C(minor))); • total_bytes_written += bytes_written; buf += bytes_written; count -= bytes_written; • } while (count > 0); • return total_bytes_written;}

  20. Lp_write y lp_seek • Implementa la operación sobre el archivo write • static int lp_write(struct inode * inode, struct file * file, char * buf, int count) • Esta llama a la función correspondiente según el modo if (LP_IRQ(MINOR(inode->i_rdev))) return lp_write_interrupt(inode, file, buf, count); • else return lp_write_polled(inode, file, buf, count);} • Implementa la operación sobre el archivo lseek • static int lp_lseek(struct inode * inode, struct file * file,off_t offset, int origin) • Devuelve el error ESPIPE • {return -ESPIPE;}

  21. Lp_open • static int lp_open(struct inode * inode, struct file * file) • { unsigned int minor = MINOR(inode->i_rdev); int ret; unsigned int irq; struct sigaction sa; • Verifica que la impresora existe y que no es usada por otro proceso • if (minor >= LP_NO) return -ENODEV; • if ((LP_F(minor) & LP_EXIST) == 0) return -ENODEV; • if (LP_F(minor) & LP_BUSY) return -EBUSY; • Inicializa la impresora • if ((irq = LP_IRQ(minor))) { • sa.sa_handler = lp_interrupt; • sa.sa_flags = SA_INTERRUPT; • sa.sa_mask = 0; • sa.sa_restorer = NULL; • ret = irqaction(irq, &sa); • if (ret) { kfree_s(lp_table[minor].lp_buffer, LP_BUFFER_SIZE); • lp_table[minor].lp_buffer = NULL; • printk("lp%d unable to use interrupt %d, error %d\n", minor, irq, ret); • return ret;}} • Marca la impresora como ocupada • LP_F(minor) |= LP_BUSY; • return 0;}

  22. Lp_release • Implementa la operación sobre el archivo release • static void lp_release(struct inode * inode, struct file * file) • { • unsigned int minor = MINOR(inode->i_rdev); • unsigned int irq; • Marca la impresora como desocupada • if ((irq = LP_IRQ(minor))) { • free_irq(irq); • kfree_s(lp_table[minor].lp_buffer, LP_BUFFER_SIZE); • lp_table[minor].lp_buffer = NULL; • } • LP_F(minor) &= ~LP_BUSY; • }

  23. Lp_init • Se llama al inicializarse el sistema, o en la carga del gestor en forma de módulo • long lp_init(long kmem_start) • { int offset = 0;unsigned int testvalue = 0;int count = 0; • Registra el gestor ( llamada a register_chrdev) , indicando la operaciones asociadas al archivo • if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) { • printk("unable to get major %d for line printer\n", LP_MAJOR); • return kmem_start; } • Efectúa un bucle de reconocimiento de los puertos posibles (llamada a lp_probe) • for (offset = 0; offset < LP_NO; offset++) { • outb_p( LP_DUMMY, LP_B(offset)); • for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++) • testvalue = inb_p(LP_B(offset)); • if (testvalue != 255) { • LP_F(offset) |= LP_EXIST; • lp_reset(offset); • printk("lp_init: lp%d exists (%d), ", offset, testvalue); • if (LP_IRQ(offset)) printk("using IRQ%d\n", LP_IRQ(offset)); • else printk("using polling driver\n"); • count++; • }} • if (count == 0) printk("lp_init: no lp devices found\n"); return kmem_start;}

  24. Lp_ioctl • implementa la operación sobre el archivo ioctl • static int lp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) • { unsigned int minor = MINOR(inode->i_rdev);int retval = 0; • if (minor >= LP_NO) return -ENODEV; • if ((LP_F(minor) & LP_EXIST) == 0) return -ENODEV; • Permite modificar o consultar los parámetros de la impresora • switch ( cmd ) {case LPTIME: LP_TIME(minor) = arg; break; • case LPCHAR:LP_CHAR(minor) = arg; break; • case LPABORT: if (arg) LP_F(minor) |= LP_ABORT; • else LP_F(minor) &= ~LP_ABORT; break; • case LPWAIT: LP_WAIT(minor) = arg; break; • case LPGETIRQ: retval = LP_IRQ(minor); break; • default: retval = -EINVAL; } • return retval; • }

More Related