blob: c12772909042d8910865301f3644ad87ae4b8b8b [file] [log] [blame]
Kevin O'Connor76977b22010-02-17 01:01:32 -05001// 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
Gerd Hoffmannd52fdf62010-11-29 09:42:13 +010013#include "ahci.h" // atapi_cmd_data
Kevin O'Connor7149fc82010-02-17 23:24:42 -050014#include "usb-msc.h" // usb_cmd_data
Kevin O'Connor76977b22010-02-17 01:01:32 -050015
Kevin O'Connor7149fc82010-02-17 23:24:42 -050016// Route command to low-level handler.
Kevin O'Connor76977b22010-02-17 01:01:32 -050017static int
18cdb_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);
Kevin O'Connor7149fc82010-02-17 23:24:42 -050024 case DTYPE_USB:
25 return usb_cmd_data(op, cdbcmd, blocksize);
Gerd Hoffmannd52fdf62010-11-29 09:42:13 +010026 case DTYPE_AHCI:
27 return ahci_cmd_data(op, cdbcmd, blocksize);
Kevin O'Connor76977b22010-02-17 01:01:32 -050028 default:
29 op->count = 0;
30 return DISK_RET_EPARAM;
31 }
32}
33
Kevin O'Connor7149fc82010-02-17 23:24:42 -050034int
35cdb_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
Kevin O'Connor76977b22010-02-17 01:01:32 -050046// Request SENSE
47int
48cdb_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
Paolo Bonzini00823742011-11-16 13:02:42 +010059// Test unit ready
60int
61cdb_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
Kevin O'Connor76977b22010-02-17 01:01:32 -050071// Request capacity
72int
73cdb_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.
84int
85cdb_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);
Kevin O'Connor7149fc82010-02-17 23:24:42 -050092 return cdb_cmd_data(op, &cmd, GET_GLOBAL(op->drive_g->blksize));
Kevin O'Connor76977b22010-02-17 01:01:32 -050093}