xref: /haiku/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 /*
2  * Copyright 2018-2020 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		B Krishnan Iyer, krishnaniyer97@gmail.com
7  *		Adrien Destugues, pulkomandy@pulkomandy.tk
8  */
9 #include <algorithm>
10 #include <new>
11 #include <stdio.h>
12 #include <string.h>
13 
14 #include <bus/PCI.h>
15 #include <PCI_x86.h>
16 
17 #include <KernelExport.h>
18 
19 #include "IOSchedulerSimple.h"
20 #include "mmc.h"
21 #include "sdhci_pci.h"
22 
23 
24 #define TRACE_SDHCI
25 #ifdef TRACE_SDHCI
26 #	define TRACE(x...) dprintf("\33[33msdhci_pci:\33[0m " x)
27 #else
28 #	define TRACE(x...) ;
29 #endif
30 #define TRACE_ALWAYS(x...)	dprintf("\33[33msdhci_pci:\33[0m " x)
31 #define ERROR(x...)			dprintf("\33[33msdhci_pci:\33[0m " x)
32 #define CALLED(x...)		TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
33 
34 
35 #define SDHCI_PCI_DEVICE_MODULE_NAME "busses/mmc/sdhci_pci/driver_v1"
36 #define SDHCI_PCI_MMC_BUS_MODULE_NAME "busses/mmc/sdhci_pci/device/v1"
37 
38 #define SLOT_NUMBER				"device/slot"
39 #define BAR_INDEX				"device/bar"
40 
41 
42 class SdhciBus {
43 	public:
44 							SdhciBus(struct registers* registers, uint8_t irq);
45 							~SdhciBus();
46 
47 		void				EnableInterrupts(uint32_t mask);
48 		void				DisableInterrupts();
49 		status_t			ExecuteCommand(uint8_t command, uint32_t argument,
50 								uint32_t* response);
51 		int32				HandleInterrupt();
52 		status_t			InitCheck();
53 		void				Reset();
54 		void				SetClock(int kilohertz);
55 		status_t			DoIO(uint8_t command, IOOperation* operation,
56 								bool offsetAsSectors);
57 		void				SetScanSemaphore(sem_id sem);
58 		void				SetBusWidth(int width);
59 
60 	private:
61 		bool				PowerOn();
62 		void				RecoverError();
63 
64 	private:
65 		struct registers*	fRegisters;
66 		uint32_t			fCommandResult;
67 		uint8_t				fIrq;
68 		sem_id				fSemaphore;
69 		sem_id				fScanSemaphore;
70 		status_t			fStatus;
71 };
72 
73 
74 class SdhciDevice {
75 	public:
76 		device_node* fNode;
77 		uint8_t fRicohOriginalMode;
78 };
79 
80 
81 device_manager_info* gDeviceManager;
82 device_module_info* gMMCBusController;
83 static pci_x86_module_info* sPCIx86Module;
84 
85 
86 static int32
87 sdhci_generic_interrupt(void* data)
88 {
89 	SdhciBus* bus = (SdhciBus*)data;
90 	return bus->HandleInterrupt();
91 }
92 
93 
94 SdhciBus::SdhciBus(struct registers* registers, uint8_t irq)
95 	:
96 	fRegisters(registers),
97 	fIrq(irq),
98 	fSemaphore(0)
99 {
100 	if (irq == 0 || irq == 0xff) {
101 		ERROR("PCI IRQ not assigned\n");
102 		fStatus = B_BAD_DATA;
103 		return;
104 	}
105 
106 	fSemaphore = create_sem(0, "SDHCI interrupts");
107 
108 	fStatus = install_io_interrupt_handler(fIrq,
109 		sdhci_generic_interrupt, this, 0);
110 
111 	if (fStatus != B_OK) {
112 		ERROR("can't install interrupt handler\n");
113 		return;
114 	}
115 
116 	// First of all, we have to make sure we are in a sane state. The easiest
117 	// way is to reset everything.
118 	Reset();
119 
120 	// Turn on the power supply to the card, if there is a card inserted
121 	if (PowerOn()) {
122 		// Then we configure the clock to the frequency needed for
123 		// initialization
124 		SetClock(400);
125 	}
126 
127 	// Finally, configure some useful interrupts
128 	EnableInterrupts(SDHCI_INT_CMD_CMP | SDHCI_INT_CARD_REM
129 		| SDHCI_INT_TRANS_CMP);
130 
131 	// We want to see the error bits in the status register, but not have an
132 	// interrupt trigger on them (we get a "command complete" interrupt on
133 	// errors already)
134 	fRegisters->interrupt_status_enable |= SDHCI_INT_ERROR
135 		| SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | SDHCI_INT_INDEX
136 		| SDHCI_INT_BUS_POWER | SDHCI_INT_END_BIT;
137 }
138 
139 
140 SdhciBus::~SdhciBus()
141 {
142 	DisableInterrupts();
143 
144 	if (fSemaphore != 0)
145 		delete_sem(fSemaphore);
146 
147 	if (fIrq != 0)
148 		remove_io_interrupt_handler(fIrq, sdhci_generic_interrupt, this);
149 
150 	area_id regs_area = area_for(fRegisters);
151 	delete_area(regs_area);
152 }
153 
154 
155 void
156 SdhciBus::EnableInterrupts(uint32_t mask)
157 {
158 	fRegisters->interrupt_status_enable |= mask;
159 	fRegisters->interrupt_signal_enable |= mask;
160 }
161 
162 
163 void
164 SdhciBus::DisableInterrupts()
165 {
166 	fRegisters->interrupt_status_enable = 0;
167 	fRegisters->interrupt_signal_enable = 0;
168 }
169 
170 
171 // #pragma mark -
172 /*
173 PartA2, SD Host Controller Simplified Specification, Version 4.20
174 §3.7.1.1 The sequence to issue an SD Command
175 */
176 status_t
177 SdhciBus::ExecuteCommand(uint8_t command, uint32_t argument, uint32_t* response)
178 {
179 	TRACE("ExecuteCommand(%d, %x)\n", command, argument);
180 
181 	// First of all clear the result
182 	fCommandResult = 0;
183 
184 	// Check if it's possible to send a command right now.
185 	// It is not possible to send a command as long as the command line is busy.
186 	// The spec says we should wait, but we can't do that on kernel side, since
187 	// it leaves no chance for the upper layers to handle the problem. So we
188 	// just say we're busy and the caller can retry later.
189 	// Note that this should normally never happen: the command line is busy
190 	// only during command execution, and we don't leave this function with ac
191 	// command running.
192 	if (fRegisters->present_state.CommandInhibit()) {
193 		panic("Command execution impossible, command inhibit\n");
194 		return B_BUSY;
195 	}
196 	if (fRegisters->present_state.DataInhibit()) {
197 		panic("Command execution unwise, data inhibit\n");
198 		return B_BUSY;
199 	}
200 
201 	uint32_t replyType;
202 
203 	switch(command) {
204 		case SD_GO_IDLE_STATE:
205 			replyType = Command::kNoReplyType;
206 			break;
207 		case SD_ALL_SEND_CID:
208 		case SD_SEND_CSD:
209 			replyType = Command::kR2Type;
210 			break;
211 		case SD_SEND_RELATIVE_ADDR:
212 			replyType = Command::kR6Type;
213 			break;
214 		case SD_SELECT_DESELECT_CARD:
215 		case SD_ERASE:
216 			replyType = Command::kR1bType;
217 			break;
218 		case SD_SEND_IF_COND:
219 			replyType = Command::kR7Type;
220 			break;
221 		case SD_READ_SINGLE_BLOCK:
222 		case SD_READ_MULTIPLE_BLOCKS:
223 		case SD_WRITE_SINGLE_BLOCK:
224 		case SD_WRITE_MULTIPLE_BLOCKS:
225 			replyType = Command::kR1Type | Command::kDataPresent;
226 			break;
227 		case SD_APP_CMD:
228 		case SD_ERASE_WR_BLK_START:
229 		case SD_ERASE_WR_BLK_END:
230 		case SD_SET_BUS_WIDTH: // SD Application command
231 			replyType = Command::kR1Type;
232 			break;
233 		case SD_SEND_OP_COND: // SD Application command
234 			replyType = Command::kR3Type;
235 			break;
236 		default:
237 			ERROR("Unknown command %x\n", command);
238 			return B_BAD_DATA;
239 	}
240 
241 	// Check if DATA line is available (if needed)
242 	if ((replyType & Command::k32BitResponseCheckBusy) != 0
243 		&& command != SD_STOP_TRANSMISSION && command != SD_IO_ABORT) {
244 		if (fRegisters->present_state.DataInhibit()) {
245 			ERROR("Execution aborted, data inhibit\n");
246 			return B_BUSY;
247 		}
248 	}
249 
250 	if (fRegisters->present_state.CommandInhibit())
251 		panic("Command line busy at start of execute command\n");
252 
253 	if (replyType == Command::kR1bType)
254 		fRegisters->transfer_mode = 0;
255 
256 	fRegisters->argument = argument;
257 	fRegisters->command.SendCommand(command, replyType);
258 
259 	// Wait for command response to be available ("command complete" interrupt)
260 	TRACE("Wait for command complete...");
261 	while (fCommandResult == 0) {
262 		acquire_sem(fSemaphore);
263 		TRACE("command complete sem acquired, status: %x\n", fCommandResult);
264 		TRACE("real status = %x command line busy: %d\n",
265 			fRegisters->interrupt_status,
266 			fRegisters->present_state.CommandInhibit());
267 	}
268 
269 	TRACE("Command response available\n");
270 
271 	if (fCommandResult & SDHCI_INT_ERROR) {
272 		fRegisters->interrupt_status |= fCommandResult;
273 		if (fCommandResult & SDHCI_INT_TIMEOUT) {
274 			ERROR("Command execution timed out\n");
275 			if (fRegisters->present_state.CommandInhibit()) {
276 				TRACE("Command line is still busy, clearing it\n");
277 				// Clear the stall
278 				fRegisters->software_reset.ResetCommandLine();
279 			}
280 			return B_TIMED_OUT;
281 		}
282 		if (fCommandResult & SDHCI_INT_CRC) {
283 			ERROR("CRC error\n");
284 			return B_BAD_VALUE;
285 		}
286 		ERROR("Command execution failed %x\n", fCommandResult);
287 		// TODO look at errors in interrupt_status register for more details
288 		// and return a more appropriate error code
289 		return B_ERROR;
290 	}
291 
292 	if (fRegisters->present_state.CommandInhibit()) {
293 		TRACE("Command execution failed, card stalled\n");
294 		// Clear the stall
295 		fRegisters->software_reset.ResetCommandLine();
296 		return B_ERROR;
297 	}
298 
299 	switch (replyType & Command::kReplySizeMask) {
300 		case Command::k32BitResponse:
301 			*response = fRegisters->response[0];
302 			break;
303 		case Command::k128BitResponse:
304 			response[0] = fRegisters->response[0];
305 			response[1] = fRegisters->response[1];
306 			response[2] = fRegisters->response[2];
307 			response[3] = fRegisters->response[3];
308 			break;
309 
310 		default:
311 			// No response
312 			break;
313 	}
314 
315 	if (replyType == Command::kR1bType
316 			&& (fCommandResult & SDHCI_INT_TRANS_CMP) == 0) {
317 		// R1b commands may use the data line so we must wait for the
318 		// "transfer complete" interrupt here.
319 		TRACE("Waiting for data line...\n");
320 		do {
321 			acquire_sem(fSemaphore);
322 		} while (fRegisters->present_state.DataInhibit());
323 		TRACE("Dataline is released.\n");
324 	}
325 
326 	ERROR("Command execution %d complete\n", command);
327 	return B_OK;
328 }
329 
330 
331 status_t
332 SdhciBus::InitCheck()
333 {
334 	return fStatus;
335 }
336 
337 
338 void
339 SdhciBus::Reset()
340 {
341 	fRegisters->software_reset.ResetAll();
342 }
343 
344 
345 void
346 SdhciBus::SetClock(int kilohertz)
347 {
348 	int base_clock = fRegisters->capabilities.BaseClockFrequency();
349 	// Try to get as close to 400kHz as possible, but not faster
350 	int divider = base_clock * 1000 / kilohertz;
351 
352 	if (fRegisters->host_controller_version.specVersion <= 1) {
353 		// Old controller only support power of two dividers up to 256,
354 		// round to next power of two up to 256
355 		if (divider > 256)
356 			divider = 256;
357 
358 		divider--;
359 		divider |= divider >> 1;
360 		divider |= divider >> 2;
361 		divider |= divider >> 4;
362 		divider++;
363 	}
364 
365 	divider = fRegisters->clock_control.SetDivider(divider);
366 
367 	// Log the value after possible rounding by SetDivider (only even values
368 	// are allowed).
369 	TRACE("SDCLK frequency: %dMHz / %d = %dkHz\n", base_clock, divider,
370 		base_clock * 1000 / divider);
371 
372 	// We have set the divider, now we can enable the internal clock.
373 	fRegisters->clock_control.EnableInternal();
374 
375 	// wait until internal clock is stabilized
376 	while (!(fRegisters->clock_control.InternalStable()));
377 
378 	fRegisters->clock_control.EnablePLL();
379 	while (!(fRegisters->clock_control.InternalStable()));
380 
381 	// Finally, route the clock to the SD card
382 	fRegisters->clock_control.EnableSD();
383 }
384 
385 
386 status_t
387 SdhciBus::DoIO(uint8_t command, IOOperation* operation, bool offsetAsSectors)
388 {
389 	bool isWrite = operation->IsWrite();
390 
391 	static const uint32 kBlockSize = 512;
392 	off_t offset = operation->Offset();
393 	generic_size_t length = operation->Length();
394 
395 	TRACE("%s %"B_PRIu64 " bytes at %" B_PRIdOFF "\n",
396 		isWrite ? "Write" : "Read", length, offset);
397 
398 	// Check that the IO scheduler did its job in following our DMA restrictions
399 	// We can start a read only at a sector boundary
400 	ASSERT(offset % kBlockSize == 0);
401 	// We can only read complete sectors
402 	ASSERT(length % kBlockSize == 0);
403 
404 	const generic_io_vec* vecs = operation->Vecs();
405 	generic_size_t vecOffset = 0;
406 
407 	// FIXME can this be moved to the init function instead?
408 	//
409 	// For simplicity we use a transfer size equal to the sector size. We could
410 	// go up to 2K here if the length to read in each individual vec is a
411 	// multiple of 2K, but we have no easy way to know this (we would need to
412 	// iterate through the IOOperation vecs and check the size of each of them).
413 	// We could also do smaller transfers, but it is not possible to start a
414 	// transfer anywhere else than the start of a sector, so it's a lot simpler
415 	// to always work in complete sectors. We set the B_DMA_ALIGNMENT device
416 	// node property accordingly, making sure that we don't get asked to do
417 	// transfers that are not aligned with sectors.
418 	//
419 	// Additionnally, set SDMA buffer boundary aligment to 512K. This is the
420 	// largest possible size. We also set the B_DMA_BOUNDARY property on the
421 	// published device node, so that the DMA resource manager knows that it
422 	// must respect this boundary. As a result, we will never be asked to
423 	// do a transfer that crosses this boundary, and we don't need to handle
424 	// the DMA boundary interrupt (the transfer will be split in two at an
425 	// upper layer).
426 	fRegisters->block_size.ConfigureTransfer(kBlockSize,
427 		BlockSize::kDmaBoundary512K);
428 	status_t result = B_OK;
429 
430 	while (length > 0) {
431 		size_t toCopy = std::min((generic_size_t)length,
432 			vecs->length - vecOffset);
433 
434 		// If the current vec is empty, we can move to the next
435 		if (toCopy == 0) {
436 			vecs++;
437 			vecOffset = 0;
438 			continue;
439 		}
440 
441 		// With SDMA we can only transfer multiples of 1 sector
442 		ASSERT(toCopy % kBlockSize == 0);
443 
444 		fRegisters->system_address = vecs->base + vecOffset;
445 		// fRegisters->adma_system_address = fDmaMemory;
446 
447 		fRegisters->block_count = toCopy / kBlockSize;
448 
449 		uint16 direction;
450 		if (isWrite)
451 			direction = TransferMode::kWrite;
452 		else
453 			direction = TransferMode::kRead;
454 		fRegisters->transfer_mode = TransferMode::kMulti | direction
455 			| TransferMode::kAutoCmd12Enable
456 			| TransferMode::kBlockCountEnable | TransferMode::kDmaEnable;
457 
458 		uint32_t response;
459 		result = ExecuteCommand(command,
460 			offset / (offsetAsSectors ? kBlockSize : 1), &response);
461 		if (result != B_OK)
462 			break;
463 
464 		// Wait for DMA transfer to complete
465 		// In theory we could go on and send other commands as long as they
466 		// don't need the DAT lines, but it's overcomplicating things.
467 		TRACE("Wait for transfer complete...");
468 		acquire_sem(fSemaphore);
469 		TRACE("transfer complete OK.\n");
470 
471 		length -= toCopy;
472 		vecOffset += toCopy;
473 		offset += toCopy;
474 	}
475 
476 	return result;
477 }
478 
479 
480 void
481 SdhciBus::SetScanSemaphore(sem_id sem)
482 {
483 	fScanSemaphore = sem;
484 
485 	// If there is already a card in, start a scan immediately
486 	if (fRegisters->present_state.IsCardInserted())
487 		release_sem(fScanSemaphore);
488 
489 	// We can now enable the card insertion interrupt for next time a card
490 	// is inserted
491 	EnableInterrupts(SDHCI_INT_CARD_INS);
492 }
493 
494 
495 void
496 SdhciBus::SetBusWidth(int width)
497 {
498 	uint8_t widthBits;
499 	switch(width) {
500 		case 1:
501 			widthBits = HostControl::kDataTransfer1Bit;
502 			break;
503 		case 4:
504 			widthBits = HostControl::kDataTransfer4Bit;
505 			break;
506 		case 8:
507 			widthBits = HostControl::kDataTransfer8Bit;
508 			break;
509 		default:
510 			panic("Incorrect bitwidth value");
511 			return;
512 	}
513 	fRegisters->host_control.SetDataTransferWidth(widthBits);
514 }
515 
516 
517 bool
518 SdhciBus::PowerOn()
519 {
520 	if (!fRegisters->present_state.IsCardInserted()) {
521 		TRACE("Card not inserted, not powering on for now\n");
522 		return false;
523 	}
524 
525 	uint8_t supportedVoltages = fRegisters->capabilities.SupportedVoltages();
526 	if ((supportedVoltages & Capabilities::k3v3) != 0)
527 		fRegisters->power_control.SetVoltage(PowerControl::k3v3);
528 	else if ((supportedVoltages & Capabilities::k3v0) != 0)
529 		fRegisters->power_control.SetVoltage(PowerControl::k3v0);
530 	else if ((supportedVoltages & Capabilities::k1v8) != 0)
531 		fRegisters->power_control.SetVoltage(PowerControl::k1v8);
532 	else {
533 		fRegisters->power_control.PowerOff();
534 		ERROR("No voltage is supported\n");
535 		return false;
536 	}
537 
538 	return true;
539 }
540 
541 
542 void
543 SdhciBus::RecoverError()
544 {
545 	fRegisters->interrupt_signal_enable &= ~(SDHCI_INT_CMD_CMP
546 		| SDHCI_INT_TRANS_CMP | SDHCI_INT_CARD_INS | SDHCI_INT_CARD_REM);
547 
548 	if (fRegisters->interrupt_status & 7)
549 		fRegisters->software_reset.ResetCommandLine();
550 
551 	int16_t error_status = fRegisters->interrupt_status;
552 	fRegisters->interrupt_status &= ~(error_status);
553 }
554 
555 
556 int32
557 SdhciBus::HandleInterrupt()
558 {
559 #if 0
560 	// We could use the slot register to quickly see for which slot the
561 	// interrupt is. But since we have an interrupt handler call for each slot
562 	// anyway, it's just as simple to let each of them scan its own interrupt
563 	// status register.
564 	if ( !(fRegisters->slot_interrupt_status & (1 << fSlot)) ) {
565 		TRACE("interrupt not for me.\n");
566 		return B_UNHANDLED_INTERRUPT;
567 	}
568 #endif
569 
570 	uint32_t intmask = fRegisters->interrupt_status;
571 
572 	// Shortcut: exit early if there is no interrupt or if the register is
573 	// clearly invalid.
574 	if ((intmask == 0) || (intmask == 0xffffffff)) {
575 		return B_UNHANDLED_INTERRUPT;
576 	}
577 
578 	TRACE("interrupt function called %x\n", intmask);
579 
580 	// handling card presence interrupts
581 	if ((intmask & SDHCI_INT_CARD_REM) != 0) {
582 		// We can get spurious interrupts as the card is inserted or removed,
583 		// so check the actual state before acting
584 		if (!fRegisters->present_state.IsCardInserted())
585 			fRegisters->power_control.PowerOff();
586 		else
587 			TRACE("Card removed interrupt, but card is inserted\n");
588 
589 		fRegisters->interrupt_status |= SDHCI_INT_CARD_REM;
590 		TRACE("Card removal interrupt handled\n");
591 	}
592 
593 	if ((intmask & SDHCI_INT_CARD_INS) != 0) {
594 		// We can get spurious interrupts as the card is inserted or removed,
595 		// so check the actual state before acting
596 		if (fRegisters->present_state.IsCardInserted()) {
597 			if (PowerOn())
598 				SetClock(400);
599 			release_sem_etc(fScanSemaphore, 1, B_DO_NOT_RESCHEDULE);
600 		} else
601 			TRACE("Card insertion interrupt, but card is removed\n");
602 
603 		fRegisters->interrupt_status |= SDHCI_INT_CARD_INS;
604 		TRACE("Card presence interrupt handled\n");
605 	}
606 
607 	// handling command interrupt
608 	if (intmask & SDHCI_INT_CMD_MASK) {
609 		fCommandResult = intmask;
610 			// Save the status before clearing so the thread can handle it
611 		fRegisters->interrupt_status |= (intmask & SDHCI_INT_CMD_MASK);
612 
613 		// Notify the thread
614 		release_sem_etc(fSemaphore, 1, B_DO_NOT_RESCHEDULE);
615 		TRACE("Command complete interrupt handled\n");
616 	}
617 
618 	if (intmask & SDHCI_INT_TRANS_CMP) {
619 		fCommandResult = intmask;
620 		fRegisters->interrupt_status |= SDHCI_INT_TRANS_CMP;
621 		release_sem_etc(fSemaphore, 1, B_DO_NOT_RESCHEDULE);
622 		TRACE("Transfer complete interrupt handled\n");
623 	}
624 
625 	// handling bus power interrupt
626 	if (intmask & SDHCI_INT_BUS_POWER) {
627 		fRegisters->interrupt_status |= SDHCI_INT_BUS_POWER;
628 		TRACE("card is consuming too much power\n");
629 	}
630 
631 	// Check that all interrupts have been cleared (we check all the ones we
632 	// enabled, so that should always be the case)
633 	intmask = fRegisters->interrupt_status;
634 	if (intmask != 0) {
635 		ERROR("Remaining interrupts at end of handler: %x\n", intmask);
636 	}
637 
638 	return B_HANDLED_INTERRUPT;
639 }
640 // #pragma mark -
641 
642 
643 static status_t
644 init_bus(device_node* node, void** bus_cookie)
645 {
646 	CALLED();
647 
648 	// Get the PCI driver and device
649 	pci_device_module_info* pci;
650 	pci_device* device;
651 
652 	device_node* parent = gDeviceManager->get_parent_node(node);
653 	device_node* pciParent = gDeviceManager->get_parent_node(parent);
654 	gDeviceManager->get_driver(pciParent, (driver_module_info**)&pci,
655 	        (void**)&device);
656 	gDeviceManager->put_node(pciParent);
657 	gDeviceManager->put_node(parent);
658 
659 	if (get_module(B_PCI_X86_MODULE_NAME, (module_info**)&sPCIx86Module)
660 	    != B_OK) {
661 	    sPCIx86Module = NULL;
662 		ERROR("PCIx86Module not loaded\n");
663 		// FIXME try probing FDT as well
664 		return B_NO_MEMORY;
665 	}
666 
667 	uint8_t bar, slot;
668 	if (gDeviceManager->get_attr_uint8(node, SLOT_NUMBER, &slot, false) < B_OK
669 		|| gDeviceManager->get_attr_uint8(node, BAR_INDEX, &bar, false) < B_OK)
670 		return B_BAD_TYPE;
671 
672 	// Ignore invalid bars
673 	TRACE("Register SD bus at slot %d, using bar %d\n", slot + 1, bar);
674 
675 	pci_info pciInfo;
676 	pci->get_pci_info(device, &pciInfo);
677 
678 	if (pciInfo.u.h0.base_register_sizes[bar] == 0) {
679 		ERROR("No registers to map\n");
680 		return B_IO_ERROR;
681 	}
682 
683 	int msiCount = sPCIx86Module->get_msi_count(pciInfo.bus,
684 		pciInfo.device, pciInfo.function);
685 	TRACE("interrupts count: %d\n",msiCount);
686 	// FIXME if available, use MSI rather than good old IRQ...
687 
688 	// enable bus master and io
689 	uint16 pcicmd = pci->read_pci_config(device, PCI_command, 2);
690 	pcicmd &= ~(PCI_command_int_disable | PCI_command_io);
691 	pcicmd |= PCI_command_master | PCI_command_memory;
692 	pci->write_pci_config(device, PCI_command, 2, pcicmd);
693 
694 	// map the slot registers
695 	area_id	regs_area;
696 	struct registers* _regs;
697 	regs_area = map_physical_memory("sdhc_regs_map",
698 		pciInfo.u.h0.base_registers[bar],
699 		pciInfo.u.h0.base_register_sizes[bar], B_ANY_KERNEL_BLOCK_ADDRESS,
700 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void**)&_regs);
701 
702 	if (regs_area < B_OK) {
703 		ERROR("Could not map registers\n");
704 		return B_BAD_VALUE;
705 	}
706 
707 	// the interrupt is shared between all busses in an SDHC controller, but
708 	// they each register an handler. Not a problem, we will just test the
709 	// interrupt registers for all busses one after the other and find no
710 	// interrupts on the idle busses.
711 	uint8_t irq = pciInfo.u.h0.interrupt_line;
712 	TRACE("irq interrupt line: %d\n", irq);
713 
714 	SdhciBus* bus = new(std::nothrow) SdhciBus(_regs, irq);
715 
716 	status_t status = B_NO_MEMORY;
717 	if (bus != NULL)
718 		status = bus->InitCheck();
719 
720 	if (status != B_OK) {
721 		if (sPCIx86Module != NULL) {
722 			put_module(B_PCI_X86_MODULE_NAME);
723 			sPCIx86Module = NULL;
724 		}
725 
726 		if (bus != NULL)
727 			delete bus;
728 		else
729 			delete_area(regs_area);
730 		return status;
731 	}
732 
733 	// Store the created object as a cookie, allowing users of the bus to
734 	// locate it.
735 	*bus_cookie = bus;
736 
737 	return status;
738 }
739 
740 
741 static void
742 uninit_bus(void* bus_cookie)
743 {
744 	SdhciBus* bus = (SdhciBus*)bus_cookie;
745 	delete bus;
746 
747 	// FIXME do we need to put() the PCI module here?
748 }
749 
750 
751 static void
752 bus_removed(void* bus_cookie)
753 {
754 	return;
755 }
756 
757 
758 static status_t
759 register_child_devices(void* cookie)
760 {
761 	CALLED();
762 	SdhciDevice* context = (SdhciDevice*)cookie;
763 	device_node* parent = gDeviceManager->get_parent_node(context->fNode);
764 	pci_device_module_info* pci;
765 	pci_device* device;
766 	uint8 slots_count, bar, slotsInfo;
767 
768 	gDeviceManager->get_driver(parent, (driver_module_info**)&pci,
769 		(void**)&device);
770 	slotsInfo = pci->read_pci_config(device, SDHCI_PCI_SLOT_INFO, 1);
771 	bar = SDHCI_PCI_SLOT_INFO_FIRST_BASE_INDEX(slotsInfo);
772 	slots_count = SDHCI_PCI_SLOTS(slotsInfo);
773 
774 	char prettyName[25];
775 
776 	if (slots_count > 6 || bar > 5) {
777 		ERROR("Invalid slots count: %d or BAR count: %d \n", slots_count, bar);
778 		return B_BAD_VALUE;
779 	}
780 
781 	for (uint8_t slot = 0; slot <= slots_count; slot++) {
782 		sprintf(prettyName, "SDHC bus %" B_PRIu8, slot);
783 		device_attr attrs[] = {
784 			// properties of this controller for mmc bus manager
785 			{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: prettyName } },
786 			{ B_DEVICE_FIXED_CHILD, B_STRING_TYPE,
787 				{string: MMC_BUS_MODULE_NAME} },
788 			{ B_DEVICE_BUS, B_STRING_TYPE, {string: "mmc"} },
789 
790 			// DMA properties
791 			// The high alignment is to force access only to complete sectors
792 			// These constraints could be removed by using ADMA which allows
793 			// use of the full 64bit address space and can do scatter-gather.
794 			{ B_DMA_ALIGNMENT, B_UINT32_TYPE, { ui32: 511 }},
795 			{ B_DMA_HIGH_ADDRESS, B_UINT64_TYPE, { ui64: 0x100000000LL }},
796 			{ B_DMA_BOUNDARY, B_UINT32_TYPE, { ui32: (1 << 19) - 1 }},
797 			{ B_DMA_MAX_SEGMENT_COUNT, B_UINT32_TYPE, { ui32: 1 }},
798 			{ B_DMA_MAX_SEGMENT_BLOCKS, B_UINT32_TYPE, { ui32: (1 << 10) - 1 }},
799 
800 			// private data to identify device
801 			{ SLOT_NUMBER, B_UINT8_TYPE, { ui8: slot} },
802 			{ BAR_INDEX, B_UINT8_TYPE, { ui8: bar + slot} },
803 			{ NULL }
804 		};
805 		device_node* node;
806 		if (gDeviceManager->register_node(context->fNode,
807 				SDHCI_PCI_MMC_BUS_MODULE_NAME, attrs, NULL,
808 				&node) != B_OK)
809 			return B_BAD_VALUE;
810 	}
811 	return B_OK;
812 }
813 
814 
815 static status_t
816 init_device(device_node* node, void** device_cookie)
817 {
818 	CALLED();
819 
820 	// Get the PCI driver and device
821 	pci_device_module_info* pci;
822 	pci_device* device;
823 	uint16 vendorId, deviceId;
824 
825 	device_node* pciParent = gDeviceManager->get_parent_node(node);
826 	gDeviceManager->get_driver(pciParent, (driver_module_info**)&pci,
827 	        (void**)&device);
828 	gDeviceManager->put_node(pciParent);
829 
830 	SdhciDevice* context = new(std::nothrow)SdhciDevice;
831 	if (context == NULL)
832 		return B_NO_MEMORY;
833 	context->fNode = node;
834 	*device_cookie = context;
835 
836 	if (gDeviceManager->get_attr_uint16(node, B_DEVICE_VENDOR_ID,
837 			&vendorId, true) != B_OK
838 		|| gDeviceManager->get_attr_uint16(node, B_DEVICE_ID, &deviceId,
839 			true) != B_OK) {
840 		panic("No vendor or device id attribute\n");
841 		return B_OK; // Let's hope it didn't need the quirk?
842 	}
843 
844 	if (vendorId == 0x1180 && deviceId == 0xe823) {
845 		// Switch the device to SD2.0 mode
846 		// This should change its device id to 0xe822 if succesful.
847 		// The device then remains in SD2.0 mode even after reboot.
848 		pci->write_pci_config(device, SDHCI_PCI_RICOH_MODE_KEY, 1, 0xfc);
849 		context->fRicohOriginalMode = pci->read_pci_config(device,
850 			SDHCI_PCI_RICOH_MODE, 1);
851 		pci->write_pci_config(device, SDHCI_PCI_RICOH_MODE, 1,
852 			SDHCI_PCI_RICOH_MODE_SD20);
853 		pci->write_pci_config(device, SDHCI_PCI_RICOH_MODE_KEY, 1, 0);
854 
855 		deviceId = pci->read_pci_config(device, 2, 2);
856 		TRACE("Device ID after Ricoh quirk: %x\n", deviceId);
857 	}
858 
859 	return B_OK;
860 }
861 
862 
863 static void
864 uninit_device(void* device_cookie)
865 {
866 	// Get the PCI driver and device
867 	pci_device_module_info* pci;
868 	pci_device* device;
869 	uint16 vendorId, deviceId;
870 
871 	SdhciDevice* context = (SdhciDevice*)device_cookie;
872 	device_node* pciParent = gDeviceManager->get_parent_node(context->fNode);
873 	gDeviceManager->get_driver(pciParent, (driver_module_info**)&pci,
874 	        (void**)&device);
875 
876 	if (gDeviceManager->get_attr_uint16(context->fNode, B_DEVICE_VENDOR_ID,
877 			&vendorId, true) != B_OK
878 		|| gDeviceManager->get_attr_uint16(context->fNode, B_DEVICE_ID,
879 			&deviceId, false) != B_OK) {
880 		ERROR("No vendor or device id attribute\n");
881 	} else if (vendorId == 0x1180 && deviceId == 0xe823) {
882 		pci->write_pci_config(device, SDHCI_PCI_RICOH_MODE_KEY, 1, 0xfc);
883 		pci->write_pci_config(device, SDHCI_PCI_RICOH_MODE, 1,
884 			context->fRicohOriginalMode);
885 		pci->write_pci_config(device, SDHCI_PCI_RICOH_MODE_KEY, 1, 0);
886 	}
887 
888 	gDeviceManager->put_node(pciParent);
889 
890 	delete context;
891 }
892 
893 
894 static status_t
895 register_device(device_node* parent)
896 {
897 	device_attr attrs[] = {
898 		{B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "SD Host Controller"}},
899 		{}
900 	};
901 
902 	return gDeviceManager->register_node(parent, SDHCI_PCI_DEVICE_MODULE_NAME,
903 		attrs, NULL, NULL);
904 }
905 
906 
907 static float
908 supports_device(device_node* parent)
909 {
910 	const char* bus;
911 	uint16 type, subType;
912 	uint16 vendorId, deviceId;
913 
914 	// make sure parent is a PCI SDHCI device node
915 	if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)
916 		!= B_OK) {
917 		TRACE("Could not find required attribute device/bus\n");
918 		return -1;
919 	}
920 
921 	if (strcmp(bus, "pci") != 0)
922 		return 0.0f;
923 
924 	if (gDeviceManager->get_attr_uint16(parent, B_DEVICE_VENDOR_ID, &vendorId,
925 			false) != B_OK
926 		|| gDeviceManager->get_attr_uint16(parent, B_DEVICE_ID, &deviceId,
927 			false) != B_OK) {
928 		TRACE("No vendor or device id attribute\n");
929 		return 0.0f;
930 	}
931 
932 	TRACE("supports_device(vid:%04x pid:%04x)\n", vendorId, deviceId);
933 
934 	if (gDeviceManager->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, &subType,
935 			false) < B_OK
936 		|| gDeviceManager->get_attr_uint16(parent, B_DEVICE_TYPE, &type,
937 			false) < B_OK) {
938 		TRACE("Could not find type/subtype attributes\n");
939 		return -1;
940 	}
941 
942 	if (type == PCI_base_peripheral) {
943 		if (subType != PCI_sd_host) {
944 			// Also accept some compliant devices that do not advertise
945 			// themselves as such.
946 			if (vendorId != 0x1180
947 				|| (deviceId != 0xe823 && deviceId != 0xe822)) {
948 				TRACE("Not the right subclass, and not a Ricoh device\n");
949 				return 0.0f;
950 			}
951 		}
952 
953 		pci_device_module_info* pci;
954 		pci_device* device;
955 		gDeviceManager->get_driver(parent, (driver_module_info**)&pci,
956 			(void**)&device);
957 		TRACE("SDHCI Device found! Subtype: 0x%04x, type: 0x%04x\n",
958 			subType, type);
959 
960 		return 0.8f;
961 	}
962 
963 	return 0.0f;
964 }
965 
966 
967 static status_t
968 set_clock(void* controller, uint32_t kilohertz)
969 {
970 	SdhciBus* bus = (SdhciBus*)controller;
971 	bus->SetClock(kilohertz);
972 	return B_OK;
973 }
974 
975 
976 static status_t
977 execute_command(void* controller, uint8_t command, uint32_t argument,
978 	uint32_t* response)
979 {
980 	SdhciBus* bus = (SdhciBus*)controller;
981 	return bus->ExecuteCommand(command, argument, response);
982 }
983 
984 
985 static status_t
986 do_io(void* controller, uint8_t command, IOOperation* operation,
987 	bool offsetAsSectors)
988 {
989 	CALLED();
990 
991 	SdhciBus* bus = (SdhciBus*)controller;
992 	return bus->DoIO(command, operation, offsetAsSectors);
993 }
994 
995 
996 static void
997 set_scan_semaphore(void* controller, sem_id sem)
998 {
999 	CALLED();
1000 
1001 	SdhciBus* bus = (SdhciBus*)controller;
1002 	return bus->SetScanSemaphore(sem);
1003 }
1004 
1005 
1006 static void
1007 set_bus_width(void* controller, int width)
1008 {
1009 	CALLED();
1010 
1011 	SdhciBus* bus = (SdhciBus*)controller;
1012 	return bus->SetBusWidth(width);
1013 }
1014 
1015 
1016 module_dependency module_dependencies[] = {
1017 	{ MMC_BUS_MODULE_NAME, (module_info**)&gMMCBusController},
1018 	{ B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager },
1019 	{}
1020 };
1021 
1022 
1023 // Device node registered for each SD slot. It implements the MMC operations so
1024 // the bus manager can use it to communicate with SD cards.
1025 static mmc_bus_interface gSDHCIPCIDeviceModule = {
1026 	{
1027 		{
1028 			SDHCI_PCI_MMC_BUS_MODULE_NAME,
1029 			0,
1030 			NULL
1031 		},
1032 		NULL,	// supports device
1033 		NULL,	// register device
1034 		init_bus,
1035 		uninit_bus,
1036 		NULL,	// register child devices
1037 		NULL,	// rescan
1038 		bus_removed,
1039 	},
1040 
1041 	set_clock,
1042 	execute_command,
1043 	do_io,
1044 	set_scan_semaphore,
1045 	set_bus_width
1046 };
1047 
1048 
1049 // Root device that binds to the PCI bus. It will register an mmc_bus_interface
1050 // node for each SD slot in the device.
1051 static driver_module_info sSDHCIDevice = {
1052 	{
1053 		SDHCI_PCI_DEVICE_MODULE_NAME,
1054 		0,
1055 		NULL
1056 	},
1057 	supports_device,
1058 	register_device,
1059 	init_device,
1060 	uninit_device,
1061 	register_child_devices,
1062 	NULL,	// rescan
1063 	NULL,	// device removed
1064 };
1065 
1066 
1067 module_info* modules[] = {
1068 	(module_info* )&sSDHCIDevice,
1069 	(module_info* )&gSDHCIPCIDeviceModule,
1070 	NULL
1071 };
1072