E s driver impresora
This presentation is the property of its rightful owner.
Sponsored Links
1 / 24

E/S Driver Impresora PowerPoint PPT Presentation


  • 72 Views
  • Uploaded on
  • Presentation posted in: General

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

Download Presentation

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


E s driver impresora

E/SDriver Impresora

  • Airam Godoy Hernández

  • Jose Yeray Suárez Perdomo


Entrada salida 1

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


Entrada salida 2

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


Modo bloque

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,…


Modo car cter

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


Driver de impresora

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


Estructuras

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


Struct lp struct

Struct lp_struct


Struct file operations

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};


Funciones de gesti n de la impresora con spolled

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.


Funciones de gesti n de la impresora con interrupciones

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.


Operaciones de e s sobre archivo i

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


Operaciones de e s sobre archivo ii

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


Funciones de inicializaci n

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)


Lp char polled

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;}


Lp wite spolled

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;}


Lp char interrupt

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;}


Lp interrupt

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);

  • }


Lp wite interrupt

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;}


Lp write y lp seek

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;}


Lp open

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;}


Lp release

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;

  • }


Lp init

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;}


Lp ioctl

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;

  • }


  • Login