1/*
2 * Copyright 2002/03, Thomas Kurschel. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6/*
7	Part of Open IDE bus manager
8
9	Basic ATA/ATAPI protocol functions
10*/
11
12
13#include "ide_internal.h"
14#include <scsi_cmds.h>
15
16#include "ide_sim.h"
17#include "ide_cmds.h"
18
19
20// time in ��s an IDE interrupt may get delayed
21// as this is used for waiting in normal code, this applies to hardware delays only
22// it's used for a hardware bug fix as well, see send_command
23#define MAX_IRQ_DELAY 50
24
25// maximum number send tries before giving up
26#define MAX_FAILED_SEND 1
27
28
29/** busy-wait for data request going high */
30
31bool
32wait_for_drq(ide_device_info *device)
33{
34	return ide_wait(device, ide_status_drq, 0, true, 10000000);
35}
36
37
38/** busy-wait for data request going low */
39
40bool
41wait_for_drqdown(ide_device_info *device)
42{
43	return ide_wait(device, 0, ide_status_drq, true, 1000000);
44}
45
46
47/** busy-wait for device ready */
48
49bool
50wait_for_drdy(ide_device_info *device)
51{
52	return ide_wait(device, ide_status_drdy, ide_status_bsy, false, 5000000);
53}
54
55
56/** reset entire IDE bus
57 *	all active request apart from <ignore> are resubmitted
58 */
59
60bool
61reset_bus(ide_device_info *device, ide_qrequest *ignore)
62{
63	ide_bus_info *bus = device->bus;
64	ide_controller_interface *controller = bus->controller;
65	ide_channel_cookie channel = bus->channel_cookie;
66
67	dprintf("ide: reset_bus() device %p, bus %p\n", device, bus);
68
69	if (device->reconnect_timer_installed) {
70		cancel_timer(&device->reconnect_timer.te);
71		device->reconnect_timer_installed = false;
72	}
73
74	if (device->other_device->reconnect_timer_installed) {
75		cancel_timer(&device->other_device->reconnect_timer.te);
76		device->other_device->reconnect_timer_installed = false;
77	}
78
79	// activate srst signal for 5 ��s
80	// also, deactivate IRQ
81	// (as usual, we will get an IRQ on disabling, but as we leave them
82	// disabled for 2 ms, this false report is ignored)
83	if (controller->write_device_control(channel,
84			ide_devctrl_nien | ide_devctrl_srst | ide_devctrl_bit3) != B_OK)
85		goto err0;
86
87	spin(5);
88
89	if (controller->write_device_control(channel, ide_devctrl_nien | ide_devctrl_bit3) != B_OK)
90		goto err0;
91
92	// let devices wake up
93	snooze(2000);
94
95	// ouch, we have to wait up to 31 seconds!
96	if (!ide_wait(device, 0, ide_status_bsy, true, 31000000)) {
97		// as we don't know which of the devices is broken
98		// we leave them both alive
99		if (controller->write_device_control(channel, ide_devctrl_bit3) != B_OK)
100			goto err0;
101
102		set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_TIMEOUT);
103		goto err1;
104	}
105
106	if (controller->write_device_control(channel, ide_devctrl_bit3) != B_OK)
107		goto err0;
108
109	finish_all_requests(bus->devices[0], ignore, SCSI_SCSI_BUS_RESET, true);
110	finish_all_requests(bus->devices[1], ignore, SCSI_SCSI_BUS_RESET, true);
111
112	dprintf("ide: reset_bus() device %p, bus %p success\n", device, bus);
113	return true;
114
115err0:
116	set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE);
117
118err1:
119	finish_all_requests(bus->devices[0], ignore, SCSI_SCSI_BUS_RESET, true);
120	finish_all_requests(bus->devices[1], ignore, SCSI_SCSI_BUS_RESET, true);
121
122	//xpt->call_async( bus->xpt_cookie, -1, -1, AC_BUS_RESET, NULL, 0 );
123
124	dprintf("ide: reset_bus() device %p, bus %p failed\n", device, bus);
125	return false;
126}
127
128
129/** execute packet device reset.
130 *	resets entire bus on fail or if device is not atapi;
131 *	all requests but <ignore> are resubmitted
132 */
133
134bool
135reset_device(ide_device_info *device, ide_qrequest *ignore)
136{
137	ide_bus_info *bus = device->bus;
138	status_t res;
139	uint8 orig_command;
140
141	dprintf("ide: reset_device() device %p\n", device);
142
143	SHOW_FLOW0(3, "");
144
145	if (!device->is_atapi)
146		goto err;
147
148	if (device->reconnect_timer_installed) {
149		cancel_timer(&device->reconnect_timer.te);
150		device->reconnect_timer_installed = false;
151	}
152
153	// select device
154	if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf,
155			ide_mask_device_head) != B_OK)
156		goto err;
157
158	// safe original command to let caller restart it
159	orig_command = device->tf.write.command;
160
161	// send device reset, independ of current device state
162	// (that's the point of a reset)
163	device->tf.write.command = IDE_CMD_DEVICE_RESET;
164	res = bus->controller->write_command_block_regs(bus->channel_cookie,
165		&device->tf, ide_mask_command);
166	device->tf.write.command = orig_command;
167
168	if (res != B_OK)
169		goto err;
170
171	// don't know how long to wait, but 31 seconds, like soft reset,
172	// should be enough
173	if (!ide_wait(device, 0, ide_status_bsy, true, 31000000))
174		goto err;
175
176	// alright, resubmit all requests
177	finish_all_requests(device, ignore, SCSI_SCSI_BUS_RESET, true);
178
179	SHOW_FLOW0(3, "done");
180	dprintf("ide: reset_device() device %p success\n", device);
181	return true;
182
183err:
184	// do the hard way
185	dprintf("ide: reset_device() device %p failed, calling reset_bus\n", device);
186	return reset_bus(device, ignore);
187}
188
189/** new_state must be either accessing, async_waiting or sync_waiting
190 *	param_mask must not include command register
191 */
192
193bool
194send_command(ide_device_info *device, ide_qrequest *qrequest,
195	bool need_drdy, uint32 timeout, ide_bus_state new_state)
196{
197	ide_bus_info *bus = device->bus;
198	bigtime_t irq_disabled_at = 0; // make compiler happy
199	uint8 num_retries = 0;
200	bool irq_guard;
201
202retry:
203	irq_guard = bus->num_running_reqs > 1;
204
205	SHOW_FLOW(3, "qrequest=%p, request=%p", qrequest,
206		qrequest ? qrequest->request : NULL);
207
208	// if there are pending requests, IRQs must be disabled to
209	// not mix up IRQ reasons
210	// XXX can we avoid that with the IDE_LOCK trick? It would
211	//     save some work and the bug workaround!
212	if (irq_guard) {
213		if (bus->controller->write_device_control(bus->channel_cookie,
214				ide_devctrl_nien | ide_devctrl_bit3) != B_OK)
215			goto err;
216
217		irq_disabled_at = system_time();
218	}
219
220	// select device
221	if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf,
222			ide_mask_device_head) != B_OK)
223		goto err;
224
225	bus->active_device = device;
226
227	if (!ide_wait(device, 0, ide_status_bsy | ide_status_drq, false, 50000)) {
228		uint8 status;
229
230		SHOW_FLOW0(1, "device is not ready");
231
232		status = bus->controller->get_altstatus(bus->channel_cookie);
233		if (status == 0xff) {
234			// there is no device (should happen during detection only)
235			SHOW_FLOW0(1, "there is no device");
236
237			// device detection recognizes this code as "all hope lost", so
238			// neither replace it nor use it anywhere else
239			device->subsys_status = SCSI_TID_INVALID;
240			return false;
241		}
242
243		// reset device and retry
244		if (reset_device(device, qrequest) && ++num_retries <= MAX_FAILED_SEND) {
245			SHOW_FLOW0(1, "retrying");
246			goto retry;
247		}
248
249		SHOW_FLOW0(1, "giving up");
250
251		// reset to often - abort request
252		device->subsys_status = SCSI_SEL_TIMEOUT;
253		return false;
254	}
255
256	if (need_drdy
257		&& (bus->controller->get_altstatus(bus->channel_cookie) & ide_status_drdy) == 0) {
258		SHOW_FLOW0(3, "drdy not set");
259		device->subsys_status = SCSI_SEQUENCE_FAIL;
260		return false;
261	}
262
263	// write parameters
264	if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf,
265			device->tf_param_mask) != B_OK)
266		goto err;
267
268	if (irq_guard) {
269		// IRQ may be fired by service requests and by the process of disabling(!)
270		// them (I heard this is caused by edge triggered PCI IRQs)
271
272		// wait at least 50 ��s to catch all pending irq's
273		// (at my system, up to 30 ��s elapsed)
274
275		// additionally, old drives (at least my IBM-DTTA-351010) loose
276		// sync if they are pushed too hard - on heavy overlapped write
277		// stress this drive tends to forget outstanding requests,
278		// waiting at least 50 ��s seems(!) to solve this
279		while (system_time() - irq_disabled_at < MAX_IRQ_DELAY)
280			spin(1);
281	}
282
283	// if we will start waiting once the command is sent, we have to
284	// lock the bus before sending; this way, IRQs that are fired
285	// shortly before/after sending of command are delayed until the
286	// command is really sent (start_waiting unlocks the bus) and then
287	// the IRQ handler can check savely whether the IRQ really signals
288	// finishing of command or not by testing the busy-signal of the device
289	if (new_state != ide_state_accessing) {
290		IDE_LOCK(bus);
291	}
292
293	if (irq_guard) {
294		// now it's clear why IRQs gets fired, so we can enable them again
295		if (bus->controller->write_device_control(bus->channel_cookie,
296				ide_devctrl_bit3) != B_OK)
297			goto err1;
298	}
299
300	// write command code - this will start the actual command
301	SHOW_FLOW(3, "Writing command 0x%02x", (int)device->tf.write.command);
302	if (bus->controller->write_command_block_regs(bus->channel_cookie,
303			&device->tf, ide_mask_command) != B_OK)
304		goto err1;
305
306	// start waiting now; also un-blocks IRQ handler (see above)
307	if (new_state != ide_state_accessing)
308		start_waiting(bus, timeout, new_state);
309
310	return true;
311
312err1:
313	if (timeout > 0) {
314		bus->state = ide_state_accessing;
315		IDE_UNLOCK(bus);
316	}
317
318err:
319	device->subsys_status = SCSI_HBA_ERR;
320	return false;
321}
322
323
324/**	busy-wait for device
325 *	mask - bits of status register that must be set
326 *	not_mask - bits of status register that must not be set
327 *	check_err - abort if error bit is set
328 *	timeout - waiting timeout
329 *	return: true on success
330 */
331
332bool
333ide_wait(ide_device_info *device, int mask, int not_mask,
334	bool check_err, bigtime_t timeout)
335{
336	ide_bus_info *bus = device->bus;
337	bigtime_t start_time = system_time();
338
339	while (1) {
340		bigtime_t elapsed_time;
341		int status;
342
343		// do spin before test as the device needs 400 ns
344		// to update its status register
345		spin(1);
346
347		status = bus->controller->get_altstatus(bus->channel_cookie);
348
349		if ((status & mask) == mask && (status & not_mask) == 0)
350			return true;
351
352		if (check_err && (status & ide_status_err) != 0) {
353			set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE);
354			return false;
355		}
356
357		elapsed_time = system_time() - start_time;
358
359		if (elapsed_time > timeout) {
360			set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_TIMEOUT);
361			return false;
362		}
363
364		// if we've waited more then 5ms, we start passive waiting
365		// to reduce system load
366		if (elapsed_time > 5000)
367			snooze(elapsed_time / 10);
368	}
369}
370
371
372/**	tell device to continue queued command
373 *	on return, no waiting is active!
374 *	tag - will contain tag of command to be continued
375 *	return: true - request continued
376 *	       false - something went wrong; sense set
377 */
378
379bool
380device_start_service(ide_device_info *device, int *tag)
381{
382	ide_bus_info *bus = device->bus;
383
384	device->tf.write.command = IDE_CMD_SERVICE;
385	device->tf.queued.mode = ide_mode_lba;
386
387	if (bus->active_device != device) {
388		// don't apply any precautions in terms of IRQ
389		// -> the bus is in accessing state, so IRQs are ignored anyway
390		if (bus->controller->write_command_block_regs(bus->channel_cookie,
391				&device->tf, ide_mask_device_head) != B_OK)
392			// on error, pretend that this device asks for service
393			// -> the disappeared controller will be recognized soon ;)
394			return true;
395
396		bus->active_device = device;
397
398		// give one clock (400 ns) to take notice
399		spin(1);
400	}
401
402	// here we go...
403	if (bus->controller->write_command_block_regs(bus->channel_cookie, &device->tf,
404			ide_mask_command) != B_OK)
405		goto err;
406
407	// we need to wait for the device as we want to read the tag
408	if (!ide_wait(device, ide_status_drdy, ide_status_bsy, false, 1000000))
409		return false;
410
411	// read tag
412	if (bus->controller->read_command_block_regs(bus->channel_cookie, &device->tf,
413			ide_mask_sector_count) != B_OK)
414		goto err;
415
416	if (device->tf.queued.release) {
417		// bus release is the wrong answer to a service request
418		set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE);
419		return false;
420	}
421
422	*tag = device->tf.queued.tag;
423
424	return true;
425
426err:
427	set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE);
428	return false;
429}
430
431
432/** check device whether it wants to continue queued request */
433
434bool
435check_service_req(ide_device_info *device)
436{
437	ide_bus_info *bus = device->bus;
438	int status;
439
440	// fast bailout if there is no request pending
441	if (device->num_running_reqs == 0)
442		return false;
443
444	if (bus->active_device != device) {
445		// don't apply any precautions in terms of IRQ
446		// -> the bus is in accessing state, so IRQs are ignored anyway
447		if (bus->controller->write_command_block_regs(bus->channel_cookie,
448				&device->tf, ide_mask_device_head) != B_OK)
449			// on error, pretend that this device asks for service
450			// -> the disappeared controller will be recognized soon ;)
451			return true;
452
453		bus->active_device = device;
454
455		// give one clock (400 ns) to take notice
456		spin(1);
457	}
458
459	status = bus->controller->get_altstatus(bus->channel_cookie);
460
461	return (status & ide_status_service) != 0;
462}
463
464