port of the BSD sdhc driver. breaks sd support atm

This commit is contained in:
Sven Peter 2009-04-11 18:20:16 +02:00 committed by bushing
parent cd4872979d
commit 3438ba21bb
14 changed files with 2039 additions and 1126 deletions

29
bsdtypes.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef __BSDTYPES_H__
#define __BSDTYPES_H__
#include "types.h"
#include "errno.h"
typedef u32 u_int;
typedef u32 u_int32_t;
typedef u16 u_int16_t;
typedef u8 u_int8_t;
typedef u8 u_char;
typedef u32 bus_space_tag_t;
typedef u32 bus_space_handle_t;
struct device {
char dv_xname[255];
void *dummy;
};
#define MIN(a, b) (((a)>(b))?(b):(a))
#define wakeup(...)
#define bzero(mem, size) memset(mem, 0, size)
#define ISSET(var, mask) (((var) & (mask)) == (mask) ? 1 : 0)
#define SET(var, mask) ((var) |= (mask))
#endif

View File

@ -7,13 +7,13 @@
#include "diskio.h"
#include "string.h"
#include "sdhc.h"
//#include "sdhc.h"
#ifndef MEM2_BSS
#define MEM2_BSS
#endif
static sdhci_t sdhci;
//static sdhci_t sdhci;
static u8 buffer[512] MEM2_BSS ALIGNED(32);
/*-----------------------------------------------------------------------*/
@ -25,8 +25,8 @@ DSTATUS disk_initialize (
{
s32 ret;
sd_init(&sdhci, 0);
ret = sd_mount(&sdhci);
// sd_init(&sdhci, 0);
// ret = sd_mount(&sdhci);
if (ret < 0)
return STA_NOINIT;
@ -43,8 +43,8 @@ DSTATUS disk_status (
BYTE drv /* Physical drive nmuber (0..) */
)
{
if (sd_inserted(&sdhci) == 0)
return STA_NODISK;
// if (sd_inserted(&sdhci) == 0)
// return STA_NODISK;
return 0;
}
@ -66,10 +66,10 @@ DRESULT disk_read (
res = RES_OK;
for (i = 0; i < count; i++) {
if (sd_read(&sdhci, sector + i, 1, buffer) != 0) {
/* if (sd_read(&sdhci, sector + i, 1, buffer) != 0) {
res = RES_ERROR;
break;
}
}*/
memcpy(buff + i * 512, buffer, 512);
}
@ -97,10 +97,10 @@ DRESULT disk_write (
for (i = 0; i < count; i++) {
memcpy(buffer, buff + i * 512, 512);
if(sd_write(&sdhci, sector + i, 1, buffer) != 0) {
/* if(sd_write(&sdhci, sector + i, 1, buffer) != 0) {
res = RES_ERROR;
break;
}
}*/
}
return res;

175
errno.h Normal file
View File

@ -0,0 +1,175 @@
/* $OpenBSD: errno.h,v 1.20 2007/09/03 14:37:52 millert Exp $ */
/* $NetBSD: errno.h,v 1.10 1996/01/20 01:33:53 jtc Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)errno.h 8.5 (Berkeley) 1/21/94
*/
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* Input/output error */
#define ENXIO 6 /* Device not configured */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file descriptor */
#define ECHILD 10 /* No child processes */
#define EDEADLK 11 /* Resource deadlock avoided */
/* 11 was EAGAIN */
#define ENOMEM 12 /* Cannot allocate memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#if __BSD_VISIBLE
#define ENOTBLK 15 /* Block device required */
#endif
#define EBUSY 16 /* Device busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* Operation not supported by device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* Too many open files in system */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Inappropriate ioctl for device */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
/* math software */
#define EDOM 33 /* Numerical argument out of domain */
#define ERANGE 34 /* Result too large */
/* non-blocking and interrupt i/o */
#define EAGAIN 35 /* Resource temporarily unavailable */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define EINPROGRESS 36 /* Operation now in progress */
#define EALREADY 37 /* Operation already in progress */
/* ipc/network software -- argument errors */
#define ENOTSOCK 38 /* Socket operation on non-socket */
#define EDESTADDRREQ 39 /* Destination address required */
#define EMSGSIZE 40 /* Message too long */
#define EPROTOTYPE 41 /* Protocol wrong type for socket */
#define ENOPROTOOPT 42 /* Protocol not available */
#define EPROTONOSUPPORT 43 /* Protocol not supported */
#if __BSD_VISIBLE
#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
#endif
#define EOPNOTSUPP 45 /* Operation not supported */
#if __BSD_VISIBLE
#define EPFNOSUPPORT 46 /* Protocol family not supported */
#endif
#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
#define EADDRINUSE 48 /* Address already in use */
#define EADDRNOTAVAIL 49 /* Can't assign requested address */
/* ipc/network software -- operational errors */
#define ENETDOWN 50 /* Network is down */
#define ENETUNREACH 51 /* Network is unreachable */
#define ENETRESET 52 /* Network dropped connection on reset */
#define ECONNABORTED 53 /* Software caused connection abort */
#define ECONNRESET 54 /* Connection reset by peer */
#define ENOBUFS 55 /* No buffer space available */
#define EISCONN 56 /* Socket is already connected */
#define ENOTCONN 57 /* Socket is not connected */
#if __BSD_VISIBLE
#define ESHUTDOWN 58 /* Can't send after socket shutdown */
#define ETOOMANYREFS 59 /* Too many references: can't splice */
#endif /* __BSD_VISIBLE */
#define ETIMEDOUT 60 /* Operation timed out */
#define ECONNREFUSED 61 /* Connection refused */
#define ELOOP 62 /* Too many levels of symbolic links */
#define ENAMETOOLONG 63 /* File name too long */
/* should be rearranged */
#if __BSD_VISIBLE
#define EHOSTDOWN 64 /* Host is down */
#define EHOSTUNREACH 65 /* No route to host */
#endif /* __BSD_VISIBLE */
#define ENOTEMPTY 66 /* Directory not empty */
/* quotas & mush */
#if __BSD_VISIBLE
#define EPROCLIM 67 /* Too many processes */
#define EUSERS 68 /* Too many users */
#endif /* __BSD_VISIBLE */
#define EDQUOT 69 /* Disk quota exceeded */
/* Network File System */
#define ESTALE 70 /* Stale NFS file handle */
#if __BSD_VISIBLE
#define EREMOTE 71 /* Too many levels of remote in path */
#define EBADRPC 72 /* RPC struct is bad */
#define ERPCMISMATCH 73 /* RPC version wrong */
#define EPROGUNAVAIL 74 /* RPC prog. not avail */
#define EPROGMISMATCH 75 /* Program version wrong */
#define EPROCUNAVAIL 76 /* Bad procedure for program */
#endif /* __BSD_VISIBLE */
#define ENOLCK 77 /* No locks available */
#define ENOSYS 78 /* Function not implemented */
#if __BSD_VISIBLE
#define EFTYPE 79 /* Inappropriate file type or format */
#define EAUTH 80 /* Authentication error */
#define ENEEDAUTH 81 /* Need authenticator */
#define EIPSEC 82 /* IPsec processing failure */
#define ENOATTR 83 /* Attribute not found */
#endif /* __BSD_VISIBLE */
#define EILSEQ 84 /* Illegal byte sequence */
#if __BSD_VISIBLE
#define ENOMEDIUM 85 /* No medium found */
#define EMEDIUMTYPE 86 /* Wrong Medium Type */
#define EOVERFLOW 87 /* Conversion overflow */
#define ECANCELED 88 /* Operation canceled */
#endif /* __BSD_VISIBLE */
#define EIDRM 89 /* Identifier removed */
#define ENOMSG 90 /* No message of desired type */
#if __BSD_VISIBLE
#define ELAST 90 /* Must be equal largest errno */
#endif /* __BSD_VISIBLE */
#ifdef _KERNEL
/* pseudo-errors returned inside kernel to modify return to process */
#define ERESTART -1 /* restart syscall */
#define EJUSTRETURN -2 /* don't modify regs, just return */
#endif

View File

@ -154,8 +154,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
/* SD Host Controller Registers */
#define SD_REG_BASE 0xd070000
#define SDHC_REG_BASE 0xd070000
#if 0
#define SDHC_SDMA_ADDR (0x000)
#define SDHC_BLOCK_SIZE (0x004)
#define SDHC_BLOCK_COUNT (0x006)
@ -187,6 +188,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define SDHC_ADMA_SYSTEM_ADDR (0x058)
#define SDHC_SLOT_INTERRUPT_STATUS (0x0fc)
#define SDHC_VERSION (0x0fe)
#endif
/* EXI Registers */

4
ipc.c
View File

@ -30,7 +30,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "gecko.h"
#include "ipc.h"
#include "nand.h"
#include "sdhc.h"
//#include "sdhc.h"
#include "crypto.h"
#include "boot2.h"
#include "powerpc.h"
@ -150,7 +150,7 @@ static u32 process_slow(volatile ipc_request *req)
nand_ipc(req);
break;
case IPC_DEV_SD:
sd_ipc(req);
// sd_ipc(req);
break;
case IPC_DEV_KEYS:
crypto_ipc(req);

7
irq.c
View File

@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "ipc.h"
#include "crypto.h"
#include "nand.h"
#include "sdhcvar.h"
static u32 _alarm_frequency = 0;
@ -98,6 +99,12 @@ void irq_handler(void)
gecko_printf("IRQ: AES\n");
write32(HW_ARMIRQFLAG, IRQF_AES);
}
if (flags & IRQF_SDHC) {
gecko_printf("IRQ: SDHC\n");
write32(HW_ARMIRQFLAG, IRQF_SDHC);
sdhc_irq();
}
flags &= ~IRQF_ALL;
if(flags) {
gecko_printf("IRQ: unknown 0x%08x\n", flags);

3
irq.h
View File

@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define IRQF_TIMER (1<<IRQ_TIMER)
#define IRQF_NAND (1<<IRQ_NAND)
#define IRQF_AES (1<<IRQ_AES)
#define IRQF_SDHC (1<<IRQ_SDHC)
#define IRQF_GPIO1B (1<<IRQ_GPIO1B)
#define IRQF_GPIO1 (1<<IRQ_GPIO1)
#define IRQF_RESET (1<<IRQ_RESET)
@ -47,7 +48,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define IRQF_ALL ( \
IRQF_TIMER|IRQF_NAND|IRQF_GPIO1B|IRQF_GPIO1| \
IRQF_RESET|IRQF_IPC|IRQF_AES \
IRQF_RESET|IRQF_IPC|IRQF_AES|IRQF_SDHC \
)
#define CPSR_IRQDIS 0x80

7
main.c
View File

@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "utils.h"
#include "start.h"
#include "hollywood.h"
#include "sdhc.h"
#include "sdhcvar.h"
#include "string.h"
#include "memory.h"
#include "elf.h"
@ -204,8 +204,9 @@ u32 _main(void *base)
gecko_printf("Initializing IPC...\n");
ipc_initialize();
gecko_printf("Initializing SD...\n");
sd_initialize();
gecko_printf("Initializing SDHC...\n");
sdhc_init();
// sd_initialize();
gecko_printf("Mounting SD...\n");
fres = f_mount(0, &fatfs);

2080
sdhc.c

File diff suppressed because it is too large Load Diff

189
sdhcreg.h Normal file
View File

@ -0,0 +1,189 @@
/* $OpenBSD: sdhcreg.h,v 1.4 2006/07/30 17:20:40 fgsch Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SDHCREG_H_
#define _SDHCREG_H_
/* PCI base address registers */
#define SDHC_PCI_BAR_START PCI_MAPREG_START
#define SDHC_PCI_BAR_END PCI_MAPREG_END
/* PCI interface classes */
#define SDHC_PCI_INTERFACE_NO_DMA 0x00
#define SDHC_PCI_INTERFACE_DMA 0x01
#define SDHC_PCI_INTERFACE_VENDOR 0x02
/* Host standard register set */
#define SDHC_DMA_ADDR 0x00
#define SDHC_BLOCK_SIZE 0x04
#define SDHC_BLOCK_COUNT 0x06
#define SDHC_BLOCK_COUNT_MAX 512
#define SDHC_ARGUMENT 0x08
#define SDHC_TRANSFER_MODE 0x0c
#define SDHC_MULTI_BLOCK_MODE (1<<5)
#define SDHC_READ_MODE (1<<4)
#define SDHC_AUTO_CMD12_ENABLE (1<<2)
#define SDHC_BLOCK_COUNT_ENABLE (1<<1)
#define SDHC_DMA_ENABLE (1<<0)
#define SDHC_COMMAND 0x0e
/* 14-15 reserved */
#define SDHC_COMMAND_INDEX_SHIFT 8
#define SDHC_COMMAND_INDEX_MASK 0x3f
#define SDHC_COMMAND_TYPE_ABORT (3<<6)
#define SDHC_COMMAND_TYPE_RESUME (2<<6)
#define SDHC_COMMAND_TYPE_SUSPEND (1<<6)
#define SDHC_COMMAND_TYPE_NORMAL (0<<6)
#define SDHC_DATA_PRESENT_SELECT (1<<5)
#define SDHC_INDEX_CHECK_ENABLE (1<<4)
#define SDHC_CRC_CHECK_ENABLE (1<<3)
/* 2 reserved */
#define SDHC_RESP_LEN_48_CHK_BUSY (3<<0)
#define SDHC_RESP_LEN_48 (2<<0)
#define SDHC_RESP_LEN_136 (1<<0)
#define SDHC_NO_RESPONSE (0<<0)
#define SDHC_RESPONSE 0x10 /* - 0x1f */
#define SDHC_DATA 0x20
#define SDHC_PRESENT_STATE 0x24
/* 25-31 reserved */
#define SDHC_CMD_LINE_SIGNAL_LEVEL (1<<24)
#define SDHC_DAT3_LINE_LEVEL (1<<23)
#define SDHC_DAT2_LINE_LEVEL (1<<22)
#define SDHC_DAT1_LINE_LEVEL (1<<21)
#define SDHC_DAT0_LINE_LEVEL (1<<20)
#define SDHC_WRITE_PROTECT_SWITCH (1<<19)
#define SDHC_CARD_DETECT_PIN_LEVEL (1<<18)
#define SDHC_CARD_STATE_STABLE (1<<17)
#define SDHC_CARD_INSERTED (1<<16)
/* 12-15 reserved */
#define SDHC_BUFFER_READ_ENABLE (1<<11)
#define SDHC_BUFFER_WRITE_ENABLE (1<<10)
#define SDHC_READ_TRANSFER_ACTIVE (1<<9)
#define SDHC_WRITE_TRANSFER_ACTIVE (1<<8)
/* 3-7 reserved */
#define SDHC_DAT_ACTIVE (1<<2)
#define SDHC_CMD_INHIBIT_DAT (1<<1)
#define SDHC_CMD_INHIBIT_CMD (1<<0)
#define SDHC_CMD_INHIBIT_MASK 0x0003
#define SDHC_HOST_CTL 0x28
#define SDHC_HIGH_SPEED (1<<2)
#define SDHC_4BIT_MODE (1<<1)
#define SDHC_LED_ON (1<<0)
#define SDHC_POWER_CTL 0x29
#define SDHC_VOLTAGE_SHIFT 1
#define SDHC_VOLTAGE_MASK 0x07
#define SDHC_VOLTAGE_3_3V 0x07
#define SDHC_VOLTAGE_3_0V 0x06
#define SDHC_VOLTAGE_1_8V 0x05
#define SDHC_BUS_POWER (1<<0)
#define SDHC_BLOCK_GAP_CTL 0x2a
#define SDHC_WAKEUP_CTL 0x2b
#define SDHC_CLOCK_CTL 0x2c
#define SDHC_SDCLK_DIV_SHIFT 8
#define SDHC_SDCLK_DIV_MASK 0xff
#define SDHC_SDCLK_ENABLE (1<<2)
#define SDHC_INTCLK_STABLE (1<<1)
#define SDHC_INTCLK_ENABLE (1<<0)
#define SDHC_TIMEOUT_CTL 0x2e
#define SDHC_TIMEOUT_MAX 0x0e
#define SDHC_SOFTWARE_RESET 0x2f
#define SDHC_RESET_MASK 0x5
#define SDHC_RESET_DAT (1<<2)
#define SDHC_RESET_CMD (1<<1)
#define SDHC_RESET_ALL (1<<0)
#define SDHC_NINTR_STATUS 0x30
#define SDHC_ERROR_INTERRUPT (1<<15)
#define SDHC_CARD_INTERRUPT (1<<8)
#define SDHC_CARD_REMOVAL (1<<7)
#define SDHC_CARD_INSERTION (1<<6)
#define SDHC_BUFFER_READ_READY (1<<5)
#define SDHC_BUFFER_WRITE_READY (1<<4)
#define SDHC_DMA_INTERRUPT (1<<3)
#define SDHC_BLOCK_GAP_EVENT (1<<2)
#define SDHC_TRANSFER_COMPLETE (1<<1)
#define SDHC_COMMAND_COMPLETE (1<<0)
#define SDHC_NINTR_STATUS_MASK 0x81ff
#define SDHC_EINTR_STATUS 0x32
#define SDHC_AUTO_CMD12_ERROR (1<<8)
#define SDHC_CURRENT_LIMIT_ERROR (1<<7)
#define SDHC_DATA_END_BIT_ERROR (1<<6)
#define SDHC_DATA_CRC_ERROR (1<<5)
#define SDHC_DATA_TIMEOUT_ERROR (1<<4)
#define SDHC_CMD_INDEX_ERROR (1<<3)
#define SDHC_CMD_END_BIT_ERROR (1<<2)
#define SDHC_CMD_CRC_ERROR (1<<1)
#define SDHC_CMD_TIMEOUT_ERROR (1<<0)
#define SDHC_EINTR_STATUS_MASK 0x01ff /* excluding vendor signals */
#define SDHC_NINTR_STATUS_EN 0x34
#define SDHC_EINTR_STATUS_EN 0x36
#define SDHC_NINTR_SIGNAL_EN 0x38
#define SDHC_NINTR_SIGNAL_MASK 0x01ff
#define SDHC_EINTR_SIGNAL_EN 0x3a
#define SDHC_EINTR_SIGNAL_MASK 0x01ff /* excluding vendor signals */
#define SDHC_CMD12_ERROR_STATUS 0x3c
#define SDHC_CAPABILITIES 0x40
#define SDHC_VOLTAGE_SUPP_1_8V (1<<26)
#define SDHC_VOLTAGE_SUPP_3_0V (1<<25)
#define SDHC_VOLTAGE_SUPP_3_3V (1<<24)
#define SDHC_DMA_SUPPORT (1<<22)
#define SDHC_HIGH_SPEED_SUPP (1<<21)
#define SDHC_MAX_BLK_LEN_512 0
#define SDHC_MAX_BLK_LEN_1024 1
#define SDHC_MAX_BLK_LEN_2048 2
#define SDHC_MAX_BLK_LEN_SHIFT 16
#define SDHC_MAX_BLK_LEN_MASK 0x3
#define SDHC_BASE_FREQ_SHIFT 8
#define SDHC_BASE_FREQ_MASK 0x3f
#define SDHC_TIMEOUT_FREQ_UNIT (1<<7) /* 0=KHz, 1=MHz */
#define SDHC_TIMEOUT_FREQ_SHIFT 0
#define SDHC_TIMEOUT_FREQ_MASK 0x1f
#define SDHC_MAX_CAPABILITIES 0x48
#define SDHC_SLOT_INTR_STATUS 0xfc
#define SDHC_HOST_CTL_VERSION 0xfe
#define SDHC_SPEC_VERS_SHIFT 0
#define SDHC_SPEC_VERS_MASK 0xff
#define SDHC_VENDOR_VERS_SHIFT 8
#define SDHC_VENDOR_VERS_MASK 0xff
/* SDHC_CAPABILITIES decoding */
#define SDHC_BASE_FREQ_KHZ(cap) \
((((cap) >> SDHC_BASE_FREQ_SHIFT) & SDHC_BASE_FREQ_MASK) * 1000)
#define SDHC_TIMEOUT_FREQ(cap) \
(((cap) >> SDHC_TIMEOUT_FREQ_SHIFT) & SDHC_TIMEOUT_FREQ_MASK)
#define SDHC_TIMEOUT_FREQ_KHZ(cap) \
(((cap) & SDHC_TIMEOUT_FREQ_UNIT) ? \
SDHC_TIMEOUT_FREQ(cap) * 1000: \
SDHC_TIMEOUT_FREQ(cap))
/* SDHC_HOST_CTL_VERSION decoding */
#define SDHC_SPEC_VERSION(hcv) \
(((hcv) >> SDHC_SPEC_VERS_SHIFT) & SDHC_SPEC_VERS_MASK)
#define SDHC_VENDOR_VERSION(hcv) \
(((hcv) >> SDHC_VENDOR_VERS_SHIFT) & SDHC_VENDOR_VERS_MASK)
#define SDHC_PRESENT_STATE_BITS \
"\20\31CL\30D3L\27D2L\26D1L\25D0L\24WPS\23CD\22CSS\21CI" \
"\14BRE\13BWE\12RTA\11WTA\3DLA\2CID\1CIC"
#define SDHC_NINTR_STATUS_BITS \
"\20\20ERROR\11CARD\10REMOVAL\7INSERTION\6READ\5WRITE" \
"\4DMA\3GAP\2XFER\1CMD"
#define SDHC_EINTR_STATUS_BITS \
"\20\11ACMD12\10CL\7DEB\6DCRC\5DT\4CI\3CEB\2CCRC\1CT"
#define SDHC_CAPABILITIES_BITS \
"\20\33Vdd1.8V\32Vdd3.0V\31Vdd3.3V\30SUSPEND\27DMA\26HIGHSPEED"
#endif

48
sdhcvar.h Normal file
View File

@ -0,0 +1,48 @@
/* $OpenBSD: sdhcvar.h,v 1.3 2007/09/06 08:01:01 jsg Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
* Copyright (c) 2009 Sven Peter <svenpeter@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SDHCVAR_H_
#define _SDHCVAR_H_
#include "bsdtypes.h"
#define SDHC_MAX_HOSTS 4
struct sdhc_host;
struct sdhc_softc {
struct device sc_dev;
struct sdhc_host *sc_host[SDHC_MAX_HOSTS];
int sc_nhosts;
u_int sc_flags;
};
/* Host controller functions called by the attachment driver. */
int sdhc_host_found(struct sdhc_softc *, bus_space_tag_t,
bus_space_handle_t, int);
void sdhc_power(int, void *);
void sdhc_shutdown(void *);
int sdhc_intr(void *);
void sdhc_init(void);
void sdhc_irq(void);
/* flag values */
#define SDHC_F_NOPWR0 (1 << 0)
#endif

88
sdmmcchip.h Normal file
View File

@ -0,0 +1,88 @@
/* $OpenBSD: sdmmcchip.h,v 1.4 2009/02/20 19:16:35 miod Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SDMMC_CHIP_H_
#define _SDMMC_CHIP_H_
struct sdmmc_command;
typedef struct sdmmc_chip_functions *sdmmc_chipset_tag_t;
typedef void *sdmmc_chipset_handle_t;
struct sdmmc_chip_functions {
/* host controller reset */
int (*host_reset)(sdmmc_chipset_handle_t);
/* host capabilities */
u_int32_t (*host_ocr)(sdmmc_chipset_handle_t);
int (*host_maxblklen)(sdmmc_chipset_handle_t);
/* card detection */
int (*card_detect)(sdmmc_chipset_handle_t);
/* bus power and clock frequency */
int (*bus_power)(sdmmc_chipset_handle_t, u_int32_t);
int (*bus_clock)(sdmmc_chipset_handle_t, int);
/* command execution */
void (*exec_command)(sdmmc_chipset_handle_t,
struct sdmmc_command *);
/* card interrupt */
void (*card_intr_mask)(sdmmc_chipset_handle_t, int);
void (*card_intr_ack)(sdmmc_chipset_handle_t);
};
/* host controller reset */
#define sdmmc_chip_host_reset(tag, handle) \
((tag)->host_reset((handle)))
/* host capabilities */
#define sdmmc_chip_host_ocr(tag, handle) \
((tag)->host_ocr((handle)))
#define sdmmc_chip_host_maxblklen(tag, handle) \
((tag)->host_maxblklen((handle)))
/* card detection */
#define sdmmc_chip_card_detect(tag, handle) \
((tag)->card_detect((handle)))
/* bus power and clock frequency */
#define sdmmc_chip_bus_power(tag, handle, ocr) \
((tag)->bus_power((handle), (ocr)))
#define sdmmc_chip_bus_clock(tag, handle, freq) \
((tag)->bus_clock((handle), (freq)))
/* command execution */
#define sdmmc_chip_exec_command(tag, handle, cmdp) \
((tag)->exec_command((handle), (cmdp)))
/* card interrupt */
#define sdmmc_chip_card_intr_mask(tag, handle, enable) \
((tag)->card_intr_mask((handle), (enable)))
#define sdmmc_chip_card_intr_ack(tag, handle) \
((tag)->card_intr_ack((handle)))
/* clock frequencies for sdmmc_chip_bus_clock() */
#define SDMMC_SDCLK_OFF 0
#define SDMMC_SDCLK_400KHZ 400
#define SDMMC_SDCLK_25MHZ 25000
struct sdmmcbus_attach_args {
const char *saa_busname;
sdmmc_chipset_tag_t sct;
sdmmc_chipset_handle_t sch;
int flags;
long max_xfer;
};
void sdmmc_needs_discover(struct device *);
void sdmmc_card_intr(struct device *);
void sdmmc_delay(u_int);
#endif

231
sdmmcreg.h Normal file
View File

@ -0,0 +1,231 @@
/* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SDMMCREG_H_
#define _SDMMCREG_H_
/* MMC commands */ /* response type */
#define MMC_GO_IDLE_STATE 0 /* R0 */
#define MMC_SEND_OP_COND 1 /* R3 */
#define MMC_ALL_SEND_CID 2 /* R2 */
#define MMC_SET_RELATIVE_ADDR 3 /* R1 */
#define MMC_SELECT_CARD 7 /* R1 */
#define MMC_SEND_CSD 9 /* R2 */
#define MMC_STOP_TRANSMISSION 12 /* R1B */
#define MMC_SEND_STATUS 13 /* R1 */
#define MMC_SET_BLOCKLEN 16 /* R1 */
#define MMC_READ_BLOCK_SINGLE 17 /* R1 */
#define MMC_READ_BLOCK_MULTIPLE 18 /* R1 */
#define MMC_SET_BLOCK_COUNT 23 /* R1 */
#define MMC_WRITE_BLOCK_SINGLE 24 /* R1 */
#define MMC_WRITE_BLOCK_MULTIPLE 25 /* R1 */
#define MMC_APP_CMD 55 /* R1 */
/* SD commands */ /* response type */
#define SD_SEND_RELATIVE_ADDR 3 /* R6 */
#define SD_SEND_IF_COND 8 /* R7 */
/* SD application commands */ /* response type */
#define SD_APP_SET_BUS_WIDTH 6 /* R1 */
#define SD_APP_OP_COND 41 /* R3 */
/* OCR bits */
#define MMC_OCR_MEM_READY (1<<31) /* memory power-up status bit */
#define MMC_OCR_3_5V_3_6V (1<<23)
#define MMC_OCR_3_4V_3_5V (1<<22)
#define MMC_OCR_3_3V_3_4V (1<<21)
#define MMC_OCR_3_2V_3_3V (1<<20)
#define MMC_OCR_3_1V_3_2V (1<<19)
#define MMC_OCR_3_0V_3_1V (1<<18)
#define MMC_OCR_2_9V_3_0V (1<<17)
#define MMC_OCR_2_8V_2_9V (1<<16)
#define MMC_OCR_2_7V_2_8V (1<<15)
#define MMC_OCR_2_6V_2_7V (1<<14)
#define MMC_OCR_2_5V_2_6V (1<<13)
#define MMC_OCR_2_4V_2_5V (1<<12)
#define MMC_OCR_2_3V_2_4V (1<<11)
#define MMC_OCR_2_2V_2_3V (1<<10)
#define MMC_OCR_2_1V_2_2V (1<<9)
#define MMC_OCR_2_0V_2_1V (1<<8)
#define MMC_OCR_1_9V_2_0V (1<<7)
#define MMC_OCR_1_8V_1_9V (1<<6)
#define MMC_OCR_1_7V_1_8V (1<<5)
#define MMC_OCR_1_6V_1_7V (1<<4)
#define SD_OCR_SDHC_CAP (1<<30)
#define SD_OCR_VOL_MASK 0xFF8000 /* bits 23:15 */
/* R1 response type bits */
#define MMC_R1_READY_FOR_DATA (1<<8) /* ready for next transfer */
#define MMC_R1_APP_CMD (1<<5) /* app. commands supported */
/* 48-bit response decoding (32 bits w/o CRC) */
#define MMC_R1(resp) ((resp)[0])
#define MMC_R3(resp) ((resp)[0])
#define SD_R6(resp) ((resp)[0])
/* RCA argument and response */
#define MMC_ARG_RCA(rca) ((rca) << 16)
#define SD_R6_RCA(resp) (SD_R6((resp)) >> 16)
/* bus width argument */
#define SD_ARG_BUS_WIDTH_1 0
#define SD_ARG_BUS_WIDTH_4 2
/* MMC R2 response (CSD) */
#define MMC_CSD_CSDVER(resp) MMC_RSP_BITS((resp), 126, 2)
#define MMC_CSD_CSDVER_1_0 1
#define MMC_CSD_CSDVER_2_0 2
#define MMC_CSD_MMCVER(resp) MMC_RSP_BITS((resp), 122, 4)
#define MMC_CSD_MMCVER_1_0 0 /* MMC 1.0 - 1.2 */
#define MMC_CSD_MMCVER_1_4 1 /* MMC 1.4 */
#define MMC_CSD_MMCVER_2_0 2 /* MMC 2.0 - 2.2 */
#define MMC_CSD_MMCVER_3_1 3 /* MMC 3.1 - 3.3 */
#define MMC_CSD_MMCVER_4_0 4 /* MMC 4 */
#define MMC_CSD_READ_BL_LEN(resp) MMC_RSP_BITS((resp), 80, 4)
#define MMC_CSD_C_SIZE(resp) MMC_RSP_BITS((resp), 62, 12)
#define MMC_CSD_CAPACITY(resp) ((MMC_CSD_C_SIZE((resp))+1) << \
(MMC_CSD_C_SIZE_MULT((resp))+2))
#define MMC_CSD_C_SIZE_MULT(resp) MMC_RSP_BITS((resp), 47, 3)
/* MMC v1 R2 response (CID) */
#define MMC_CID_MID_V1(resp) MMC_RSP_BITS((resp), 104, 24)
#define MMC_CID_PNM_V1_CPY(resp, pnm) \
do { \
(pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \
(pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \
(pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \
(pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \
(pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \
(pnm)[5] = MMC_RSP_BITS((resp), 56, 8); \
(pnm)[6] = MMC_RSP_BITS((resp), 48, 8); \
(pnm)[7] = '\0'; \
} while (0)
#define MMC_CID_REV_V1(resp) MMC_RSP_BITS((resp), 40, 8)
#define MMC_CID_PSN_V1(resp) MMC_RSP_BITS((resp), 16, 24)
#define MMC_CID_MDT_V1(resp) MMC_RSP_BITS((resp), 8, 8)
/* MMC v2 R2 response (CID) */
#define MMC_CID_MID_V2(resp) MMC_RSP_BITS((resp), 120, 8)
#define MMC_CID_OID_V2(resp) MMC_RSP_BITS((resp), 104, 16)
#define MMC_CID_PNM_V2_CPY(resp, pnm) \
do { \
(pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \
(pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \
(pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \
(pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \
(pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \
(pnm)[5] = MMC_RSP_BITS((resp), 56, 8); \
(pnm)[6] = '\0'; \
} while (0)
#define MMC_CID_PSN_V2(resp) MMC_RSP_BITS((resp), 16, 32)
/* SD R2 response (CSD) */
#define SD_CSD_CSDVER(resp) MMC_RSP_BITS((resp), 126, 2)
#define SD_CSD_CSDVER_1_0 0
#define SD_CSD_CSDVER_2_0 1
#define SD_CSD_TAAC(resp) MMC_RSP_BITS((resp), 112, 8)
#define SD_CSD_TAAC_1_5_MSEC 0x26
#define SD_CSD_NSAC(resp) MMC_RSP_BITS((resp), 104, 8)
#define SD_CSD_SPEED(resp) MMC_RSP_BITS((resp), 96, 8)
#define SD_CSD_SPEED_25_MHZ 0x32
#define SD_CSD_SPEED_50_MHZ 0x5a
#define SD_CSD_CCC(resp) MMC_RSP_BITS((resp), 84, 12)
#define SD_CSD_CCC_ALL 0x5f5
#define SD_CSD_READ_BL_LEN(resp) MMC_RSP_BITS((resp), 80, 4)
#define SD_CSD_READ_BL_PARTIAL(resp) MMC_RSP_BITS((resp), 79, 1)
#define SD_CSD_WRITE_BLK_MISALIGN(resp) MMC_RSP_BITS((resp), 78, 1)
#define SD_CSD_READ_BLK_MISALIGN(resp) MMC_RSP_BITS((resp), 77, 1)
#define SD_CSD_DSR_IMP(resp) MMC_RSP_BITS((resp), 76, 1)
#define SD_CSD_C_SIZE(resp) MMC_RSP_BITS((resp), 62, 12)
#define SD_CSD_CAPACITY(resp) ((SD_CSD_C_SIZE((resp))+1) << \
(SD_CSD_C_SIZE_MULT((resp))+2))
#define SD_CSD_V2_C_SIZE(resp) MMC_RSP_BITS((resp), 48, 22)
#define SD_CSD_V2_CAPACITY(resp) ((SD_CSD_V2_C_SIZE((resp))+1) << 10)
#define SD_CSD_V2_BL_LEN 0x9 /* 512 */
#define SD_CSD_VDD_R_CURR_MIN(resp) MMC_RSP_BITS((resp), 59, 3)
#define SD_CSD_VDD_R_CURR_MAX(resp) MMC_RSP_BITS((resp), 56, 3)
#define SD_CSD_VDD_W_CURR_MIN(resp) MMC_RSP_BITS((resp), 53, 3)
#define SD_CSD_VDD_W_CURR_MAX(resp) MMC_RSP_BITS((resp), 50, 3)
#define SD_CSD_VDD_RW_CURR_100mA 0x7
#define SD_CSD_VDD_RW_CURR_80mA 0x6
#define SD_CSD_C_SIZE_MULT(resp) MMC_RSP_BITS((resp), 47, 3)
#define SD_CSD_ERASE_BLK_EN(resp) MMC_RSP_BITS((resp), 46, 1)
#define SD_CSD_SECTOR_SIZE(resp) MMC_RSP_BITS((resp), 39, 7) /* +1 */
#define SD_CSD_WP_GRP_SIZE(resp) MMC_RSP_BITS((resp), 32, 7) /* +1 */
#define SD_CSD_WP_GRP_ENABLE(resp) MMC_RSP_BITS((resp), 31, 1)
#define SD_CSD_R2W_FACTOR(resp) MMC_RSP_BITS((resp), 26, 3)
#define SD_CSD_WRITE_BL_LEN(resp) MMC_RSP_BITS((resp), 22, 4)
#define SD_CSD_RW_BL_LEN_2G 0xa
#define SD_CSD_RW_BL_LEN_1G 0x9
#define SD_CSD_WRITE_BL_PARTIAL(resp) MMC_RSP_BITS((resp), 21, 1)
#define SD_CSD_FILE_FORMAT_GRP(resp) MMC_RSP_BITS((resp), 15, 1)
#define SD_CSD_COPY(resp) MMC_RSP_BITS((resp), 14, 1)
#define SD_CSD_PERM_WRITE_PROTECT(resp) MMC_RSP_BITS((resp), 13, 1)
#define SD_CSD_TMP_WRITE_PROTECT(resp) MMC_RSP_BITS((resp), 12, 1)
#define SD_CSD_FILE_FORMAT(resp) MMC_RSP_BITS((resp), 10, 2)
/* SD R2 response (CID) */
#define SD_CID_MID(resp) MMC_RSP_BITS((resp), 120, 8)
#define SD_CID_OID(resp) MMC_RSP_BITS((resp), 104, 16)
#define SD_CID_PNM_CPY(resp, pnm) \
do { \
(pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \
(pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \
(pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \
(pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \
(pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \
(pnm)[5] = '\0'; \
} while (0)
#define SD_CID_REV(resp) MMC_RSP_BITS((resp), 56, 8)
#define SD_CID_PSN(resp) MMC_RSP_BITS((resp), 24, 32)
#define SD_CID_MDT(resp) MMC_RSP_BITS((resp), 8, 12)
/* Might be slow, but it should work on big and little endian systems. */
#define MMC_RSP_BITS(resp, start, len) __bitfield((resp), (start)-8, (len))
static __inline int
__bitfield(u_int32_t *src, int start, int len)
{
u_int8_t *sp;
u_int32_t dst, mask;
int shift, bs, bc;
if (start < 0 || len < 0 || len > 32)
return 0;
dst = 0;
mask = len % 32 ? UINT_MAX >> (32 - (len % 32)) : UINT_MAX;
shift = 0;
while (len > 0) {
sp = (u_int8_t *)src + start / 8;
bs = start % 8;
bc = 8 - bs;
if (bc > len)
bc = len;
dst |= (*sp++ >> bs) << shift;
shift += bc;
start += bc;
len -= bc;
}
dst &= mask;
return (int)dst;
}
#endif

280
sdmmcvar.h Normal file
View File

@ -0,0 +1,280 @@
/* $OpenBSD: sdmmcvar.h,v 1.16 2009/04/07 16:35:52 blambert Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
* Copyright (c) 2009 Sven Peter <svenpeter@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SDMMCVAR_H_
#define _SDMMCVAR_H_
#if 0
#include <sys/queue.h>
#include <sys/lock.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#include <dev/sdmmc/sdmmcchip.h>
#include <dev/sdmmc/sdmmcreg.h>
#endif
struct sdmmc_csd {
int csdver; /* CSD structure format */
int mmcver; /* MMC version (for CID format) */
int capacity; /* total number of sectors */
int sector_size; /* sector size in bytes */
int read_bl_len; /* block length for reads */
/* ... */
};
struct sdmmc_cid {
int mid; /* manufacturer identification number */
int oid; /* OEM/product identification number */
char pnm[8]; /* product name (MMC v1 has the longest) */
int rev; /* product revision */
int psn; /* product serial number */
int mdt; /* manufacturing date */
};
typedef u_int32_t sdmmc_response[4];
struct sdmmc_softc;
struct sdmmc_task {
void (*func)(void *arg);
void *arg;
int onqueue;
struct sdmmc_softc *sc;
#if 0
TAILQ_ENTRY(sdmmc_task) next;
#endif
};
#define sdmmc_init_task(xtask, xfunc, xarg) do { \
(xtask)->func = (xfunc); \
(xtask)->arg = (xarg); \
(xtask)->onqueue = 0; \
(xtask)->sc = NULL; \
} while (0)
#define sdmmc_task_pending(xtask) ((xtask)->onqueue)
struct sdmmc_command {
struct sdmmc_task c_task; /* task queue entry */
u_int16_t c_opcode; /* SD or MMC command index */
u_int32_t c_arg; /* SD/MMC command argument */
sdmmc_response c_resp; /* response buffer */
void *c_data; /* buffer to send or read into */
int c_datalen; /* length of data buffer */
int c_blklen; /* block length */
int c_flags; /* see below */
#define SCF_ITSDONE 0x0001 /* command is complete */
#define SCF_CMD(flags) ((flags) & 0x00f0)
#define SCF_CMD_AC 0x0000
#define SCF_CMD_ADTC 0x0010
#define SCF_CMD_BC 0x0020
#define SCF_CMD_BCR 0x0030
#define SCF_CMD_READ 0x0040 /* read command (data expected) */
#define SCF_RSP_BSY 0x0100
#define SCF_RSP_136 0x0200
#define SCF_RSP_CRC 0x0400
#define SCF_RSP_IDX 0x0800
#define SCF_RSP_PRESENT 0x1000
/* response types */
#define SCF_RSP_R0 0 /* none */
#define SCF_RSP_R1 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
#define SCF_RSP_R1B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY)
#define SCF_RSP_R2 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_136)
#define SCF_RSP_R3 (SCF_RSP_PRESENT)
#define SCF_RSP_R4 (SCF_RSP_PRESENT)
#define SCF_RSP_R5 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
#define SCF_RSP_R5B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY)
#define SCF_RSP_R6 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
#define SCF_RSP_R7 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX)
int c_error; /* errno value on completion */
/* Host controller owned fields for data xfer in progress */
int c_resid; /* remaining I/O */
u_char *c_buf; /* remaining data */
};
/*
* Decoded PC Card 16 based Card Information Structure (CIS),
* per card (function 0) and per function (1 and greater).
*/
struct sdmmc_cis {
u_int16_t manufacturer;
#define SDMMC_VENDOR_INVALID 0xffff
u_int16_t product;
#define SDMMC_PRODUCT_INVALID 0xffff
u_int8_t function;
#define SDMMC_FUNCTION_INVALID 0xff
u_char cis1_major;
u_char cis1_minor;
char cis1_info_buf[256];
char *cis1_info[4];
};
/*
* Structure describing either an SD card I/O function or a SD/MMC
* memory card from a "stack of cards" that responded to CMD2. For a
* combo card with one I/O function and one memory card, there will be
* two of these structures allocated. Each card slot has such a list
* of sdmmc_function structures.
*/
struct sdmmc_function {
/* common members */
struct sdmmc_softc *sc; /* card slot softc */
u_int16_t rca; /* relative card address */
int flags;
#define SFF_ERROR 0x0001 /* function is poo; ignore it */
#define SFF_SDHC 0x0002 /* SD High Capacity card */
#if 0
SIMPLEQ_ENTRY(sdmmc_function) sf_list;
#endif
/* SD card I/O function members */
int number; /* I/O function number or -1 */
struct device *child; /* function driver */
struct sdmmc_cis cis; /* decoded CIS */
/* SD/MMC memory card members */
struct sdmmc_csd csd; /* decoded CSD value */
struct sdmmc_cid cid; /* decoded CID value */
sdmmc_response raw_cid; /* temp. storage for decoding */
};
/*
* Structure describing a single SD/MMC/SDIO card slot.
*/
struct sdmmc_softc {
struct device sc_dev; /* base device */
#define SDMMCDEVNAME(sc) ((sc)->sc_dev.dv_xname)
sdmmc_chipset_tag_t sct; /* host controller chipset tag */
sdmmc_chipset_handle_t sch; /* host controller chipset handle */
int sc_flags;
#define SMF_SD_MODE 0x0001 /* host in SD mode (MMC otherwise) */
#define SMF_IO_MODE 0x0002 /* host in I/O mode (SD mode only) */
#define SMF_MEM_MODE 0x0004 /* host in memory mode (SD or MMC) */
#define SMF_CARD_PRESENT 0x0010 /* card presence noticed */
#define SMF_CARD_ATTACHED 0x0020 /* card driver(s) attached */
#define SMF_STOP_AFTER_MULTIPLE 0x0040 /* send a stop after a multiple cmd */
int sc_function_count; /* number of I/O functions (SDIO) */
struct sdmmc_function *sc_card; /* selected card */
struct sdmmc_function *sc_fn0; /* function 0, the card itself */
#if 0
SIMPLEQ_HEAD(, sdmmc_function) sf_head; /* list of card functions */
#endif
int sc_dying; /* bus driver is shutting down */
struct proc *sc_task_thread; /* asynchronous tasks */
#if 0
TAILQ_HEAD(, sdmmc_task) sc_tskq; /* task thread work queue */
#endif
struct sdmmc_task sc_discover_task; /* card attach/detach task */
struct sdmmc_task sc_intr_task; /* card interrupt task */
#if 0
struct lock sc_lock; /* lock around host controller */
#endif
void *sc_scsibus; /* SCSI bus emulation softc */
#if 0
TAILQ_HEAD(, sdmmc_intr_handler) sc_intrq; /* interrupt handlers */
#endif
long sc_max_xfer; /* maximum transfer size */
};
/*
* Attach devices at the sdmmc bus.
*/
struct sdmmc_attach_args {
struct scsi_link *scsi_link; /* XXX */
struct sdmmc_function *sf;
};
#define IPL_SDMMC IPL_BIO
#define splsdmmc() splbio()
#define SDMMC_LOCK(sc) lockmgr(&(sc)->sc_lock, LK_EXCLUSIVE, NULL)
#define SDMMC_UNLOCK(sc) lockmgr(&(sc)->sc_lock, LK_RELEASE, NULL)
#define SDMMC_ASSERT_LOCKED(sc) \
KASSERT(lockstatus(&((sc))->sc_lock) == LK_EXCLUSIVE)
#if 0
void sdmmc_add_task(struct sdmmc_softc *, struct sdmmc_task *);
void sdmmc_del_task(struct sdmmc_task *);
struct sdmmc_function *sdmmc_function_alloc(struct sdmmc_softc *);
void sdmmc_function_free(struct sdmmc_function *);
int sdmmc_set_bus_power(struct sdmmc_softc *, u_int32_t, u_int32_t);
int sdmmc_mmc_command(struct sdmmc_softc *, struct sdmmc_command *);
int sdmmc_app_command(struct sdmmc_softc *, struct sdmmc_command *);
void sdmmc_go_idle_state(struct sdmmc_softc *);
int sdmmc_select_card(struct sdmmc_softc *, struct sdmmc_function *);
int sdmmc_set_relative_addr(struct sdmmc_softc *,
struct sdmmc_function *);
int sdmmc_send_if_cond(struct sdmmc_softc *, uint32_t);
void sdmmc_intr_enable(struct sdmmc_function *);
void sdmmc_intr_disable(struct sdmmc_function *);
void *sdmmc_intr_establish(struct device *, int (*)(void *),
void *, const char *);
void sdmmc_intr_disestablish(void *);
void sdmmc_intr_task(void *);
int sdmmc_io_enable(struct sdmmc_softc *);
void sdmmc_io_scan(struct sdmmc_softc *);
int sdmmc_io_init(struct sdmmc_softc *, struct sdmmc_function *);
void sdmmc_io_attach(struct sdmmc_softc *);
void sdmmc_io_detach(struct sdmmc_softc *);
u_int8_t sdmmc_io_read_1(struct sdmmc_function *, int);
u_int16_t sdmmc_io_read_2(struct sdmmc_function *, int);
u_int32_t sdmmc_io_read_4(struct sdmmc_function *, int);
int sdmmc_io_read_multi_1(struct sdmmc_function *, int, u_char *, int);
void sdmmc_io_write_1(struct sdmmc_function *, int, u_int8_t);
void sdmmc_io_write_2(struct sdmmc_function *, int, u_int16_t);
void sdmmc_io_write_4(struct sdmmc_function *, int, u_int32_t);
int sdmmc_io_write_multi_1(struct sdmmc_function *, int, u_char *, int);
int sdmmc_io_function_ready(struct sdmmc_function *);
int sdmmc_io_function_enable(struct sdmmc_function *);
void sdmmc_io_function_disable(struct sdmmc_function *);
int sdmmc_read_cis(struct sdmmc_function *, struct sdmmc_cis *);
void sdmmc_print_cis(struct sdmmc_function *);
void sdmmc_check_cis_quirks(struct sdmmc_function *);
int sdmmc_mem_enable(struct sdmmc_softc *);
void sdmmc_mem_scan(struct sdmmc_softc *);
int sdmmc_mem_init(struct sdmmc_softc *, struct sdmmc_function *);
int sdmmc_mem_read_block(struct sdmmc_function *, int, u_char *, size_t);
int sdmmc_mem_write_block(struct sdmmc_function *, int, u_char *, size_t);
/* ioctls */
#include <sys/ioccom.h>
struct bio_sdmmc_command {
void *cookie;
struct sdmmc_command cmd;
};
struct bio_sdmmc_debug {
void *cookie;
int debug;
};
#define SDIOCEXECMMC _IOWR('S',0, struct bio_sdmmc_command)
#define SDIOCEXECAPP _IOWR('S',1, struct bio_sdmmc_command)
#define SDIOCSETDEBUG _IOWR('S',2, struct bio_sdmmc_debug)
#endif
#endif