+ exec* functions
[meinos.git] / apps / lib / libcdi / scsi.c
blobc815ccee3251a785da2f3fa64cdcf6826002fee7
1 /*
2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <stddef.h>
20 #include <stdint.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <sys/shm.h>
24 #include <rpc.h>
25 #include <errno.h>
27 #include "cdi.h"
28 #include "cdi/scsi.h"
29 #include "cdi/lists.h"
31 static cdi_list_t cdi_scsi_devices = NULL;
33 struct cdi_scsi_packet* cdi_scsi_packet_alloc(size_t size) {
34 struct cdi_scsi_packet *packet = malloc(sizeof(struct cdi_scsi_packet));
35 memset(packet,0,sizeof(struct cdi_scsi_packet));
37 packet->bufsize = size;
38 packet->buffer = malloc(size);
40 return packet;
43 /**
44 * Ein SCSI-Paket freigeben
46 * @param packet Pointer auf das Paket
48 void cdi_scsi_packet_free(struct cdi_scsi_packet* packet) {
49 free(packet->buffer);
50 free(packet);
53 /**
54 * SCSI-Request
55 * @param devname Device name
56 * @param shmid SHMID for buffer
57 * @param bufsize Size of buffer
58 * @param direction Direction
59 * @param cmdd1 Command dword 1
60 * @param cmdd2 Command dword 2
61 * @param cmdd3 Command dword 3
62 * @param cmdd4 Command dword 4
63 * @param cmdsize Size of command
64 * @return Success?
66 static int cdi_scsi_request(char *devname,int shmid,size_t bufsize,int direction,uint32_t cmdd1,uint32_t cmdd2,uint32_t cmdd3,uint32_t cmdd4,size_t cmdsize) {
67 uint32_t cmd[4] = {cmdd1,cmdd2,cmdd3,cmdd4};
69 struct cdi_scsi_device *dev;
70 size_t i;
71 for (i=0;(dev = cdi_list_get(cdi_scsi_devices,i));i++) {
72 if (strcmp(dev->dev.name,devname)==0) {
73 int ret = 0;
74 void *shmbuf = shmat(shmid,NULL,0);
75 if (shmbuf!=NULL) {
76 struct cdi_scsi_packet packet = {
77 .buffer = shmbuf,
78 .bufsize = bufsize,
79 .cmdsize = cmdsize,
80 .direction = bufsize==0?CDI_SCSI_NODATA:(direction?CDI_SCSI_WRITE:CDI_SCSI_READ)
82 memcpy(&packet.command,&cmd,sizeof(packet.command));
83 ret = ((struct cdi_scsi_driver*)(dev->dev.driver))->request(dev,&packet);
85 else ret = -ENOMEM;
86 shmdt(shmbuf);
87 return ret;
90 return -ENOENT;
93 /**
94 * Initialisiert die Datenstrukturen fuer einen SCSI-Treiber
96 void cdi_scsi_driver_init(struct cdi_scsi_driver* driver) {
97 cdi_driver_init((struct cdi_driver*)driver);
101 * Deinitialisiert die Datenstrukturen fuer einen SCSI-Treiber
102 * @todo remove device from cdi_scsi_devices
104 void cdi_scsi_driver_destroy(struct cdi_scsi_driver* driver) {
105 cdi_driver_destroy((struct cdi_driver*)driver);
109 * Registiert einen SCSI-Treiber
111 void cdi_scsi_driver_register(struct cdi_scsi_driver* driver) {
112 cdi_driver_register((struct cdi_driver*)driver);
114 if (cdi_scsi_devices==NULL) cdi_scsi_devices = cdi_list_create();
116 struct cdi_scsi_device *dev;
117 size_t i;
118 for (i=0;(dev = cdi_list_get(driver->drv.devices,i));i++) {
119 char *name;
120 asprintf(&name,"scsi_request_%s",dev->dev.name);
121 rpc_func_create(name,cdi_scsi_request,"$iiiddddi",NAME_MAX+sizeof(int)*4+16);
122 free(name);
123 cdi_list_push(cdi_scsi_devices,dev);
127 void cdi_scsi_device_init(struct cdi_scsi_device* device) {