[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tyndur-devel] [PATCH] cdi: CD-ROM-Unterstuetzung



On Sat, Jan 03 21:19, Kevin Wolf wrote:
> + cdi: Storage: Zusaetzliche Funktionen get_size() und get_block_size(), da SCSI-Geraete die Variablen nicht haben
> + cdi: SCSI: Grundfunktionalitaet
> + cdi: SCSI: Storage-Backend scsi/disk (momentan nur fuer CD-ROM geeignet)
> * cdi: Storage nimmt jetzt auch SCSI-Geraete
> * cdi: Storage-Treiber und -Geraete werden einzeln initialisiert
> * ata/floppy: An geaenderte Interfaces geanpasst
> ---
>  src/modules/cdi/ata/atapi.c           |    3 +
>  src/modules/cdi/ata/device.c          |   19 ++-
>  src/modules/cdi/ata/device.h          |    6 +-
>  src/modules/cdi/ata/main.c            |    4 +-
>  src/modules/cdi/floppy/device.c       |   29 +++-
>  src/modules/cdi/floppy/device.h       |    6 +-
>  src/modules/cdi/floppy/main.c         |    8 +-
>  src/modules/cdi/include/cdi.h         |    3 +-
>  src/modules/cdi/include/cdi/scsi.h    |   86 +++++++++++
>  src/modules/cdi/include/cdi/storage.h |   19 ++-
>  src/modules/cdi/lib/cdi.c             |    1 +
>  src/modules/cdi/lib/scsi/disk.c       |  264 +++++++++++++++++++++++++++++++++
>  src/modules/cdi/lib/scsi/driver.c     |   56 +++++++
>  src/modules/cdi/lib/storage.c         |   89 ++++++++----
>  14 files changed, 546 insertions(+), 47 deletions(-)
>  create mode 100644 src/modules/cdi/include/cdi/scsi.h
>  create mode 100644 src/modules/cdi/lib/scsi/disk.c
>  create mode 100644 src/modules/cdi/lib/scsi/driver.c
> 
> diff --git a/src/modules/cdi/ata/atapi.c b/src/modules/cdi/ata/atapi.c
> index 67dc140..ecff315 100644
> --- a/src/modules/cdi/ata/atapi.c
> +++ b/src/modules/cdi/ata/atapi.c
> @@ -86,7 +86,10 @@ int atapi_drv_identify(struct ata_device* dev)
>  
>  void atapi_init_device(struct cdi_device* device)
>  {
> +    struct cdi_scsi_device* scsi = (struct cdi_scsi_device*) device;
>  
> +    scsi->type = CDI_STORAGE;
> +    cdi_scsi_device_init(scsi);
>  }
>  
>  void atapi_remove_device(struct cdi_device* device)
> diff --git a/src/modules/cdi/ata/device.c b/src/modules/cdi/ata/device.c
> index f9ccf21..b9763d4 100644
> --- a/src/modules/cdi/ata/device.c
> +++ b/src/modules/cdi/ata/device.c
> @@ -333,6 +333,8 @@ void ata_remove_controller(struct ata_controller* controller)
>  
>  void ata_init_device(struct cdi_device* device)
>  {
> +    struct ata_device* dev = (struct ata_device*) device;
> +    cdi_storage_device_init(&dev->dev.storage);
>  }
>  
>  void ata_remove_device(struct cdi_device* device)
> @@ -344,7 +346,7 @@ void ata_remove_device(struct cdi_device* device)
>  /**
>   * Blocks von einem ATA(PI) Geraet lesen
>   */
> -int ata_read_blocks(struct cdi_storage_device* device, uint64_t block,
> +int ata_read_blocks(struct cdi_device* device, uint64_t block,
>      uint64_t count, void* buffer)
>  {
>      struct ata_device* dev = (struct ata_device*) device;
> @@ -374,7 +376,7 @@ int ata_read_blocks(struct cdi_storage_device* device, uint64_t block,
>  /**
>   * Blocks auf ein ATA(PI) Geraet schreiben
>   */
> -int ata_write_blocks(struct cdi_storage_device* device, uint64_t block,
> +int ata_write_blocks(struct cdi_device* device, uint64_t block,
>      uint64_t count, void* buffer)
>  {
>      struct ata_device* dev = (struct ata_device*) device;
> @@ -401,3 +403,16 @@ int ata_write_blocks(struct cdi_storage_device* device, uint64_t block,
>      }
>  }
>  
> +uint64_t ata_get_size(struct cdi_device* device)
> +{
> +    struct cdi_storage_device* storage = (struct cdi_storage_device*) device;
> +
> +    return storage->block_size * storage->block_count;
> +}
> +
> +uint64_t ata_get_block_size(struct cdi_device* device)
> +{
> +    struct cdi_storage_device* storage = (struct cdi_storage_device*) device;
> +
> +    return storage->block_size;
> +}
> diff --git a/src/modules/cdi/ata/device.h b/src/modules/cdi/ata/device.h
> index 140f037..eaa890a 100644
> --- a/src/modules/cdi/ata/device.h
> +++ b/src/modules/cdi/ata/device.h
> @@ -411,11 +411,13 @@ void ata_init_controller(struct ata_controller* controller);
>  void ata_remove_controller(struct ata_controller* controller);
>  void ata_init_device(struct cdi_device* device);
>  void ata_remove_device(struct cdi_device* device);
> -int ata_read_blocks(struct cdi_storage_device* device, uint64_t block,
> +int ata_read_blocks(struct cdi_device* device, uint64_t block,
>      uint64_t count, void* buffer);
> -int ata_write_blocks(struct cdi_storage_device* device, uint64_t block,
> +int ata_write_blocks(struct cdi_device* device, uint64_t block,
>      uint64_t count, void* buffer);
>  
> +uint64_t ata_get_size(struct cdi_device* device);
> +uint64_t ata_get_block_size(struct cdi_device* device);
>  
>  // Einen ATA-Request absenden und ausfuehren
>  int ata_request(struct ata_request* request);
> diff --git a/src/modules/cdi/ata/main.c b/src/modules/cdi/ata/main.c
> index 750f7b2..18e7225 100644
> --- a/src/modules/cdi/ata/main.c
> +++ b/src/modules/cdi/ata/main.c
> @@ -80,7 +80,7 @@ static void ata_driver_init()
>      // Konstruktor der Vaterklasse
>      cdi_storage_driver_init((struct cdi_storage_driver*) &driver_storage);
>      cdi_scsi_driver_init((struct cdi_scsi_driver*) &driver_scsi);

Hm sicher dass dein diff hier korrekt ist? Haben wir da wirklich schon
ein cdi_scsi_driver_init drin? :-/

> -    
> +

Und hier haben wir noch eine Whitespace Änderung, sowas aber auch. ;-)

>      // Namen setzen
>      driver_storage.drv.name = driver_storage_name;
>      driver_scsi.drv.name = driver_scsi_name;
> @@ -91,6 +91,8 @@ static void ata_driver_init()
>      driver_storage.drv.remove_device    = ata_remove_device;
>      driver_storage.read_blocks          = ata_read_blocks;
>      driver_storage.write_blocks         = ata_write_blocks;
> +    driver_storage.get_size             = ata_get_size;
> +    driver_storage.get_block_size       = ata_get_block_size;
>  
>      driver_scsi.drv.destroy             = atapi_driver_destroy;
>      driver_scsi.drv.init_device         = atapi_init_device;
> diff --git a/src/modules/cdi/floppy/device.c b/src/modules/cdi/floppy/device.c
> index 6614e1e..4435630 100644
> --- a/src/modules/cdi/floppy/device.c
> +++ b/src/modules/cdi/floppy/device.c
> @@ -796,6 +796,8 @@ void floppy_init_device(struct cdi_device* device)
>  
>      dev->dev.block_size = FLOPPY_SECTOR_SIZE(dev);
>      dev->dev.block_count = FLOPPY_SECTOR_COUNT(dev);
> +
> +    cdi_storage_device_init(&dev->dev);
>  }
>  
>  /**
> @@ -808,7 +810,7 @@ void floppy_remove_device(struct cdi_device* device)
>  /**
>   * Sektoren einlesen
>   */
> -int floppy_read_blocks(struct cdi_storage_device* dev, uint64_t block,
> +int floppy_read_blocks(struct cdi_device* dev, uint64_t block,
>      uint64_t count, void* buffer)
>  {
>      struct floppy_device* device = (struct floppy_device*) dev;
> @@ -823,7 +825,7 @@ int floppy_read_blocks(struct cdi_storage_device* dev, uint64_t block,
>          // Wenn das schief geht, wird mehrmals probiert
>          for (j = 0; (j < 5) && (result != 0); j++) {
>              result = floppy_drive_sector_read(device, (uint32_t) block + i,
> -                buffer + i * dev->block_size);
> +                buffer + i * device->dev.block_size);
>          }
>      }
>  
> @@ -833,7 +835,7 @@ int floppy_read_blocks(struct cdi_storage_device* dev, uint64_t block,
>  /**
>   * Sektoren schreiben
>   */
> -int floppy_write_blocks(struct cdi_storage_device* dev, uint64_t block,
> +int floppy_write_blocks(struct cdi_device* dev, uint64_t block,
>      uint64_t count, void* buffer)
>  {
>      struct floppy_device* device = (struct floppy_device*) dev;
> @@ -848,13 +850,32 @@ int floppy_write_blocks(struct cdi_storage_device* dev, uint64_t block,
>          // Wenn das schief geht, wird mehrmals probiert
>          for (j = 0; (j < 5) && (result != 0); j++) {
>              result = floppy_drive_sector_write(device, (uint32_t) block + i,
> -                buffer + i * dev->block_size);
> +                buffer + i * device->dev.block_size);
>          }
>      }
>  
>      return result;
>  }
>  
> +/**
> + * Gibt die Groesse des Mediums zurueck
> + */
> +uint64_t floppy_get_size(struct cdi_device* device)
> +{
> +    struct cdi_storage_device* storage = (struct cdi_storage_device*) device;
> +
> +    return storage->block_size * storage->block_count;
> +}
> +
> +/**
> + * Gibt die Sektorgroesse des Mediums zurueck
> + */
> +uint64_t floppy_get_block_size(struct cdi_device* device)
> +{
> +    struct cdi_storage_device* storage = (struct cdi_storage_device*) device;
> +
> +    return storage->block_size;
> +}
>  
>  /**
>   * IRQ-Handler fuer den Kontroller; Erhoeht nur den IRQ-Zaehler in der
> diff --git a/src/modules/cdi/floppy/device.h b/src/modules/cdi/floppy/device.h
> index 24d16f9..6c3bfcf 100644
> --- a/src/modules/cdi/floppy/device.h
> +++ b/src/modules/cdi/floppy/device.h
> @@ -137,10 +137,12 @@ int floppy_init_controller(struct floppy_controller* controller);
>  
>  void floppy_init_device(struct cdi_device* device);
>  void floppy_remove_device(struct cdi_device* device);
> -int floppy_read_blocks(struct cdi_storage_device* device, uint64_t block,
> +int floppy_read_blocks(struct cdi_device* device, uint64_t block,
>      uint64_t count, void* buffer);
> -int floppy_write_blocks(struct cdi_storage_device* device, uint64_t block,
> +int floppy_write_blocks(struct cdi_device* device, uint64_t block,
>      uint64_t count, void* buffer);
> +uint64_t floppy_get_size(struct cdi_device* device);
> +uint64_t floppy_get_block_size(struct cdi_device* device);
>  
>  void floppy_handle_interrupt(struct cdi_device* device);
>  
> diff --git a/src/modules/cdi/floppy/main.c b/src/modules/cdi/floppy/main.c
> index 435ff1f..aa32ed5 100644
> --- a/src/modules/cdi/floppy/main.c
> +++ b/src/modules/cdi/floppy/main.c
> @@ -87,7 +87,7 @@ static int floppy_driver_init(struct floppy_driver* driver)
>  
>      // Konstruktor der Vaterklasse
>      cdi_storage_driver_init((struct cdi_storage_driver*) driver);
> -    
> +

Schon wieder nur leerzeichen entfernt

>      // Namen setzen
>      driver->storage.drv.name = driver_name;
>  
> @@ -95,9 +95,11 @@ static int floppy_driver_init(struct floppy_driver* driver)
>      driver->storage.drv.destroy         = floppy_driver_destroy;
>      driver->storage.drv.init_device     = floppy_init_device;
>      driver->storage.drv.remove_device   = floppy_remove_device;
> -    driver->storage.read_blocks         = floppy_read_blocks; 
> +    driver->storage.read_blocks         = floppy_read_blocks;

Hier auch wieder

>      driver->storage.write_blocks        = floppy_write_blocks;
> -    
> +    driver->storage.get_size            = floppy_get_size;
> +    driver->storage.get_block_size      = floppy_get_block_size;
> +
>      // Geraete erstellen (TODO: Was wenn eines oder beide nicht vorhanden
>      // sind?)
>      for (i = 0; i < 2; i++) {
> diff --git a/src/modules/cdi/include/cdi.h b/src/modules/cdi/include/cdi.h
> index 42e4643..5fb7025 100644
> --- a/src/modules/cdi/include/cdi.h
> +++ b/src/modules/cdi/include/cdi.h
> @@ -23,7 +23,8 @@
>  typedef enum {
>      CDI_UNKNOWN         = 0,
>      CDI_NETWORK         = 1,
> -    CDI_STORAGE         = 2
> +    CDI_STORAGE         = 2,
> +    CDI_SCSI            = 3,
>  } cdi_device_type_t;
>  
>  struct cdi_driver;
> diff --git a/src/modules/cdi/include/cdi/scsi.h b/src/modules/cdi/include/cdi/scsi.h
> new file mode 100644
> index 0000000..78f0c30
> --- /dev/null
> +++ b/src/modules/cdi/include/cdi/scsi.h
> @@ -0,0 +1,86 @@

Gibts hier keinen Lizenzheader?

Dann könntest du auch noch gleich die Doxygen-Anweisungen reinpacken,
damit das ins SCSI-Modul kommt.

> +#ifndef _CDI_SCSI_H_
> +#define _CDI_SCSI_H_
> +
> +#include <stdint.h>
> +#include <stddef.h>
> +
> +#include "cdi.h"
> +
> +// SCSI-Paket

Hier bitte alles so kommentieren dass Doxygen es versteht, also entweder
/** blub */ oder /// blub.

> +struct cdi_scsi_packet {
> +  // Buffer zum Senden oder Empfangen von Daten
> +  void *buffer;
> +
> +  // Groesse des Buffers
> +  size_t bufsize;
> +
> +  // Ob gelesen oder geschrieben werden soll
> +  enum {
> +    CDI_SCSI_NODATA,
> +    CDI_SCSI_READ,
> +    CDI_SCSI_WRITE,
> +  } direction;
> +
> +  // SCSI Command
> +  uint8_t command[16];
> +
> +  // Groesse des SCSI Commands
> +  size_t cmdsize;
> +};
> +
> +// SCSI-Geraet
> +struct cdi_scsi_device {
> +
> +    struct cdi_device dev;
> +
> +    // Geraetetyp, der ueber SCSI angesteuert wird
> +    cdi_device_type_t type;
> +
> +};
> +
> +// SCSI-Driver
> +struct cdi_scsi_driver {
> +  struct cdi_driver drv;
> +

Hier hätte ich eigentlich auch irgend einen kommentar erwartet.

> +  int (*request)(struct cdi_scsi_device *device,struct cdi_scsi_packet *packet);
> +};
> +
> +/**
> + * Ein SCSI-Paket allozieren
> + *
> + * @param size Benoetigte Groesse
> + *
> + * @return Pointer auf das Paket oder NULL im Fehlerfall
> + */
> +struct cdi_scsi_packet* cdi_scsi_packet_alloc(size_t size);
> +
> +/**
> + * Ein SCSI-Paket freigeben
> + *
> + * @param packet Pointer auf das Paket
> + */
> +void cdi_scsi_packet_free(struct cdi_scsi_packet* packet);
> +
> +/**
> + * Initialisiert die Datenstrukturen fuer einen SCSI-Treiber
> + */
> +void cdi_scsi_driver_init(struct cdi_scsi_driver* driver);
> +
> +/**
> + * Deinitialisiert die Datenstrukturen fuer einen SCSI-Treiber
> + */
> +void cdi_scsi_driver_destroy(struct cdi_scsi_driver* driver);
> +
> +/**
> + * Registiert einen SCSI-Treiber
> + */
> +void cdi_scsi_driver_register(struct cdi_scsi_driver* driver);
> +
> +/**
> + * Initialisiert ein neues SCSI-Geraet
> + *
> + * Der Typ der Geraetes muss bereits gesetzt sein
> + */
> +void cdi_scsi_device_init(struct cdi_scsi_device* device);
> +
> +#endif
> diff --git a/src/modules/cdi/include/cdi/storage.h b/src/modules/cdi/include/cdi/storage.h
> index 73ae245..781a158 100644
> --- a/src/modules/cdi/include/cdi/storage.h
> +++ b/src/modules/cdi/include/cdi/storage.h
> @@ -40,7 +40,7 @@ struct cdi_storage_driver {
>       *
>       * @return 0 bei Erfolg, -1 im Fehlerfall.
>       */
> -    int (*read_blocks)(struct cdi_storage_device* device, uint64_t start,
> +    int (*read_blocks)(struct cdi_device* device, uint64_t start,
>          uint64_t count, void* buffer);
>      
>      /**
> @@ -53,8 +53,18 @@ struct cdi_storage_driver {
>       *
>       * @return 0 bei Erfolg, -1 im Fehlerfall
>       */
> -    int (*write_blocks)(struct cdi_storage_device* device, uint64_t start,
> +    int (*write_blocks)(struct cdi_device* device, uint64_t start,
>          uint64_t count, void* buffer);
> +
> +    /**
> +     * Gibt die Groesse des Mediums in Bytes zurueck
> +     */
> +    uint64_t (*get_size)(struct cdi_device* device);
> +
> +    /**
> +     * Gibt die Blockgroesse des Geraets in Bytes zurueck
> +     */
> +    uint64_t (*get_block_size)(struct cdi_device* device);
>  };
>  
>  
> @@ -75,6 +85,11 @@ void cdi_storage_driver_destroy(struct cdi_storage_driver* driver);
>   */
>  void cdi_storage_driver_register(struct cdi_storage_driver* driver);
>  
> +/**
> + * Initialisiert einen Massenspeicher
> + */
> +void cdi_storage_device_init(struct cdi_storage_device* device);
> +
>  #endif
>  
>  /*\@}*/
> diff --git a/src/modules/cdi/lib/cdi.c b/src/modules/cdi/lib/cdi.c
> index d8c7819..487887e 100644
> --- a/src/modules/cdi/lib/cdi.c
> +++ b/src/modules/cdi/lib/cdi.c
> @@ -86,6 +86,7 @@ void cdi_run_drivers(void)
>  
>          for (j = 0; (device = cdi_list_get(driver->devices, j)); j++) {
>              device->driver = driver;
> +            device->type = driver->type;
>  
>              if (driver->init_device) {
>                  driver->init_device(device);
> diff --git a/src/modules/cdi/lib/scsi/disk.c b/src/modules/cdi/lib/scsi/disk.c
> new file mode 100644
> index 0000000..9bd5a74
> --- /dev/null
> +++ b/src/modules/cdi/lib/scsi/disk.c
> @@ -0,0 +1,264 @@
> +/*
> + * Copyright (C) 2008 Mathias Gottschlag
> + * Copyright (C) 2009 Kevin Wolf
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to
> + * deal in the Software without restriction, including without limitation the
> + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
> + * sell copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + */

Hm müsste da nicht noch ein Hinweis in doc/COPYRIGHT?

> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdlib.h>
> +
> +#include <cdi/lists.h>
> +#include <cdi/scsi.h>
> +#include <cdi/storage.h>
> +
> +#define big_endian_word(x) ((((x) & 0xFF) << 8) | (((x) & 0xFF00) >> 8))
> +#define big_endian_dword(x) \
> +    ((big_endian_word((x) & 0xFFFF) << 16) | \
> +    (big_endian_word((x) >> 16)))
> +
> +static int cdi_scsi_disk_read(struct cdi_device* device,
> +    uint64_t start, uint64_t count, void* buffer);
> +
> +static int cdi_scsi_disk_write(struct cdi_device* device,
> +    uint64_t start, uint64_t count, void* buffer);
> +
> +static uint64_t cdi_scsi_disk_get_size(struct cdi_device* device);
> +static uint64_t cdi_scsi_disk_get_block_size(struct cdi_device* device);
> +
> +struct cdi_storage_driver cdi_scsi_disk_driver = {
> +    .read_blocks    = cdi_scsi_disk_read,
> +    .write_blocks   = cdi_scsi_disk_write,
> +    .get_size       = cdi_scsi_disk_get_size,
> +    .get_block_size = cdi_scsi_disk_get_block_size,
> +};
> +
> +// TODO: This is kind of incomplete... -.-
> +// FIXME Das ist alles sehr CD-ROM-spezifisch hartkodiert...
> +
> +union cdrom_command
> +{
> +	struct
> +	{
> +		uint8_t opcode;
> +		uint8_t reserved0;
> +		uint32_t address;
> +		uint8_t reserved1;
> +		uint16_t length;
> +		uint8_t reserved2;
> +	} __attribute__ ((packed)) dfl;
> +	struct
> +	{
> +		uint8_t opcode;
> +		uint8_t reserved0;
> +		uint32_t address;
> +		uint32_t length;
> +		uint16_t reserved1;
> +	} __attribute__ ((packed)) ext;
> +};
> +
> +static int cdrom_read_sector(
> +    struct cdi_scsi_device *device, uint32_t sector, char *buffer)
> +{
> +	struct cdi_scsi_packet packet;
> +    struct cdi_scsi_driver* drv = (struct cdi_scsi_driver*) device->dev.driver;
> +    union cdrom_command* cmd = (union cdrom_command*) &packet.command;
> +
> +	memset(&packet, 0, sizeof(packet));
> +	packet.direction = CDI_SCSI_READ;
> +	packet.buffer = buffer;
> +	packet.bufsize = 2048;
> +	packet.cmdsize = 12;
> +
> +	cmd->ext.opcode = 0xA8;
> +	cmd->ext.address = big_endian_dword(sector);
> +	cmd->ext.length = 0x01000000;
> +
> +	if (drv->request(device, &packet)) {
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int cdrom_capacity(struct cdi_scsi_device *device,
> +    uint32_t* num_sectors, uint32_t* sector_size)
> +{
> +    uint32_t buffer[32];
> +	struct cdi_scsi_packet packet;
> +    struct cdi_scsi_driver* drv = (struct cdi_scsi_driver*) device->dev.driver;
> +    union cdrom_command* cmd = (union cdrom_command*) &packet.command;
> +
> +	memset(&packet, 0, sizeof(packet));
> +	packet.direction = CDI_SCSI_READ;
> +	packet.buffer = buffer;
> +	packet.bufsize = sizeof(buffer);
> +	packet.cmdsize = 12;
> +
> +	cmd->ext.opcode = 0x25;
> +
> +	if (drv->request(device, &packet)) {
> +		return -1;
> +	}
> +
> +    *num_sectors = big_endian_dword(buffer[0]);
> +    *sector_size = big_endian_dword(buffer[1]);
> +
> +	return 0;
> +}
> +
> +#if 0
> +static int cdrom_lock_device(FsSCSIDevice *device, int index, int lock)
> +{
> +	// Lock drive
> +	FsSCSIPacket packet;
> +	memset(&packet, 0, sizeof(FsSCSIPacket));
> +	packet.direction = CDI_SCSI_NO_DATA;
> +	((union cdrom_command*)packet.command)->dfl.opcode = 0x1E;
> +	packet.command[4] = 1;
> +	packet.buffer = 0;
> +	packet.length = 0;
> +	packet.commandsize = 12;
> +	uint32_t status = device->request(device, &packet);
> +	if (status)
> +	{
> +		kePrint("cdrom %d: Lock failed, %x\n", index, status);
> +		fsCloseSCSIDevice(device);
> +		return KE_ERROR_UNKNOWN;
> +	}
> +	return 0;
> +}
> +
> +static void cdrom_sense(FsSCSIDevice *device, uint32_t index)
> +{
> +	char sense_data[18];
> +	FsSCSIPacket packet;
> +	packet.direction = CDI_SCSI_READ;
> +	packet.buffer = sense_data;
> +	packet.length = 18;
> +	packet.commandsize = 12;
> +	((union cdrom_command*)packet.command)->dfl.opcode = 0x12;
> +}
> +#endif
> +
> +int cdrom_init(struct cdi_scsi_device* device)
> +{
> +	// Send inquiry command
> +    struct cdi_scsi_driver* drv = (struct cdi_scsi_driver*) device->dev.driver;
> +	struct cdi_scsi_packet packet;
> +	uint32_t status;
> +	unsigned char inqdata[96];
> +
> +	memset(&packet, 0, sizeof(packet));
> +	memset(inqdata, 0xF0, sizeof(inqdata));
> +
> +	packet.direction = CDI_SCSI_READ;
> +	packet.buffer = inqdata;
> +	packet.bufsize = 96;
> +	packet.cmdsize = 12;
> +
> +	((union cdrom_command*)packet.command)->dfl.opcode = 0x12;
> +	packet.command[4] = 96;
> +	status = drv->request(device, &packet);
> +	if (status)
> +	{
> +		return -1;
> +	}
> +
> +#if 0
> +	if (cdrom_lock_device(device, index, 1))
> +		return KE_ERROR_UNKNOWN;
> +#endif
> +
> +	// Start drive
> +	packet.direction = CDI_SCSI_NODATA;
> +	((union cdrom_command*)packet.command)->dfl.opcode = 0x1B;
> +	packet.buffer = 0;
> +	packet.bufsize = 0;
> +	packet.command[4] = 0;
> +	packet.command[4] = 3;
> +	packet.cmdsize = 12;
> +
> +	status = drv->request(device, &packet);
> +	if (status)
> +	{
> +		printf("cdrom %d: Start failed, %x\n", index, status);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int cdi_scsi_disk_read(struct cdi_device* device,
> +    uint64_t start, uint64_t count, void* buffer)
> +{
> +    struct cdi_scsi_device* dev = (struct cdi_scsi_device*) device;
> +
> +    while (count--) {
> +        if (cdrom_read_sector(dev, start, buffer)) {

Hm SCSI kann doch mehrere Sektoren in einem Rutsch lesen?

> +            return -1;
> +        }
> +        start ++;
> +        buffer += 2048;
> +    }
> +
> +    return 0;
> +}
> +
> +static int cdi_scsi_disk_write(struct cdi_device* device,
> +    uint64_t start, uint64_t count, void* buffer)
> +{
> +    return -1;
> +}
> +
> +static uint64_t cdi_scsi_disk_get_size(struct cdi_device* device)
> +{
> +    struct cdi_scsi_device* dev = (struct cdi_scsi_device*) device;
> +    uint32_t num_sectors, sector_size;
> +
> +
> +    // TODO Einmal beim Initialisieren eines Mediums einlesen und dann bei
> +    // jedem Aufruf wiederverwenden
> +    cdrom_capacity(dev, &num_sectors, &sector_size);
> +
> +    return num_sectors * sector_size;
> +}
> +
> +static uint64_t cdi_scsi_disk_get_block_size(struct cdi_device* device)
> +{
> +    struct cdi_scsi_device* dev = (struct cdi_scsi_device*) device;
> +    uint32_t num_sectors, sector_size;
> +
> +
> +    // TODO s.o.
> +    cdrom_capacity(dev, &num_sectors, &sector_size);
> +
> +    return sector_size;
> +}
> +
> +int lostio_mst_if_newdev(struct cdi_device* device);
> +
> +void cdi_scsi_disk_init(struct cdi_scsi_device* device)
> +{
> +    if (cdrom_init(device) == 0) {
> +        // LostIO-Verzeichnisknoten anlegen
> +        lostio_mst_if_newdev(&device->dev);
> +    }
> +}
> diff --git a/src/modules/cdi/lib/scsi/driver.c b/src/modules/cdi/lib/scsi/driver.c
> new file mode 100644
> index 0000000..745bd25
> --- /dev/null
> +++ b/src/modules/cdi/lib/scsi/driver.c
> @@ -0,0 +1,56 @@
> +/*
> + * Copyright (c) 2009 Kevin Wolf
> + *
> + * This program is free software. It comes without any warranty, to
> + * the extent permitted by applicable law. You can redistribute it
> + * and/or modify it under the terms of the Do What The Fuck You Want
> + * To Public License, Version 2, as published by Sam Hocevar. See
> + * http://sam.zoy.org/projects/COPYING.WTFPL for more details.
> + */
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <lostio.h>
> +
> +#include "cdi/scsi.h"
> +
> +extern void cdi_scsi_disk_init(struct cdi_scsi_device* device);
> +
> +/**
> + * Initialisiert die Datenstrukturen fuer einen SCSI-Treiber
> + */
> +void cdi_scsi_driver_init(struct cdi_scsi_driver* driver)
> +{
> +    driver->drv.type = CDI_SCSI;
> +    cdi_driver_init((struct cdi_driver*) driver);
> +}
> +
> +/**
> + * Deinitialisiert die Datenstrukturen fuer einen SCSI-Treiber
> + */
> +void cdi_scsi_driver_destroy(struct cdi_scsi_driver* driver)
> +{
> +    cdi_driver_destroy((struct cdi_driver*) driver);
> +}
> +
> +/**
> + * Initialisiert ein neues SCSI-Geraet
> + *
> + * Der Typ der Geraetes muss bereits gesetzt sein
> + */
> +void cdi_scsi_device_init(struct cdi_scsi_device* device)
> +{
> +    if (device->type == CDI_STORAGE) {
> +        cdi_scsi_disk_init(device);
> +    }
> +}
> +
> +/**
> + * Registiert den Treiber fuer SCSI-Geraete
> + */
> +void cdi_scsi_driver_register(struct cdi_scsi_driver* driver)
> +{
> +    cdi_driver_register((struct cdi_driver*) driver);
> +}
> diff --git a/src/modules/cdi/lib/storage.c b/src/modules/cdi/lib/storage.c
> index 9dd9746..16e4a7e 100644
> --- a/src/modules/cdi/lib/storage.c
> +++ b/src/modules/cdi/lib/storage.c
> @@ -17,7 +17,7 @@
>  #include "cdi/storage.h"
>  
>  static void lostio_mst_if_init(void);
> -static int lostio_mst_if_newdev(struct cdi_storage_device* device);
> +int lostio_mst_if_newdev(struct cdi_device* device);
>  
>  static size_t lostio_mst_read_handler(lostio_filehandle_t* fh,
>      void* buf, size_t blocksize, size_t blockcount);
> @@ -63,8 +63,6 @@ void cdi_storage_driver_destroy(struct cdi_storage_driver* driver)
>  void cdi_storage_driver_register(struct cdi_storage_driver* driver)
>  {
>      static int initialized = 0;
> -    int i;
> -    struct cdi_storage_device* device;
>  
>      cdi_driver_register((struct cdi_driver*) driver);
>  
> @@ -72,11 +70,32 @@ void cdi_storage_driver_register(struct cdi_storage_driver* driver)
>          lostio_mst_if_init();
>          initialized = 1;
>      }
> +}
> +
> +/**
> + * Initialisiert einen Massenspeicher
> + */
> +void cdi_storage_device_init(struct cdi_storage_device* device)
> +{
> +    device->dev.type = CDI_STORAGE;
>  
>      // Geraeteknoten fuer LostIO erstellen
> -    for (i = 0; (device = cdi_list_get(driver->drv.devices, i)); i++) {
> -        lostio_mst_if_newdev(device);
> +    lostio_mst_if_newdev(&device->dev);
> +}
> +
> +extern struct cdi_storage_driver cdi_scsi_disk_driver;
> +
> +static struct cdi_storage_driver* get_storage_drv(struct cdi_device* dev)
> +{
> +    struct cdi_storage_driver* driver = NULL;
> +
> +    if (dev->type == CDI_STORAGE) {
> +        driver = (struct cdi_storage_driver*) dev->driver;
> +    } else if (dev->type == CDI_SCSI) {
> +        driver = &cdi_scsi_disk_driver;
>      }
> +
> +    return driver;
>  }
>  
>  /**
> @@ -86,12 +105,12 @@ void cdi_storage_driver_register(struct cdi_storage_driver* driver)
>   * @param size Anzahl der zu lesenden Bytes
>   * @param dest Buffer
>   */
> -int cdi_storage_read(struct cdi_storage_device* device, uint64_t pos,
> +int cdi_storage_read(struct cdi_device* device, uint64_t pos,
>      size_t size, void* dest)
>  {
> -    struct cdi_storage_driver* driver = (struct cdi_storage_driver*) device->
> -        dev.driver;
> -    size_t block_size = device->block_size;
> +    struct cdi_storage_driver* driver = get_storage_drv(device);
> +    size_t block_size = driver->get_block_size(device);
> +
>      // Start- und Endblock
>      uint64_t block_read_start = pos / block_size;
>      uint64_t block_read_end = (pos + size) / block_size;
> @@ -128,13 +147,12 @@ int cdi_storage_read(struct cdi_storage_device* device, uint64_t pos,
>   * @param size Anzahl der zu schreibendes Bytes
>   * @param src Buffer
>   */
> -int cdi_storage_write(struct cdi_storage_device* device, uint64_t pos,
> +int cdi_storage_write(struct cdi_device* device, uint64_t pos,
>      size_t size, void* src)
>  {
> -    struct cdi_storage_driver* driver = (struct cdi_storage_driver*) device->
> -        dev.driver;
> -    
> -    size_t block_size = device->block_size;
> +    struct cdi_storage_driver* driver = get_storage_drv(device);
> +    size_t block_size = driver->get_block_size(device);
> +
>      uint64_t block_write_start = pos / block_size;
>      uint8_t buffer[block_size];
>      size_t offset;
> @@ -206,15 +224,17 @@ static void lostio_mst_if_init()
>  /**
>   * Erstellt den Dateisystemknoten fuer ein Geraet.
>   */
> -static int lostio_mst_if_newdev(struct cdi_storage_device* device)
> +int lostio_mst_if_newdev(struct cdi_device* device)
>  {
> +    struct cdi_storage_driver* driver = get_storage_drv(device);
> +
>      // Slash vor Pfad angaengen
> -    char path[strlen(device->dev.name) + 2];
> -    strcpy(path + 1, device->dev.name);
> +    char path[strlen(device->name) + 2];
> +    strcpy(path + 1, device->name);
>      *path = '/';
>  
> -    if (vfstree_create_node(path, CDI_LOSTIO_TYPE_MST, device->block_size *
> -        device->block_count, (void*) device, 0) == FALSE)
> +    if (vfstree_create_node(path, CDI_LOSTIO_TYPE_MST,
> +        driver->get_size(device), (void*) device, 0) == FALSE)
>      {
>          return -1;
>      }
> @@ -227,13 +247,19 @@ static int lostio_mst_if_newdev(struct cdi_storage_device* device)
>  static size_t lostio_mst_read_handler(lostio_filehandle_t* fh,
>      void* buf, size_t blocksize, size_t blockcount)
>  {
> -    struct cdi_storage_device* device = (struct cdi_storage_device*) fh->node->
> -        data;
> +    struct cdi_device* device = (struct cdi_device*) fh->node->data;
> +    struct cdi_storage_driver* drv = get_storage_drv(device);
> +
>      size_t size = blocksize * blockcount;
> +    size_t devsize = drv->get_size(device);
>  
>      // Groesse anpassen, wenn ueber das Medium hinaus gelesen werden soll
> -    if (size > (device->block_count * device->block_size - fh->pos)) {
> -        size = device->block_count * device->block_size - fh->pos;
> +    if (size > (devsize - fh->pos)) {
> +        size = devsize - fh->pos;
> +        if (size == 0) {
> +            fh->flags |= LOSTIO_FLAG_EOF;
> +            return 0;
> +        }
>      }
>  
>      // In den uebergebenen Buffer einlesen
> @@ -253,14 +279,16 @@ static size_t lostio_mst_read_handler(lostio_filehandle_t* fh,
>  static size_t lostio_mst_write_handler(lostio_filehandle_t* fh,
>      size_t blocksize, size_t blockcount, void* data)
>  {
> -    struct cdi_storage_device* device = (struct cdi_storage_device*) fh->node->
> -        data;
> +    struct cdi_device* device = (struct cdi_device*) fh->node->data;
> +    struct cdi_storage_driver* drv = get_storage_drv(device);
> +
>      size_t size = blocksize * blockcount;
> +    size_t devsize = drv->get_size(device);
>      size_t result = size;
>  
>      // Groesse anpassen, wenn ueber das Medium hinaus geschrieben werden soll
> -    if (size > (device->block_count * device->block_size - fh->pos)) {
> -        size = device->block_count * device->block_size - fh->pos;
> +    if (size > (devsize - fh->pos)) {
> +        size = devsize - fh->pos;
>      }
>  
>      // Daten schreiben
> @@ -279,10 +307,11 @@ static size_t lostio_mst_write_handler(lostio_filehandle_t* fh,
>  static int lostio_mst_seek_handler(lostio_filehandle_t* fh, uint64_t offset,
>      int origin)
>  {
> -    struct cdi_storage_device* device = (struct cdi_storage_device*) fh->node->
> -        data;
> +    struct cdi_device* device = (struct cdi_device*) fh->node->data;
> +    struct cdi_storage_driver* drv = get_storage_drv(device);
> +
>      uint64_t new_pos = fh->pos;
> -    uint64_t size = device->block_size * device->block_count;
> +    uint64_t size = drv->get_size(device);
>  
>      switch (origin)  {
>          case SEEK_SET:

-- 
Antoine Kaufmann
<toni@xxxxxxxxxxxxxxxx>

Attachment: pgplOrH5sdvzO.pgp
Description: PGP signature