vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / bus_managers / ata / ATAModule.cpp
blob34c4b34492b7ca6e332ed8508eb88b89dfd533d6
1 /*
2 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
3 * Copyright 2008, Marcus Overhagen.
4 * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de.
5 * Copyright 2002-2003, Thomas Kurschel.
7 * Distributed under the terms of the MIT License.
8 */
10 #include "ATAPrivate.h"
13 scsi_for_sim_interface *gSCSIModule = NULL;
14 device_manager_info *gDeviceManager = NULL;
17 static status_t
18 ata_sim_init_bus(device_node *node, void **cookie)
20 ATAChannel *channel = new(std::nothrow) ATAChannel(node);
21 if (channel == NULL)
22 return B_NO_MEMORY;
24 status_t result = channel->InitCheck();
25 if (result != B_OK) {
26 TRACE_ERROR("failed to set up ata channel object\n");
27 return result;
30 *cookie = channel;
31 return B_OK;
35 static void
36 ata_sim_uninit_bus(void *cookie)
38 ATAChannel *channel = (ATAChannel *)cookie;
39 delete channel;
43 static void
44 ata_sim_bus_removed(void *cookie)
46 ATAChannel *channel = (ATAChannel *)cookie;
47 if (channel->Bus() != NULL) {
48 gSCSIModule->block_bus(channel->Bus());
49 channel->SetBus(NULL);
54 static void
55 ata_sim_set_scsi_bus(scsi_sim_cookie cookie, scsi_bus bus)
57 ATAChannel *channel = (ATAChannel *)cookie;
58 channel->SetBus(bus);
59 channel->ScanBus();
63 static void
64 ata_sim_scsi_io(scsi_sim_cookie cookie, scsi_ccb *ccb)
66 ATAChannel *channel = (ATAChannel *)cookie;
67 if (channel->Bus() == NULL) {
68 ccb->subsys_status = SCSI_NO_HBA;
69 gSCSIModule->finished(ccb, 1);
70 return;
73 if (channel->ExecuteIO(ccb) == B_BUSY)
74 gSCSIModule->requeue(ccb, true);
78 static uchar
79 ata_sim_abort(scsi_sim_cookie cookie, scsi_ccb *ccb)
81 ATAChannel *channel = (ATAChannel *)cookie;
82 if (channel->Bus() == NULL)
83 return SCSI_NO_HBA;
85 // aborting individual commands is not possible
86 return SCSI_REQ_CMP;
90 static uchar
91 ata_sim_reset_device(scsi_sim_cookie cookie, uchar targetId, uchar targetLun)
93 ATAChannel *channel = (ATAChannel *)cookie;
94 if (channel->Bus() == NULL)
95 return SCSI_NO_HBA;
97 // TODO: implement
98 return SCSI_REQ_INVALID;
102 static uchar
103 ata_sim_term_io(scsi_sim_cookie cookie, scsi_ccb *ccb)
105 ATAChannel *channel = (ATAChannel *)cookie;
106 if (channel->Bus() == NULL)
107 return SCSI_NO_HBA;
109 // we don't terminate commands, ignore
110 return SCSI_REQ_CMP;
114 static uchar
115 ata_sim_path_inquiry(scsi_sim_cookie cookie, scsi_path_inquiry *info)
117 ATAChannel *channel = (ATAChannel *)cookie;
118 if (channel->Bus() == NULL)
119 return SCSI_NO_HBA;
121 channel->PathInquiry(info);
122 return SCSI_REQ_CMP;
126 static uchar
127 ata_sim_rescan_bus(scsi_sim_cookie cookie)
129 // TODO: implement
130 return SCSI_REQ_CMP;
134 static uchar
135 ata_sim_reset_bus(scsi_sim_cookie cookie)
137 ATAChannel *channel = (ATAChannel *)cookie;
138 if (channel->Bus() == NULL)
139 return SCSI_NO_HBA;
141 //channel->Reset();
142 panic("asking for trouble");
143 return SCSI_REQ_CMP;
147 static void
148 ata_sim_get_restrictions(scsi_sim_cookie cookie, uchar targetID,
149 bool *isATAPI, bool *noAutoSense, uint32 *maxBlocks)
151 ATAChannel *channel = (ATAChannel *)cookie;
152 channel->GetRestrictions(targetID, isATAPI, noAutoSense, maxBlocks);
156 static status_t
157 ata_sim_control(scsi_sim_cookie cookie, uchar targetID, uint32 op, void *buffer,
158 size_t length)
160 ATAChannel *channel = (ATAChannel *)cookie;
161 return channel->Control(targetID, op, buffer, length);
165 status_t
166 ata_channel_added(device_node *parent)
168 const char *controllerName;
169 if (gDeviceManager->get_attr_string(parent,
170 ATA_CONTROLLER_CONTROLLER_NAME_ITEM, &controllerName, true) != B_OK) {
171 TRACE_ERROR("controller name missing\n");
172 return B_ERROR;
175 int32 channelID = gDeviceManager->create_id(ATA_CHANNEL_ID_GENERATOR);
176 if (channelID < 0) {
177 TRACE_ERROR("out of channel ids\n");
178 return B_ERROR;
181 device_attr attributes[] = {
183 B_DEVICE_FIXED_CHILD, B_STRING_TYPE,
184 { string: SCSI_FOR_SIM_MODULE_NAME }
188 SCSI_DESCRIPTION_CONTROLLER_NAME, B_STRING_TYPE,
189 { string: controllerName }
192 // maximum number of blocks per transmission:
193 // - ATAPI uses packets, i.e. normal SCSI limits apply
194 // but I'm not sure about controller restrictions
195 // - ATA allows up to 256 blocks for LBA28 and 65535 for LBA48
196 // to fix specific drive bugs use ATAChannel::GetRestrictions()
197 { B_DMA_MAX_TRANSFER_BLOCKS, B_UINT32_TYPE, { ui32: 0xffff } },
198 { ATA_CHANNEL_ID_ITEM, B_UINT32_TYPE, { ui32: (uint32)channelID } },
199 { NULL }
202 return gDeviceManager->register_node(parent, ATA_SIM_MODULE_NAME,
203 attributes, NULL, NULL);
207 status_t
208 ata_interrupt_handler(void *cookie, uint8 status)
210 ATAChannel *channel = (ATAChannel *)cookie;
211 return channel->Interrupt(status);
215 static status_t
216 std_ops(int32 op, ...)
218 switch (op) {
219 case B_MODULE_INIT:
220 case B_MODULE_UNINIT:
221 return B_OK;
223 default:
224 break;
227 return B_ERROR;
231 scsi_sim_interface ata_sim_module = {
234 ATA_SIM_MODULE_NAME,
236 std_ops
239 NULL, // supported devices
240 NULL, // register node
241 ata_sim_init_bus,
242 ata_sim_uninit_bus,
243 NULL, // register child devices
244 NULL, // rescan
245 ata_sim_bus_removed,
246 NULL, // suspend
247 NULL, // resume
250 ata_sim_set_scsi_bus,
251 ata_sim_scsi_io,
252 ata_sim_abort,
253 ata_sim_reset_device,
254 ata_sim_term_io,
255 ata_sim_path_inquiry,
256 ata_sim_rescan_bus,
257 ata_sim_reset_bus,
258 ata_sim_get_restrictions,
259 ata_sim_control
262 ata_for_controller_interface ata_for_controller_module = {
265 ATA_FOR_CONTROLLER_MODULE_NAME,
267 &std_ops
270 NULL, // supported devices
271 ata_channel_added,
272 NULL,
273 NULL,
274 NULL
277 ata_interrupt_handler
281 module_dependency module_dependencies[] = {
282 { SCSI_FOR_SIM_MODULE_NAME, (module_info **)&gSCSIModule },
283 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
287 module_info *modules[] = {
288 (module_info *)&ata_for_controller_module,
289 (module_info *)&ata_sim_module,
290 NULL