f5e2ce3f70518ba85bd504e2bb23486bd9056fdd
[seabios.git] / src / blockcmd.c
1 // Support for several common scsi like command data block requests
2 //
3 // Copyright (C) 2010  Kevin O'Connor <kevin@koconnor.net>
4 // Copyright (C) 2002  MandrakeSoft S.A.
5 //
6 // This file may be distributed under the terms of the GNU LGPLv3 license.
7
8 #include "biosvar.h" // GET_GLOBAL
9 #include "util.h" // htonl
10 #include "disk.h" // struct disk_op_s
11 #include "blockcmd.h" // struct cdb_request_sense
12 #include "ata.h" // atapi_cmd_data
13 #include "ahci.h" // atapi_cmd_data
14 #include "usb-msc.h" // usb_cmd_data
15
16 // Route command to low-level handler.
17 static int
18 cdb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
19 {
20     u8 type = GET_GLOBAL(op->drive_g->type);
21     switch (type) {
22     case DTYPE_ATAPI:
23         return atapi_cmd_data(op, cdbcmd, blocksize);
24     case DTYPE_USB:
25         return usb_cmd_data(op, cdbcmd, blocksize);
26     case DTYPE_AHCI:
27         return ahci_cmd_data(op, cdbcmd, blocksize);
28     default:
29         op->count = 0;
30         return DISK_RET_EPARAM;
31     }
32 }
33
34 int
35 cdb_get_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data)
36 {
37     struct cdb_request_sense cmd;
38     memset(&cmd, 0, sizeof(cmd));
39     cmd.command = CDB_CMD_INQUIRY;
40     cmd.length = sizeof(*data);
41     op->count = 1;
42     op->buf_fl = data;
43     return cdb_cmd_data(op, &cmd, sizeof(*data));
44 }
45
46 // Request SENSE
47 int
48 cdb_get_sense(struct disk_op_s *op, struct cdbres_request_sense *data)
49 {
50     struct cdb_request_sense cmd;
51     memset(&cmd, 0, sizeof(cmd));
52     cmd.command = CDB_CMD_REQUEST_SENSE;
53     cmd.length = sizeof(*data);
54     op->count = 1;
55     op->buf_fl = data;
56     return cdb_cmd_data(op, &cmd, sizeof(*data));
57 }
58
59 // Test unit ready
60 int
61 cdb_test_unit_ready(struct disk_op_s *op)
62 {
63     struct cdb_request_sense cmd;
64     memset(&cmd, 0, sizeof(cmd));
65     cmd.command = CDB_CMD_TEST_UNIT_READY;
66     op->count = 0;
67     op->buf_fl = NULL;
68     return cdb_cmd_data(op, &cmd, 0);
69 }
70
71 // Request capacity
72 int
73 cdb_read_capacity(struct disk_op_s *op, struct cdbres_read_capacity *data)
74 {
75     struct cdb_read_capacity cmd;
76     memset(&cmd, 0, sizeof(cmd));
77     cmd.command = CDB_CMD_READ_CAPACITY;
78     op->count = 1;
79     op->buf_fl = data;
80     return cdb_cmd_data(op, &cmd, sizeof(*data));
81 }
82
83 // Read sectors.
84 int
85 cdb_read(struct disk_op_s *op)
86 {
87     struct cdb_rwdata_10 cmd;
88     memset(&cmd, 0, sizeof(cmd));
89     cmd.command = CDB_CMD_READ_10;
90     cmd.lba = htonl(op->lba);
91     cmd.count = htons(op->count);
92     return cdb_cmd_data(op, &cmd, GET_GLOBAL(op->drive_g->blksize));
93 }
94
95 // Write sectors.
96 int
97 cdb_write(struct disk_op_s *op)
98 {
99     struct cdb_rwdata_10 cmd;
100     memset(&cmd, 0, sizeof(cmd));
101     cmd.command = CDB_CMD_WRITE_10;
102     cmd.lba = htonl(op->lba);
103     cmd.count = htons(op->count);
104     return cdb_cmd_data(op, &cmd, GET_GLOBAL(op->drive_g->blksize));
105 }