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, §or_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, §or_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