aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAndy Green <andy@openmoko.com>2008-11-19 17:11:20 +0000
committerAndy Green <andy@openmoko.com>2008-11-19 17:11:20 +0000
commit5a3e16857d5da8a5db2e2c803129ccb43982cfc1 (patch)
tree27f4532d00c465113f2085b103b2aff3eb95cd32 /drivers
parentd30ce47da36cc3610ae5b0cea3f64b6fd389294a (diff)
prepare-ar6001-driver-linux-sdio.patch
Signed-off-by: Andy Green <andy@openmoko.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ar6000/Makefile (renamed from drivers/sdio/function/wlan/ar6000/Makefile)0
-rw-r--r--drivers/ar6000/ar6000/ar6000_drv.c (renamed from drivers/sdio/function/wlan/ar6000/ar6000/ar6000_drv.c)0
-rw-r--r--drivers/ar6000/ar6000/ar6000_drv.h (renamed from drivers/sdio/function/wlan/ar6000/ar6000/ar6000_drv.h)0
-rw-r--r--drivers/ar6000/ar6000/ar6000_raw_if.c (renamed from drivers/sdio/function/wlan/ar6000/ar6000/ar6000_raw_if.c)0
-rw-r--r--drivers/ar6000/ar6000/ar6xapi_linux.h (renamed from drivers/sdio/function/wlan/ar6000/ar6000/ar6xapi_linux.h)0
-rw-r--r--drivers/ar6000/ar6000/athdrv_linux.h (renamed from drivers/sdio/function/wlan/ar6000/ar6000/athdrv_linux.h)0
-rw-r--r--drivers/ar6000/ar6000/athtypes_linux.h (renamed from drivers/sdio/function/wlan/ar6000/ar6000/athtypes_linux.h)0
-rw-r--r--drivers/ar6000/ar6000/config_linux.h (renamed from drivers/sdio/function/wlan/ar6000/ar6000/config_linux.h)0
-rw-r--r--drivers/ar6000/ar6000/debug_linux.h (renamed from drivers/sdio/function/wlan/ar6000/ar6000/debug_linux.h)0
-rw-r--r--drivers/ar6000/ar6000/ioctl.c (renamed from drivers/sdio/function/wlan/ar6000/ar6000/ioctl.c)0
-rw-r--r--drivers/ar6000/ar6000/netbuf.c (renamed from drivers/sdio/function/wlan/ar6000/ar6000/netbuf.c)0
-rw-r--r--drivers/ar6000/ar6000/osapi_linux.h (renamed from drivers/sdio/function/wlan/ar6000/ar6000/osapi_linux.h)0
-rw-r--r--drivers/ar6000/ar6000/wireless_ext.c (renamed from drivers/sdio/function/wlan/ar6000/ar6000/wireless_ext.c)0
-rw-r--r--drivers/ar6000/bmi/bmi.c (renamed from drivers/sdio/function/wlan/ar6000/bmi/bmi.c)0
-rw-r--r--drivers/ar6000/bmi/bmi_internal.h (renamed from drivers/sdio/function/wlan/ar6000/bmi/bmi_internal.h)0
-rw-r--r--drivers/ar6000/hif/hif.c (renamed from drivers/sdio/function/wlan/ar6000/hif/hif.c)0
-rw-r--r--drivers/ar6000/hif/hif_internal.h (renamed from drivers/sdio/function/wlan/ar6000/hif/hif_internal.h)0
-rw-r--r--drivers/ar6000/htc/ar6k.c (renamed from drivers/sdio/function/wlan/ar6000/htc/ar6k.c)0
-rw-r--r--drivers/ar6000/htc/ar6k.h (renamed from drivers/sdio/function/wlan/ar6000/htc/ar6k.h)0
-rw-r--r--drivers/ar6000/htc/ar6k_events.c (renamed from drivers/sdio/function/wlan/ar6000/htc/ar6k_events.c)0
-rw-r--r--drivers/ar6000/htc/htc.c (renamed from drivers/sdio/function/wlan/ar6000/htc/htc.c)0
-rw-r--r--drivers/ar6000/htc/htc_debug.h (renamed from drivers/sdio/function/wlan/ar6000/htc/htc_debug.h)0
-rw-r--r--drivers/ar6000/htc/htc_internal.h (renamed from drivers/sdio/function/wlan/ar6000/htc/htc_internal.h)0
-rw-r--r--drivers/ar6000/htc/htc_recv.c (renamed from drivers/sdio/function/wlan/ar6000/htc/htc_recv.c)0
-rw-r--r--drivers/ar6000/htc/htc_send.c (renamed from drivers/sdio/function/wlan/ar6000/htc/htc_send.c)0
-rw-r--r--drivers/ar6000/htc/htc_services.c (renamed from drivers/sdio/function/wlan/ar6000/htc/htc_services.c)0
-rw-r--r--drivers/ar6000/include/AR6001_regdump.h (renamed from drivers/sdio/function/wlan/ar6000/include/AR6001_regdump.h)0
-rw-r--r--drivers/ar6000/include/AR6K_version.h (renamed from drivers/sdio/function/wlan/ar6000/include/AR6K_version.h)0
-rw-r--r--drivers/ar6000/include/AR6K_version.h.NEW (renamed from drivers/sdio/function/wlan/ar6000/include/AR6K_version.h.NEW)0
-rw-r--r--drivers/ar6000/include/AR6Khwreg.h (renamed from drivers/sdio/function/wlan/ar6000/include/AR6Khwreg.h)0
-rw-r--r--drivers/ar6000/include/a_config.h (renamed from drivers/sdio/function/wlan/ar6000/include/a_config.h)0
-rw-r--r--drivers/ar6000/include/a_debug.h (renamed from drivers/sdio/function/wlan/ar6000/include/a_debug.h)0
-rw-r--r--drivers/ar6000/include/a_drv.h (renamed from drivers/sdio/function/wlan/ar6000/include/a_drv.h)0
-rw-r--r--drivers/ar6000/include/a_drv_api.h (renamed from drivers/sdio/function/wlan/ar6000/include/a_drv_api.h)0
-rw-r--r--drivers/ar6000/include/a_osapi.h (renamed from drivers/sdio/function/wlan/ar6000/include/a_osapi.h)0
-rw-r--r--drivers/ar6000/include/a_types.h (renamed from drivers/sdio/function/wlan/ar6000/include/a_types.h)0
-rw-r--r--drivers/ar6000/include/ar6000_api.h (renamed from drivers/sdio/function/wlan/ar6000/include/ar6000_api.h)0
-rw-r--r--drivers/ar6000/include/ar6000_diag.h (renamed from drivers/sdio/function/wlan/ar6000/include/ar6000_diag.h)0
-rw-r--r--drivers/ar6000/include/athdefs.h (renamed from drivers/sdio/function/wlan/ar6000/include/athdefs.h)0
-rw-r--r--drivers/ar6000/include/athdrv.h (renamed from drivers/sdio/function/wlan/ar6000/include/athdrv.h)0
-rw-r--r--drivers/ar6000/include/athendpack.h (renamed from drivers/sdio/function/wlan/ar6000/include/athendpack.h)0
-rw-r--r--drivers/ar6000/include/athstartpack.h (renamed from drivers/sdio/function/wlan/ar6000/include/athstartpack.h)0
-rw-r--r--drivers/ar6000/include/bmi.h (renamed from drivers/sdio/function/wlan/ar6000/include/bmi.h)0
-rw-r--r--drivers/ar6000/include/bmi_msg.h (renamed from drivers/sdio/function/wlan/ar6000/include/bmi_msg.h)0
-rw-r--r--drivers/ar6000/include/common_drv.h (renamed from drivers/sdio/function/wlan/ar6000/include/common_drv.h)0
-rw-r--r--drivers/ar6000/include/dbglog.h (renamed from drivers/sdio/function/wlan/ar6000/include/dbglog.h)0
-rw-r--r--drivers/ar6000/include/dbglog_api.h (renamed from drivers/sdio/function/wlan/ar6000/include/dbglog_api.h)0
-rw-r--r--drivers/ar6000/include/dbglog_id.h (renamed from drivers/sdio/function/wlan/ar6000/include/dbglog_id.h)0
-rw-r--r--drivers/ar6000/include/dl_list.h (renamed from drivers/sdio/function/wlan/ar6000/include/dl_list.h)0
-rw-r--r--drivers/ar6000/include/dset_api.h (renamed from drivers/sdio/function/wlan/ar6000/include/dset_api.h)0
-rw-r--r--drivers/ar6000/include/dset_internal.h (renamed from drivers/sdio/function/wlan/ar6000/include/dset_internal.h)0
-rw-r--r--drivers/ar6000/include/dsetid.h (renamed from drivers/sdio/function/wlan/ar6000/include/dsetid.h)0
-rw-r--r--drivers/ar6000/include/gpio.h (renamed from drivers/sdio/function/wlan/ar6000/include/gpio.h)0
-rw-r--r--drivers/ar6000/include/gpio_api.h (renamed from drivers/sdio/function/wlan/ar6000/include/gpio_api.h)0
-rw-r--r--drivers/ar6000/include/hif.h (renamed from drivers/sdio/function/wlan/ar6000/include/hif.h)0
-rw-r--r--drivers/ar6000/include/host_version.h (renamed from drivers/sdio/function/wlan/ar6000/include/host_version.h)0
-rw-r--r--drivers/ar6000/include/htc.h (renamed from drivers/sdio/function/wlan/ar6000/include/htc.h)0
-rw-r--r--drivers/ar6000/include/htc_api.h (renamed from drivers/sdio/function/wlan/ar6000/include/htc_api.h)0
-rw-r--r--drivers/ar6000/include/htc_packet.h (renamed from drivers/sdio/function/wlan/ar6000/include/htc_packet.h)0
-rw-r--r--drivers/ar6000/include/htc_services.h (renamed from drivers/sdio/function/wlan/ar6000/include/htc_services.h)0
-rw-r--r--drivers/ar6000/include/ieee80211.h (renamed from drivers/sdio/function/wlan/ar6000/include/ieee80211.h)0
-rw-r--r--drivers/ar6000/include/ieee80211_ioctl.h (renamed from drivers/sdio/function/wlan/ar6000/include/ieee80211_ioctl.h)0
-rw-r--r--drivers/ar6000/include/ieee80211_node.h (renamed from drivers/sdio/function/wlan/ar6000/include/ieee80211_node.h)0
-rw-r--r--drivers/ar6000/include/ini_dset.h (renamed from drivers/sdio/function/wlan/ar6000/include/ini_dset.h)0
-rw-r--r--drivers/ar6000/include/regDb.h (renamed from drivers/sdio/function/wlan/ar6000/include/regDb.h)0
-rw-r--r--drivers/ar6000/include/regdump.h (renamed from drivers/sdio/function/wlan/ar6000/include/regdump.h)0
-rw-r--r--drivers/ar6000/include/targaddrs.h (renamed from drivers/sdio/function/wlan/ar6000/include/targaddrs.h)0
-rw-r--r--drivers/ar6000/include/testcmd.h (renamed from drivers/sdio/function/wlan/ar6000/include/testcmd.h)0
-rw-r--r--drivers/ar6000/include/wlan_api.h (renamed from drivers/sdio/function/wlan/ar6000/include/wlan_api.h)0
-rw-r--r--drivers/ar6000/include/wlan_dset.h (renamed from drivers/sdio/function/wlan/ar6000/include/wlan_dset.h)0
-rw-r--r--drivers/ar6000/include/wmi.h (renamed from drivers/sdio/function/wlan/ar6000/include/wmi.h)0
-rw-r--r--drivers/ar6000/include/wmi_api.h (renamed from drivers/sdio/function/wlan/ar6000/include/wmi_api.h)0
-rw-r--r--drivers/ar6000/include/wmix.h (renamed from drivers/sdio/function/wlan/ar6000/include/wmix.h)0
-rw-r--r--drivers/ar6000/miscdrv/common_drv.c (renamed from drivers/sdio/function/wlan/ar6000/miscdrv/common_drv.c)0
-rw-r--r--drivers/ar6000/miscdrv/credit_dist.c (renamed from drivers/sdio/function/wlan/ar6000/miscdrv/credit_dist.c)0
-rw-r--r--drivers/ar6000/wlan/wlan_node.c (renamed from drivers/sdio/function/wlan/ar6000/wlan/wlan_node.c)0
-rw-r--r--drivers/ar6000/wlan/wlan_recv_beacon.c (renamed from drivers/sdio/function/wlan/ar6000/wlan/wlan_recv_beacon.c)0
-rw-r--r--drivers/ar6000/wlan/wlan_utils.c (renamed from drivers/sdio/function/wlan/ar6000/wlan/wlan_utils.c)0
-rw-r--r--drivers/ar6000/wmi/wmi.c (renamed from drivers/sdio/function/wlan/ar6000/wmi/wmi.c)0
-rw-r--r--drivers/ar6000/wmi/wmi_doc.h (renamed from drivers/sdio/function/wlan/ar6000/wmi/wmi_doc.h)0
-rw-r--r--drivers/ar6000/wmi/wmi_host.h (renamed from drivers/sdio/function/wlan/ar6000/wmi/wmi_host.h)0
-rw-r--r--drivers/sdio/Kconfig17
-rw-r--r--drivers/sdio/Makefile4
-rw-r--r--drivers/sdio/function/Kconfig11
-rw-r--r--drivers/sdio/function/Makefile1
-rw-r--r--drivers/sdio/function/wlan/Makefile4
-rw-r--r--drivers/sdio/hcd/Kconfig14
-rw-r--r--drivers/sdio/hcd/Makefile1
-rw-r--r--drivers/sdio/hcd/s3c24xx/Makefile2
-rw-r--r--drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c1568
-rw-r--r--drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h81
-rw-r--r--drivers/sdio/stack/Makefile1
-rw-r--r--drivers/sdio/stack/busdriver/Makefile2
-rw-r--r--drivers/sdio/stack/busdriver/_busdriver.h466
-rw-r--r--drivers/sdio/stack/busdriver/sdio_bus.c2120
-rw-r--r--drivers/sdio/stack/busdriver/sdio_bus_events.c1040
-rw-r--r--drivers/sdio/stack/busdriver/sdio_bus_misc.c3122
-rw-r--r--drivers/sdio/stack/busdriver/sdio_bus_os.c828
-rw-r--r--drivers/sdio/stack/busdriver/sdio_function.c715
-rw-r--r--drivers/sdio/stack/lib/Makefile2
-rw-r--r--drivers/sdio/stack/lib/_sdio_lib.h50
-rw-r--r--drivers/sdio/stack/lib/sdio_lib_c.c908
-rw-r--r--drivers/sdio/stack/lib/sdio_lib_os.c251
-rw-r--r--drivers/sdio/stack/platform/Makefile2
-rw-r--r--drivers/sdio/stack/platform/sdioplatformdriver.c300
105 files changed, 0 insertions, 11510 deletions
diff --git a/drivers/sdio/function/wlan/ar6000/Makefile b/drivers/ar6000/Makefile
index 4dc5109e3bd..4dc5109e3bd 100644
--- a/drivers/sdio/function/wlan/ar6000/Makefile
+++ b/drivers/ar6000/Makefile
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/ar6000_drv.c b/drivers/ar6000/ar6000/ar6000_drv.c
index 5dd16517f1e..5dd16517f1e 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/ar6000_drv.c
+++ b/drivers/ar6000/ar6000/ar6000_drv.c
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/ar6000_drv.h b/drivers/ar6000/ar6000/ar6000_drv.h
index 9e8ce0216a4..9e8ce0216a4 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/ar6000_drv.h
+++ b/drivers/ar6000/ar6000/ar6000_drv.h
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/ar6000_raw_if.c b/drivers/ar6000/ar6000/ar6000_raw_if.c
index 746cb2b023e..746cb2b023e 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/ar6000_raw_if.c
+++ b/drivers/ar6000/ar6000/ar6000_raw_if.c
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/ar6xapi_linux.h b/drivers/ar6000/ar6000/ar6xapi_linux.h
index b8e6e096165..b8e6e096165 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/ar6xapi_linux.h
+++ b/drivers/ar6000/ar6000/ar6xapi_linux.h
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/athdrv_linux.h b/drivers/ar6000/ar6000/athdrv_linux.h
index 9c3e449735f..9c3e449735f 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/athdrv_linux.h
+++ b/drivers/ar6000/ar6000/athdrv_linux.h
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/athtypes_linux.h b/drivers/ar6000/ar6000/athtypes_linux.h
index 3e91de331f4..3e91de331f4 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/athtypes_linux.h
+++ b/drivers/ar6000/ar6000/athtypes_linux.h
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/config_linux.h b/drivers/ar6000/ar6000/config_linux.h
index 11a691d0c16..11a691d0c16 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/config_linux.h
+++ b/drivers/ar6000/ar6000/config_linux.h
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/debug_linux.h b/drivers/ar6000/ar6000/debug_linux.h
index c74e1df9f45..c74e1df9f45 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/debug_linux.h
+++ b/drivers/ar6000/ar6000/debug_linux.h
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/ioctl.c b/drivers/ar6000/ar6000/ioctl.c
index eb712b4ffc9..eb712b4ffc9 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/ioctl.c
+++ b/drivers/ar6000/ar6000/ioctl.c
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/netbuf.c b/drivers/ar6000/ar6000/netbuf.c
index 97b273b3ac1..97b273b3ac1 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/netbuf.c
+++ b/drivers/ar6000/ar6000/netbuf.c
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/osapi_linux.h b/drivers/ar6000/ar6000/osapi_linux.h
index 5b64212a27c..5b64212a27c 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/osapi_linux.h
+++ b/drivers/ar6000/ar6000/osapi_linux.h
diff --git a/drivers/sdio/function/wlan/ar6000/ar6000/wireless_ext.c b/drivers/ar6000/ar6000/wireless_ext.c
index ab4d21b1f8c..ab4d21b1f8c 100644
--- a/drivers/sdio/function/wlan/ar6000/ar6000/wireless_ext.c
+++ b/drivers/ar6000/ar6000/wireless_ext.c
diff --git a/drivers/sdio/function/wlan/ar6000/bmi/bmi.c b/drivers/ar6000/bmi/bmi.c
index d7b610c153e..d7b610c153e 100644
--- a/drivers/sdio/function/wlan/ar6000/bmi/bmi.c
+++ b/drivers/ar6000/bmi/bmi.c
diff --git a/drivers/sdio/function/wlan/ar6000/bmi/bmi_internal.h b/drivers/ar6000/bmi/bmi_internal.h
index 1e213540c76..1e213540c76 100644
--- a/drivers/sdio/function/wlan/ar6000/bmi/bmi_internal.h
+++ b/drivers/ar6000/bmi/bmi_internal.h
diff --git a/drivers/sdio/function/wlan/ar6000/hif/hif.c b/drivers/ar6000/hif/hif.c
index d04486c35b0..d04486c35b0 100644
--- a/drivers/sdio/function/wlan/ar6000/hif/hif.c
+++ b/drivers/ar6000/hif/hif.c
diff --git a/drivers/sdio/function/wlan/ar6000/hif/hif_internal.h b/drivers/ar6000/hif/hif_internal.h
index d8fc1013234..d8fc1013234 100644
--- a/drivers/sdio/function/wlan/ar6000/hif/hif_internal.h
+++ b/drivers/ar6000/hif/hif_internal.h
diff --git a/drivers/sdio/function/wlan/ar6000/htc/ar6k.c b/drivers/ar6000/htc/ar6k.c
index 0fd671ab064..0fd671ab064 100644
--- a/drivers/sdio/function/wlan/ar6000/htc/ar6k.c
+++ b/drivers/ar6000/htc/ar6k.c
diff --git a/drivers/sdio/function/wlan/ar6000/htc/ar6k.h b/drivers/ar6000/htc/ar6k.h
index 301ab34a37e..301ab34a37e 100644
--- a/drivers/sdio/function/wlan/ar6000/htc/ar6k.h
+++ b/drivers/ar6000/htc/ar6k.h
diff --git a/drivers/sdio/function/wlan/ar6000/htc/ar6k_events.c b/drivers/ar6000/htc/ar6k_events.c
index fbbcd51896e..fbbcd51896e 100644
--- a/drivers/sdio/function/wlan/ar6000/htc/ar6k_events.c
+++ b/drivers/ar6000/htc/ar6k_events.c
diff --git a/drivers/sdio/function/wlan/ar6000/htc/htc.c b/drivers/ar6000/htc/htc.c
index b5e691b962e..b5e691b962e 100644
--- a/drivers/sdio/function/wlan/ar6000/htc/htc.c
+++ b/drivers/ar6000/htc/htc.c
diff --git a/drivers/sdio/function/wlan/ar6000/htc/htc_debug.h b/drivers/ar6000/htc/htc_debug.h
index 08080be51a2..08080be51a2 100644
--- a/drivers/sdio/function/wlan/ar6000/htc/htc_debug.h
+++ b/drivers/ar6000/htc/htc_debug.h
diff --git a/drivers/sdio/function/wlan/ar6000/htc/htc_internal.h b/drivers/ar6000/htc/htc_internal.h
index ebb8ac16ed1..ebb8ac16ed1 100644
--- a/drivers/sdio/function/wlan/ar6000/htc/htc_internal.h
+++ b/drivers/ar6000/htc/htc_internal.h
diff --git a/drivers/sdio/function/wlan/ar6000/htc/htc_recv.c b/drivers/ar6000/htc/htc_recv.c
index 4be2b0833c8..4be2b0833c8 100644
--- a/drivers/sdio/function/wlan/ar6000/htc/htc_recv.c
+++ b/drivers/ar6000/htc/htc_recv.c
diff --git a/drivers/sdio/function/wlan/ar6000/htc/htc_send.c b/drivers/ar6000/htc/htc_send.c
index fd5ef6e2605..fd5ef6e2605 100644
--- a/drivers/sdio/function/wlan/ar6000/htc/htc_send.c
+++ b/drivers/ar6000/htc/htc_send.c
diff --git a/drivers/sdio/function/wlan/ar6000/htc/htc_services.c b/drivers/ar6000/htc/htc_services.c
index e5d50d16ddc..e5d50d16ddc 100644
--- a/drivers/sdio/function/wlan/ar6000/htc/htc_services.c
+++ b/drivers/ar6000/htc/htc_services.c
diff --git a/drivers/sdio/function/wlan/ar6000/include/AR6001_regdump.h b/drivers/ar6000/include/AR6001_regdump.h
index c1bcadea372..c1bcadea372 100644
--- a/drivers/sdio/function/wlan/ar6000/include/AR6001_regdump.h
+++ b/drivers/ar6000/include/AR6001_regdump.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/AR6K_version.h b/drivers/ar6000/include/AR6K_version.h
index d5b2a20b043..d5b2a20b043 100644
--- a/drivers/sdio/function/wlan/ar6000/include/AR6K_version.h
+++ b/drivers/ar6000/include/AR6K_version.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/AR6K_version.h.NEW b/drivers/ar6000/include/AR6K_version.h.NEW
index d5b2a20b043..d5b2a20b043 100644
--- a/drivers/sdio/function/wlan/ar6000/include/AR6K_version.h.NEW
+++ b/drivers/ar6000/include/AR6K_version.h.NEW
diff --git a/drivers/sdio/function/wlan/ar6000/include/AR6Khwreg.h b/drivers/ar6000/include/AR6Khwreg.h
index ecfdf20a0f0..ecfdf20a0f0 100644
--- a/drivers/sdio/function/wlan/ar6000/include/AR6Khwreg.h
+++ b/drivers/ar6000/include/AR6Khwreg.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/a_config.h b/drivers/ar6000/include/a_config.h
index 627b2984d30..627b2984d30 100644
--- a/drivers/sdio/function/wlan/ar6000/include/a_config.h
+++ b/drivers/ar6000/include/a_config.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/a_debug.h b/drivers/ar6000/include/a_debug.h
index 4b0b35155b0..4b0b35155b0 100644
--- a/drivers/sdio/function/wlan/ar6000/include/a_debug.h
+++ b/drivers/ar6000/include/a_debug.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/a_drv.h b/drivers/ar6000/include/a_drv.h
index 07e52d1792e..07e52d1792e 100644
--- a/drivers/sdio/function/wlan/ar6000/include/a_drv.h
+++ b/drivers/ar6000/include/a_drv.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/a_drv_api.h b/drivers/ar6000/include/a_drv_api.h
index 75317260cfb..75317260cfb 100644
--- a/drivers/sdio/function/wlan/ar6000/include/a_drv_api.h
+++ b/drivers/ar6000/include/a_drv_api.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/a_osapi.h b/drivers/ar6000/include/a_osapi.h
index 7d6086712f7..7d6086712f7 100644
--- a/drivers/sdio/function/wlan/ar6000/include/a_osapi.h
+++ b/drivers/ar6000/include/a_osapi.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/a_types.h b/drivers/ar6000/include/a_types.h
index e2ed090767b..e2ed090767b 100644
--- a/drivers/sdio/function/wlan/ar6000/include/a_types.h
+++ b/drivers/ar6000/include/a_types.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/ar6000_api.h b/drivers/ar6000/include/ar6000_api.h
index abe5de79a52..abe5de79a52 100644
--- a/drivers/sdio/function/wlan/ar6000/include/ar6000_api.h
+++ b/drivers/ar6000/include/ar6000_api.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/ar6000_diag.h b/drivers/ar6000/include/ar6000_diag.h
index 2df131df205..2df131df205 100644
--- a/drivers/sdio/function/wlan/ar6000/include/ar6000_diag.h
+++ b/drivers/ar6000/include/ar6000_diag.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/athdefs.h b/drivers/ar6000/include/athdefs.h
index c28c871c599..c28c871c599 100644
--- a/drivers/sdio/function/wlan/ar6000/include/athdefs.h
+++ b/drivers/ar6000/include/athdefs.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/athdrv.h b/drivers/ar6000/include/athdrv.h
index 19da97e4bbd..19da97e4bbd 100644
--- a/drivers/sdio/function/wlan/ar6000/include/athdrv.h
+++ b/drivers/ar6000/include/athdrv.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/athendpack.h b/drivers/ar6000/include/athendpack.h
index 42921ae7f73..42921ae7f73 100644
--- a/drivers/sdio/function/wlan/ar6000/include/athendpack.h
+++ b/drivers/ar6000/include/athendpack.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/athstartpack.h b/drivers/ar6000/include/athstartpack.h
index 6632cc2cb50..6632cc2cb50 100644
--- a/drivers/sdio/function/wlan/ar6000/include/athstartpack.h
+++ b/drivers/ar6000/include/athstartpack.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/bmi.h b/drivers/ar6000/include/bmi.h
index 2eb7134c7b8..2eb7134c7b8 100644
--- a/drivers/sdio/function/wlan/ar6000/include/bmi.h
+++ b/drivers/ar6000/include/bmi.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/bmi_msg.h b/drivers/ar6000/include/bmi_msg.h
index 7c91ef47389..7c91ef47389 100644
--- a/drivers/sdio/function/wlan/ar6000/include/bmi_msg.h
+++ b/drivers/ar6000/include/bmi_msg.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/common_drv.h b/drivers/ar6000/include/common_drv.h
index 1bdc3dae5ca..1bdc3dae5ca 100644
--- a/drivers/sdio/function/wlan/ar6000/include/common_drv.h
+++ b/drivers/ar6000/include/common_drv.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/dbglog.h b/drivers/ar6000/include/dbglog.h
index 3d1e528f757..3d1e528f757 100644
--- a/drivers/sdio/function/wlan/ar6000/include/dbglog.h
+++ b/drivers/ar6000/include/dbglog.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/dbglog_api.h b/drivers/ar6000/include/dbglog_api.h
index 06c8102e12b..06c8102e12b 100644
--- a/drivers/sdio/function/wlan/ar6000/include/dbglog_api.h
+++ b/drivers/ar6000/include/dbglog_api.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/dbglog_id.h b/drivers/ar6000/include/dbglog_id.h
index ce22b168242..ce22b168242 100644
--- a/drivers/sdio/function/wlan/ar6000/include/dbglog_id.h
+++ b/drivers/ar6000/include/dbglog_id.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/dl_list.h b/drivers/ar6000/include/dl_list.h
index 4b9c5819854..4b9c5819854 100644
--- a/drivers/sdio/function/wlan/ar6000/include/dl_list.h
+++ b/drivers/ar6000/include/dl_list.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/dset_api.h b/drivers/ar6000/include/dset_api.h
index de5cc6a66e0..de5cc6a66e0 100644
--- a/drivers/sdio/function/wlan/ar6000/include/dset_api.h
+++ b/drivers/ar6000/include/dset_api.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/dset_internal.h b/drivers/ar6000/include/dset_internal.h
index f0be380e692..f0be380e692 100644
--- a/drivers/sdio/function/wlan/ar6000/include/dset_internal.h
+++ b/drivers/ar6000/include/dset_internal.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/dsetid.h b/drivers/ar6000/include/dsetid.h
index 85729f8b3d0..85729f8b3d0 100644
--- a/drivers/sdio/function/wlan/ar6000/include/dsetid.h
+++ b/drivers/ar6000/include/dsetid.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/gpio.h b/drivers/ar6000/include/gpio.h
index 2203c7e012a..2203c7e012a 100644
--- a/drivers/sdio/function/wlan/ar6000/include/gpio.h
+++ b/drivers/ar6000/include/gpio.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/gpio_api.h b/drivers/ar6000/include/gpio_api.h
index 8078aa57ff8..8078aa57ff8 100644
--- a/drivers/sdio/function/wlan/ar6000/include/gpio_api.h
+++ b/drivers/ar6000/include/gpio_api.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/hif.h b/drivers/ar6000/include/hif.h
index 846a69f3633..846a69f3633 100644
--- a/drivers/sdio/function/wlan/ar6000/include/hif.h
+++ b/drivers/ar6000/include/hif.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/host_version.h b/drivers/ar6000/include/host_version.h
index c090115bcca..c090115bcca 100644
--- a/drivers/sdio/function/wlan/ar6000/include/host_version.h
+++ b/drivers/ar6000/include/host_version.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/htc.h b/drivers/ar6000/include/htc.h
index 152d867b71b..152d867b71b 100644
--- a/drivers/sdio/function/wlan/ar6000/include/htc.h
+++ b/drivers/ar6000/include/htc.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/htc_api.h b/drivers/ar6000/include/htc_api.h
index 73b7df60ed0..73b7df60ed0 100644
--- a/drivers/sdio/function/wlan/ar6000/include/htc_api.h
+++ b/drivers/ar6000/include/htc_api.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/htc_packet.h b/drivers/ar6000/include/htc_packet.h
index 9ce871817e5..9ce871817e5 100644
--- a/drivers/sdio/function/wlan/ar6000/include/htc_packet.h
+++ b/drivers/ar6000/include/htc_packet.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/htc_services.h b/drivers/ar6000/include/htc_services.h
index fc6fc296625..fc6fc296625 100644
--- a/drivers/sdio/function/wlan/ar6000/include/htc_services.h
+++ b/drivers/ar6000/include/htc_services.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/ieee80211.h b/drivers/ar6000/include/ieee80211.h
index 7090040249e..7090040249e 100644
--- a/drivers/sdio/function/wlan/ar6000/include/ieee80211.h
+++ b/drivers/ar6000/include/ieee80211.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/ieee80211_ioctl.h b/drivers/ar6000/include/ieee80211_ioctl.h
index dab6747c496..dab6747c496 100644
--- a/drivers/sdio/function/wlan/ar6000/include/ieee80211_ioctl.h
+++ b/drivers/ar6000/include/ieee80211_ioctl.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/ieee80211_node.h b/drivers/ar6000/include/ieee80211_node.h
index 46b613c09c6..46b613c09c6 100644
--- a/drivers/sdio/function/wlan/ar6000/include/ieee80211_node.h
+++ b/drivers/ar6000/include/ieee80211_node.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/ini_dset.h b/drivers/ar6000/include/ini_dset.h
index 410f2b52597..410f2b52597 100644
--- a/drivers/sdio/function/wlan/ar6000/include/ini_dset.h
+++ b/drivers/ar6000/include/ini_dset.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/regDb.h b/drivers/ar6000/include/regDb.h
index b3f665ff5f2..b3f665ff5f2 100644
--- a/drivers/sdio/function/wlan/ar6000/include/regDb.h
+++ b/drivers/ar6000/include/regDb.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/regdump.h b/drivers/ar6000/include/regdump.h
index 0106825ce27..0106825ce27 100644
--- a/drivers/sdio/function/wlan/ar6000/include/regdump.h
+++ b/drivers/ar6000/include/regdump.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/targaddrs.h b/drivers/ar6000/include/targaddrs.h
index da2a6509020..da2a6509020 100644
--- a/drivers/sdio/function/wlan/ar6000/include/targaddrs.h
+++ b/drivers/ar6000/include/targaddrs.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/testcmd.h b/drivers/ar6000/include/testcmd.h
index 737533adb4d..737533adb4d 100644
--- a/drivers/sdio/function/wlan/ar6000/include/testcmd.h
+++ b/drivers/ar6000/include/testcmd.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/wlan_api.h b/drivers/ar6000/include/wlan_api.h
index aabca4b7b6e..aabca4b7b6e 100644
--- a/drivers/sdio/function/wlan/ar6000/include/wlan_api.h
+++ b/drivers/ar6000/include/wlan_api.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/wlan_dset.h b/drivers/ar6000/include/wlan_dset.h
index 8a876d6476c..8a876d6476c 100644
--- a/drivers/sdio/function/wlan/ar6000/include/wlan_dset.h
+++ b/drivers/ar6000/include/wlan_dset.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/wmi.h b/drivers/ar6000/include/wmi.h
index 045acd4d398..045acd4d398 100644
--- a/drivers/sdio/function/wlan/ar6000/include/wmi.h
+++ b/drivers/ar6000/include/wmi.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/wmi_api.h b/drivers/ar6000/include/wmi_api.h
index 267edfd0a9a..267edfd0a9a 100644
--- a/drivers/sdio/function/wlan/ar6000/include/wmi_api.h
+++ b/drivers/ar6000/include/wmi_api.h
diff --git a/drivers/sdio/function/wlan/ar6000/include/wmix.h b/drivers/ar6000/include/wmix.h
index 8f12b5e5586..8f12b5e5586 100644
--- a/drivers/sdio/function/wlan/ar6000/include/wmix.h
+++ b/drivers/ar6000/include/wmix.h
diff --git a/drivers/sdio/function/wlan/ar6000/miscdrv/common_drv.c b/drivers/ar6000/miscdrv/common_drv.c
index 2b0dfd32931..2b0dfd32931 100644
--- a/drivers/sdio/function/wlan/ar6000/miscdrv/common_drv.c
+++ b/drivers/ar6000/miscdrv/common_drv.c
diff --git a/drivers/sdio/function/wlan/ar6000/miscdrv/credit_dist.c b/drivers/ar6000/miscdrv/credit_dist.c
index 8d37d627203..8d37d627203 100644
--- a/drivers/sdio/function/wlan/ar6000/miscdrv/credit_dist.c
+++ b/drivers/ar6000/miscdrv/credit_dist.c
diff --git a/drivers/sdio/function/wlan/ar6000/wlan/wlan_node.c b/drivers/ar6000/wlan/wlan_node.c
index b12484597f8..b12484597f8 100644
--- a/drivers/sdio/function/wlan/ar6000/wlan/wlan_node.c
+++ b/drivers/ar6000/wlan/wlan_node.c
diff --git a/drivers/sdio/function/wlan/ar6000/wlan/wlan_recv_beacon.c b/drivers/ar6000/wlan/wlan_recv_beacon.c
index 15beabb6549..15beabb6549 100644
--- a/drivers/sdio/function/wlan/ar6000/wlan/wlan_recv_beacon.c
+++ b/drivers/ar6000/wlan/wlan_recv_beacon.c
diff --git a/drivers/sdio/function/wlan/ar6000/wlan/wlan_utils.c b/drivers/ar6000/wlan/wlan_utils.c
index fd5aac90e61..fd5aac90e61 100644
--- a/drivers/sdio/function/wlan/ar6000/wlan/wlan_utils.c
+++ b/drivers/ar6000/wlan/wlan_utils.c
diff --git a/drivers/sdio/function/wlan/ar6000/wmi/wmi.c b/drivers/ar6000/wmi/wmi.c
index d322cf3f522..d322cf3f522 100644
--- a/drivers/sdio/function/wlan/ar6000/wmi/wmi.c
+++ b/drivers/ar6000/wmi/wmi.c
diff --git a/drivers/sdio/function/wlan/ar6000/wmi/wmi_doc.h b/drivers/ar6000/wmi/wmi_doc.h
index 19cd9386cab..19cd9386cab 100644
--- a/drivers/sdio/function/wlan/ar6000/wmi/wmi_doc.h
+++ b/drivers/ar6000/wmi/wmi_doc.h
diff --git a/drivers/sdio/function/wlan/ar6000/wmi/wmi_host.h b/drivers/ar6000/wmi/wmi_host.h
index 57844bcf3df..57844bcf3df 100644
--- a/drivers/sdio/function/wlan/ar6000/wmi/wmi_host.h
+++ b/drivers/ar6000/wmi/wmi_host.h
diff --git a/drivers/sdio/Kconfig b/drivers/sdio/Kconfig
deleted file mode 100644
index 14bf5e36a35..00000000000
--- a/drivers/sdio/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# SDIO driver and host controller support
-#
-
-menu "SDIO support"
-
-config SDIO
- tristate "SDIO support"
- default m
- ---help---
- good luck.
-
-source "drivers/sdio/hcd/Kconfig"
-
-source "drivers/sdio/function/Kconfig"
-
-endmenu
diff --git a/drivers/sdio/Makefile b/drivers/sdio/Makefile
deleted file mode 100644
index f56aa0f7650..00000000000
--- a/drivers/sdio/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-#Makefile for SDIO stack
-obj-$(CONFIG_SDIO) += stack/
-obj-$(CONFIG_SDIO) += hcd/
-obj-$(CONFIG_SDIO) += function/
diff --git a/drivers/sdio/function/Kconfig b/drivers/sdio/function/Kconfig
deleted file mode 100644
index 9b46af31ca3..00000000000
--- a/drivers/sdio/function/Kconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-#menu "SDIO function drivers"
-
-config SDIO_AR6000_WLAN
- tristate "ar6000 wireless networking over sdio"
- depends on SDIO
- select WIRELESS_EXT
- default m
- help
- good luck.
-
-#endmenu \ No newline at end of file
diff --git a/drivers/sdio/function/Makefile b/drivers/sdio/function/Makefile
deleted file mode 100644
index 4940d3746a6..00000000000
--- a/drivers/sdio/function/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_SDIO_AR6000_WLAN) += wlan/ \ No newline at end of file
diff --git a/drivers/sdio/function/wlan/Makefile b/drivers/sdio/function/wlan/Makefile
deleted file mode 100644
index b1e61fcd663..00000000000
--- a/drivers/sdio/function/wlan/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# SDIO wlan ar600 card function driver
-#
-obj-$(CONFIG_SDIO_AR6000_WLAN) += ar6000/ \ No newline at end of file
diff --git a/drivers/sdio/hcd/Kconfig b/drivers/sdio/hcd/Kconfig
deleted file mode 100644
index e4d8397414d..00000000000
--- a/drivers/sdio/hcd/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-config SDIO_S3C24XX
- tristate "Samsung s3c24xx host controller"
- depends on PLAT_S3C24XX && SDIO
- default m
- help
- good luck.
-
-config SDIO_S3C24XX_DMA
- bool "Samsung s3c24xx host controller DMA I/O"
- depends on SDIO_S3C24XX
- default n
- help
- good luck.
-
diff --git a/drivers/sdio/hcd/Makefile b/drivers/sdio/hcd/Makefile
deleted file mode 100644
index e2401e2bd5c..00000000000
--- a/drivers/sdio/hcd/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_PLAT_S3C24XX) += s3c24xx/
diff --git a/drivers/sdio/hcd/s3c24xx/Makefile b/drivers/sdio/hcd/s3c24xx/Makefile
deleted file mode 100644
index d2d099c910a..00000000000
--- a/drivers/sdio/hcd/s3c24xx/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_PLAT_S3C24XX) += sdio_s3c24xx_hcd.o
-sdio_s3c24xx_hcd-objs := s3c24xx_hcd.o
diff --git a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
deleted file mode 100644
index f56b85f1c85..00000000000
--- a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
+++ /dev/null
@@ -1,1568 +0,0 @@
-/*
- * s3c24xx_hcd.c - Samsung S3C MCI driver, Atheros SDIO API compatible.
- *
- * Copyright (C) 2007 by Openmoko, Inc.
- * Written by Samuel Ortiz <sameo@openedhand.com>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/dma-mapping.h>
-#include <linux/errno.h>
-#include <linux/platform_device.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/fs.h>
-#include <linux/ioport.h>
-#include <linux/workqueue.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/seq_file.h>
-#include <linux/debugfs.h>
-
-#include <linux/sdio/ctsystem.h>
-#include <linux/sdio/sdio_busdriver.h>
-#include <linux/sdio/sdio_lib.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/dma.h>
-#include <asm/dma-mapping.h>
-
-#include <mach/regs-sdi.h>
-#include <mach/regs-gpio.h>
-#include <mach/mci.h>
-#include <mach/gta02.h>
-
-#include "s3c24xx_hcd.h"
-
-#define DESCRIPTION "S3c24xx SDIO host controller"
-#define AUTHOR "Samuel Ortiz <sameo@openedhand.com>"
-
-#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
-
-static struct s3c2410_dma_client s3c24xx_hcd_dma_client = {
- .name = "s3c24xx_hcd",
-};
-
-extern struct platform_device s3c_device_sdi;
-
-static void dump_request(struct s3c24xx_hcd_context * context)
-{
- if (context->hcd.pCurrentRequest != NULL) {
- DBG_PRINT(SDDBG_ERROR, ("Current Request Command:%d, ARG:0x%8.8X flags: 0x%04x\n",
- context->hcd.pCurrentRequest->Command, context->hcd.pCurrentRequest->Argument,
- context->hcd.pCurrentRequest->Flags));
- if (IS_SDREQ_DATA_TRANS(context->hcd.pCurrentRequest->Flags)) {
- DBG_PRINT(SDDBG_ERROR, ("Data %s, Blocks: %d, BlockLen:%d Remaining: %d \n",
- IS_SDREQ_WRITE_DATA(context->hcd.pCurrentRequest->Flags) ? "WRITE":"READ",
- context->hcd.pCurrentRequest->BlockCount,
- context->hcd.pCurrentRequest->BlockLen,
- context->hcd.pCurrentRequest->DataRemaining));
- }
- }
-}
-
-static void s3c24xx_dump_regs(struct s3c24xx_hcd_context * context)
-{
- u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer, bsize;
- u32 datcon, datcnt, datsta, fsta, imask;
-
- con = readl(context->base + S3C2410_SDICON);
- pre = readl(context->base + S3C2410_SDIPRE);
- cmdarg = readl(context->base + S3C2410_SDICMDARG);
- cmdcon = readl(context->base + S3C2410_SDICMDCON);
- cmdsta = readl(context->base + S3C2410_SDICMDSTAT);
- r0 = readl(context->base + S3C2410_SDIRSP0);
- r1 = readl(context->base + S3C2410_SDIRSP1);
- r2 = readl(context->base + S3C2410_SDIRSP2);
- r3 = readl(context->base + S3C2410_SDIRSP3);
- timer = readl(context->base + S3C2410_SDITIMER);
- bsize = readl(context->base + S3C2410_SDIBSIZE);
- datcon = readl(context->base + S3C2410_SDIDCON);
- datcnt = readl(context->base + S3C2410_SDIDCNT);
- datsta = readl(context->base + S3C2410_SDIDSTA);
- fsta = readl(context->base + S3C2410_SDIFSTA);
- imask = readl(context->base + S3C2440_SDIIMSK);
-
- printk("SDICON: 0x%08x\n", con);
- printk("SDIPRE: 0x%08x\n", pre);
- printk("SDICmdArg: 0x%08x\n", cmdarg);
- printk("SDICmdCon: 0x%08x\n", cmdcon);
- printk("SDICmdSta: 0x%08x\n", cmdsta);
- printk("SDIRSP0: 0x%08x\n", r0);
- printk("SDIRSP1: 0x%08x\n", r1);
- printk("SDIRSP2: 0x%08x\n", r2);
- printk("SDIRSP3: 0x%08x\n", r3);
- printk("SDIDTimer: 0x%08x\n", timer);
- printk("SDIBSize: 0x%08x\n", bsize);
- printk("SDIDatCon: 0x%08x\n", datcon);
- printk("SDIDatCnt: 0x%08x\n", datcnt);
- printk("SDIDatSta: 0x%08x\n", datsta);
- printk("SDIFSta: 0x%08x\n", fsta);
- printk("SDIIntMsk: 0x%08x\n", imask);
-}
-
-static inline void s3c24xx_hcd_clear_imask(struct s3c24xx_hcd_context * context)
-{
- if (context->int_sdio) {
- writel(S3C2410_SDIIMSK_SDIOIRQ | S3C2410_SDIIMSK_READWAIT,
- context->base + S3C2440_SDIIMSK);
- } else {
- writel(0, context->base + S3C2440_SDIIMSK);
- }
-}
-
-static inline void s3c24xx_hcd_set_imask(struct s3c24xx_hcd_context * context)
-{
- writel(context->int_mask, context->base + S3C2440_SDIIMSK);
-}
-
-
-static inline void s3c24xx_hcd_clear_dsta(struct s3c24xx_hcd_context * context)
-{
- u32 dsta;
-
- dsta = readl(context->base + S3C2410_SDIDSTA);
- writel(dsta, context->base + S3C2410_SDIDSTA);
-}
-
-static inline void s3c24xx_hcd_clear_csta(struct s3c24xx_hcd_context * context)
-{
- u32 csta, csta_clear = 0;
-
- csta = readl(context->base + S3C2410_SDICMDSTAT);
-
- if (csta & S3C2410_SDICMDSTAT_CRCFAIL)
- csta_clear |= S3C2410_SDICMDSTAT_CRCFAIL;
- if (csta & S3C2410_SDICMDSTAT_CMDSENT)
- csta_clear |= S3C2410_SDICMDSTAT_CMDSENT;
- if (csta & S3C2410_SDICMDSTAT_CMDTIMEOUT)
- csta_clear |= S3C2410_SDICMDSTAT_CMDTIMEOUT;
- if (csta & S3C2410_SDICMDSTAT_RSPFIN)
- csta_clear |= S3C2410_SDICMDSTAT_RSPFIN;
-
- writel(csta_clear, context->base + S3C2410_SDICMDSTAT);
-}
-
-static inline void s3c24xx_hcd_clear_sta(struct s3c24xx_hcd_context * context)
-{
- u32 csta, dsta, csta_clear = 0, dsta_clear = 0;
-
- csta = readl(context->base + S3C2410_SDICMDSTAT);
- dsta = readl(context->base + S3C2410_SDIDSTA);
-
- if (csta & S3C2410_SDICMDSTAT_CRCFAIL)
- csta_clear |= S3C2410_SDICMDSTAT_CRCFAIL;
- if (csta & S3C2410_SDICMDSTAT_CMDSENT)
- csta_clear |= S3C2410_SDICMDSTAT_CMDSENT;
- if (csta & S3C2410_SDICMDSTAT_CMDTIMEOUT)
- csta_clear |= S3C2410_SDICMDSTAT_CMDTIMEOUT;
- if (csta & S3C2410_SDICMDSTAT_RSPFIN)
- csta_clear |= S3C2410_SDICMDSTAT_RSPFIN;
-
-
- if (dsta & S3C2410_SDIDSTA_RDYWAITREQ)
- dsta_clear |= S3C2410_SDIDSTA_RDYWAITREQ;
- if (dsta & S3C2410_SDIDSTA_SDIOIRQDETECT)
- dsta_clear |= S3C2410_SDIDSTA_SDIOIRQDETECT;
- if (dsta & S3C2410_SDIDSTA_FIFOFAIL)
- dsta_clear |= S3C2410_SDIDSTA_FIFOFAIL;
- if (dsta & S3C2410_SDIDSTA_CRCFAIL)
- dsta_clear |= S3C2410_SDIDSTA_CRCFAIL;
- if (dsta & S3C2410_SDIDSTA_RXCRCFAIL)
- dsta_clear |= S3C2410_SDIDSTA_RXCRCFAIL;
- if (dsta & S3C2410_SDIDSTA_DATATIMEOUT)
- dsta_clear |= S3C2410_SDIDSTA_DATATIMEOUT;
- if (dsta & S3C2410_SDIDSTA_XFERFINISH)
- dsta_clear |= S3C2410_SDIDSTA_XFERFINISH;
- if (dsta & S3C2410_SDIDSTA_BUSYFINISH)
- dsta_clear |= S3C2410_SDIDSTA_BUSYFINISH;
- if (dsta & S3C2410_SDIDSTA_SBITERR)
- dsta_clear |= S3C2410_SDIDSTA_SBITERR;
-
- writel(csta_clear, context->base + S3C2410_SDICMDSTAT);
- writel(dsta_clear, context->base + S3C2410_SDIDSTA);
-}
-
-static inline void s3c24xx_hcd_fifo_reset(struct s3c24xx_hcd_context * context)
-{
- u32 fsta;
-
- fsta = readl(context->base + S3C2410_SDIFSTA);
- fsta |= S3C2440_SDIFSTA_FIFORESET;
- writel(fsta, context->base + S3C2410_SDIFSTA);
-}
-
-#if 0
-static void s3c24xx_hcd_reset(struct s3c24xx_hcd_context * context)
-{
- u32 con, counter;
- unsigned long flags;
-
- spin_lock_irqsave(&context->lock, flags);
-
- con = readl(context->base + S3C2410_SDICON);
-
- con |= S3C2440_SDICON_SDRESET;
-
- writel(con, context->base + S3C2410_SDICON);
-
- counter = 1000;
- while(counter) {
- con = readl(context->base + S3C2410_SDICON);
- if (!(con & S3C2440_SDICON_SDRESET))
- break;
- counter--;
- mdelay(1);
- }
-
- spin_unlock_irqrestore(&context->lock, flags);
-}
-#endif
-
-static SDIO_STATUS s3c24xx_hcd_clock_enable(struct s3c24xx_hcd_context * context,
- unsigned int clock_rate,
- unsigned char enable)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- unsigned long flags;
- u32 con;
-
- spin_lock_irqsave(&context->lock, flags);
-
- con = readl(context->base + S3C2410_SDICON);
-
- if (enable && clock_rate) {
- con |= S3C2410_SDICON_CLOCKTYPE;
- } else {
- con &= ~S3C2410_SDICON_CLOCKTYPE;
- }
-
- if (clock_rate) {
- int prescaler;
-
- for (prescaler = 0; prescaler < 0xff; prescaler++) {
- context->device.actual_clock_rate =
- context->device.max_clock_rate / (prescaler + 1);
-
- if (context->device.actual_clock_rate <= clock_rate &&
- context->device.actual_clock_rate <= context->hcd.MaxClockRate)
- break;
- }
-
- if (prescaler == 0xff)
- DBG_PRINT(SDDBG_ERROR , ("Using lowest clock rate\n"));
-
- writel(prescaler, context->base + S3C2410_SDIPRE);
- }
-
- writel(con, context->base + S3C2410_SDICON);
-
- spin_unlock_irqrestore(&context->lock, flags);
-
- return SDIOErrorToOSError(status);
-}
-
-static void s3c24xx_hcd_set_bus_mode(struct s3c24xx_hcd_context *context,
- PSDCONFIG_BUS_MODE_DATA pMode)
-{
- u32 datacon;
- unsigned long flags;
-
- DBG_PRINT(SDDBG_TRACE , ("SetBusMode\n"));
-
- spin_lock_irqsave(&context->lock, flags);
- datacon = readl(context->base + S3C2410_SDIDCON);
-
- switch (SDCONFIG_GET_BUSWIDTH(pMode->BusModeFlags)) {
- case SDCONFIG_BUS_WIDTH_1_BIT:
- context->bus_width = 1;
- datacon &= S3C2410_SDIDCON_WIDEBUS;
- break;
- case SDCONFIG_BUS_WIDTH_4_BIT:
- context->bus_width = 4;
- datacon |= S3C2410_SDIDCON_WIDEBUS;
- break;
- default:
- DBG_PRINT(SDDBG_TRACE , ("Unknown bus width: %d\n", SDCONFIG_GET_BUSWIDTH(pMode->BusModeFlags)));
- break;
- }
-
- writel(datacon, context->base + S3C2410_SDIDCON);
- spin_unlock_irqrestore(&context->lock, flags);
-
- /* Set clock rate and enable clock */
- s3c24xx_hcd_clock_enable(context, pMode->ClockRate, 1);
- pMode->ActualClockRate = context->device.actual_clock_rate;
-
- DBG_PRINT(SDDBG_TRACE , ("BUS mode: %d bits wide, actual clock rate: %d kHz (requested %d kHz)\n",
- context->bus_width, pMode->ActualClockRate / 1000, pMode->ClockRate / 1000));
-}
-
-
-static void s3c24xx_hcd_dma_complete(struct s3c24xx_hcd_context * context)
-{
- u32 dsta, counter, i;
- PSDREQUEST req;
- SDIO_STATUS status = SDIO_STATUS_ERROR;
-
- req = GET_CURRENT_REQUEST(&context->hcd);
- if (req == NULL) {
- DBG_PRINT(SDDBG_ERROR, ("%s(): No current request\n", __FUNCTION__));
- return;
- }
-
- if (context->complete == S3C24XX_HCD_DATA_READ) {
- /* DMA READ completion */
- if (context->latest_xfer_size != req->DataRemaining) {
- DBG_PRINT(SDDBG_ERROR, ("Unexpected read xfer size: %d <-> %d\n",
- context->latest_xfer_size, req->DataRemaining));
- status = SDIO_STATUS_BUS_WRITE_ERROR;
- }
-
- counter = 0;
- dsta = readl(context->base + S3C2410_SDIDSTA);
- while (!(dsta & S3C2410_SDIDSTA_XFERFINISH)) {
- if (counter > 500) {
- printk("read xfer timed out\n");
- s3c24xx_dump_regs(context);
- memcpy(req->pDataBuffer, context->io_buffer,
- req->BlockCount * req->BlockLen);
- printk("Transfer: %dx%d\n", req->BlockCount, req->BlockLen);
- for (i = 0; i < req->DataRemaining; i++)
- printk("0x%x ", *(((char *)context->io_buffer) + i));
- printk("\n");
- status = SDIO_STATUS_BUS_READ_TIMEOUT;
- goto out;
- }
- dsta = readl(context->base + S3C2410_SDIDSTA);
- counter++;
- mdelay(1);
- };
-
- dma_sync_single(NULL, context->io_buffer_dma,
- req->BlockCount * req->BlockLen, DMA_BIDIRECTIONAL);
-
- writel(S3C2410_SDIDSTA_XFERFINISH, context->base + S3C2410_SDIDSTA);
-
- memcpy(req->pDataBuffer, context->io_buffer,
- req->BlockCount * req->BlockLen);
-
- req->DataRemaining = 0;
- status = SDIO_STATUS_SUCCESS;
-
- } else if (context->complete == S3C24XX_HCD_DATA_WRITE) {
- /* DMA WRITE completion */
- if (context->latest_xfer_size != req->DataRemaining) {
- DBG_PRINT(SDDBG_ERROR, ("Unexpected write xfer size: %d <-> %d\n",
- context->latest_xfer_size, req->DataRemaining));
- status = SDIO_STATUS_BUS_WRITE_ERROR;
- }
-
- dsta = readl(context->base + S3C2410_SDIDSTA);
- counter = 0;
- while (!(dsta & S3C2410_SDIDSTA_XFERFINISH)) {
- if (counter > 500) {
- printk("write xfer timed out\n");
- status = SDIO_STATUS_BUS_WRITE_ERROR;
- goto out;
- }
- dsta = readl(context->base + S3C2410_SDIDSTA);
- counter++;
- mdelay(1);
- };
-
- writel(S3C2410_SDIDSTA_XFERFINISH, context->base + S3C2410_SDIDSTA);
- req->DataRemaining = 0;
- status = SDIO_STATUS_SUCCESS;
- }
-
- out:
- req->Status = status;
-}
-
-static void s3c24xx_hcd_pio_complete(struct s3c24xx_hcd_context * context)
-{
- u32 fsta, counter;
- u8 *ptr;
- int fifo_count;
- PSDREQUEST req;
- SDIO_STATUS status = SDIO_STATUS_ERROR;
-
- req = GET_CURRENT_REQUEST(&context->hcd);
- if (req == NULL) {
- DBG_PRINT(SDDBG_ERROR, ("%s(): No current request\n", __FUNCTION__));
- return;
- }
-
- ptr = req->pDataBuffer;
-
- if (context->complete == S3C24XX_HCD_DATA_READ) {
- counter = 0;
- DBG_PRINT(SDDBG_TRACE, ("Data read..."));
- do {
- counter++;
- fsta = readl(context->base + S3C2410_SDIFSTA);
- mdelay(1);
- if (counter > 1000) {
- DBG_PRINT(SDDBG_ERROR, ("DATA read timeout\n"));
- status = SDIO_STATUS_BUS_READ_TIMEOUT;
- s3c24xx_dump_regs(context);
- goto out;
- }
- } while(!(fsta & S3C2410_SDIFSTA_RFDET));
- DBG_PRINT(SDDBG_TRACE, ("RX detected\n"));
-
- while (1) {
- counter = 0;
- fifo_count = (readl(context->base + S3C2410_SDIFSTA) & S3C2410_SDIFSTA_COUNTMASK);
- while (!fifo_count) {
- counter++;
- mdelay(1);
- if (counter > 500) {
- s3c24xx_dump_regs(context);
- DBG_PRINT(SDDBG_ERROR, ("No more bytes in FIFO\n"));
- goto out;
- }
- fifo_count = (readl(context->base + S3C2410_SDIFSTA) & S3C2410_SDIFSTA_COUNTMASK);
- }
-
- if (fifo_count > req->DataRemaining) {
- DBG_PRINT(SDDBG_ERROR, ("DATA read, fifo_count %d > expected %d\n", fifo_count, req->DataRemaining));
- fifo_count = req->DataRemaining;
- }
-
- req->DataRemaining -= fifo_count;
- while (fifo_count > 0) {
- if (context->data_size == 4)
- *(ptr) = readl(context->base + S3C2440_SDIDATA);
- else if (context->data_size == 2)
- *(ptr) = readw(context->base + S3C2440_SDIDATA);
- else
- *(ptr) = readb(context->base + S3C2440_SDIDATA);
-
- ptr += context->data_size;
- fifo_count -= context->data_size;
-
- }
-
- if (!req->DataRemaining) {
- /* We poll for xfer finish */
- counter = 0;
- while (!(readl(context->base + S3C2410_SDIDSTA)
- & S3C2410_SDIDSTA_XFERFINISH)) {
- counter++;
- mdelay(1);
- if (counter > 500) {
- DBG_PRINT(SDDBG_ERROR, ("RX XFERFINISH missing\n"));
- s3c24xx_dump_regs(context);
- break;
- }
- }
-
- status = SDIO_STATUS_SUCCESS;
- goto out;
- }
- }
-
- } else if (context->complete == S3C24XX_HCD_DATA_WRITE) {
- counter = 0;
- DBG_PRINT(SDDBG_TRACE, ("Data write..."));
- do {
- counter++;
- fsta = readl(context->base + S3C2410_SDIFSTA);
- mdelay(1);
- if (counter > 1000) {
- DBG_PRINT(SDDBG_ERROR, ("DATA write timeout\n"));
- status = SDIO_STATUS_BUS_WRITE_ERROR;
- goto out;
- break;
- }
-
- } while(!(fsta & S3C2410_SDIFSTA_TFDET));
- DBG_PRINT(SDDBG_TRACE, ("TX detected\n"));
-
- while (1) {
- counter = 0;
- fifo_count = 63 - (readl(context->base + S3C2410_SDIFSTA) & S3C2410_SDIFSTA_COUNTMASK);
- while (!fifo_count) {
- counter++;
- mdelay(1);
- if (counter > 500) {
- s3c24xx_dump_regs(context);
- DBG_PRINT(SDDBG_ERROR, ("No more space in FIFO\n"));
- goto out;
- }
- fifo_count = 63 - (readl(context->base + S3C2410_SDIFSTA) & S3C2410_SDIFSTA_COUNTMASK);
- }
-
- if (fifo_count > req->DataRemaining)
- fifo_count = req->DataRemaining;
-
- req->DataRemaining -= fifo_count;
-
- while (fifo_count > 0) {
- if (context->data_size == 4)
- writel(*(ptr), context->base + S3C2440_SDIDATA);
- else if (context->data_size == 2)
- writew(*(ptr), context->base + S3C2440_SDIDATA);
- else
- writeb(*(ptr), context->base + S3C2440_SDIDATA);
-
- ptr += context->data_size;
- fifo_count -= context->data_size;
- }
-
- if (!req->DataRemaining) {
- /* We poll for xfer finish */
- counter = 0;
- while (!(readl(context->base + S3C2410_SDIDSTA)
- & S3C2410_SDIDSTA_XFERFINISH)) {
- counter++;
- mdelay(1);
- if (counter > 500) {
- DBG_PRINT(SDDBG_ERROR, ("RX XFERFINISH missing\n"));
- s3c24xx_dump_regs(context);
- break;
- }
- }
-
- status = SDIO_STATUS_SUCCESS;
- goto out;
- }
- }
-
- } else {
- DBG_PRINT(SDDBG_ERROR, ("Wrong context: %d\n", context->complete));
- }
-
- out:
- req->Status = status;
-}
-
-static void s3c24xx_hcd_io_work(struct work_struct *work)
-{
- PSDREQUEST req;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- struct s3c24xx_hcd_context * context =
- container_of(work, struct s3c24xx_hcd_context, io_work);
-
- req = GET_CURRENT_REQUEST(&context->hcd);
- if (req == NULL) {
- DBG_PRINT(SDDBG_ERROR, ("%s(): No current request\n", __FUNCTION__));
- return;
- }
-
- if (req->Status == SDIO_STATUS_BUS_RESP_TIMEOUT) {
- DBG_PRINT(SDDBG_ERROR, ("### TIMEOUT ###\n"));
- s3c24xx_dump_regs(context);
- goto out;
- }
-
- if (context->complete == S3C24XX_HCD_NO_RESPONSE &&
- req->Status == SDIO_STATUS_SUCCESS) {
- DBG_PRINT(SDDBG_TRACE, ("CMD done, Status: %d\n", req->Status));
- printk("CMD done, Status: %d\n", req->Status);
- goto out;
- }
-
- if ((context->complete == S3C24XX_HCD_RESPONSE_SHORT ||
- context->complete == S3C24XX_HCD_RESPONSE_LONG ||
- context->complete == S3C24XX_HCD_DATA_READ ||
- context->complete == S3C24XX_HCD_DATA_WRITE) &&
- req->Status == SDIO_STATUS_SUCCESS) {
- u32 resp[4];
-
- /* We need to copy the response data and send it over */
- resp[0] = readl(context->base + S3C2410_SDIRSP0);
- resp[1] = readl(context->base + S3C2410_SDIRSP1);
- resp[2] = readl(context->base + S3C2410_SDIRSP2);
- resp[3] = readl(context->base + S3C2410_SDIRSP3);
-
- if (GET_SDREQ_RESP_TYPE(req->Flags) != SDREQ_FLAGS_RESP_R2) {
- DBG_PRINT(SDDBG_TRACE, ("SHORT response: 0x%08x\n", resp[0]));
- memcpy(&req->Response[1], (u8*)resp, 4);
- req->Response[5] = (readl(context->base + S3C2410_SDICMDSTAT) & 0xff);
- } else {
- printk("LONG response: 0x%08x\n", resp[0]);
- DBG_PRINT(SDDBG_TRACE, ("LONG response: 0x%08x\n", resp[0]));
- memcpy(&req->Response[1], (u8*)resp, 16);
- //req->Response[17] = (readl(context->base + S3C2410_SDICMDSTAT) & 0xff);
- }
-
- /* There is a data stage */
- if (context->complete == S3C24XX_HCD_DATA_READ ||
- context->complete == S3C24XX_HCD_DATA_WRITE) {
- status = SDIO_CheckResponse(&context->hcd, req,
- SDHCD_CHECK_DATA_TRANS_OK);
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR,
- ("Target not ready for data xfer\n"));
- return;
- }
-
- if (context->dma_en) {
- dma_sync_single(NULL, context->io_buffer_dma,
- req->BlockCount * req->BlockLen, DMA_BIDIRECTIONAL);
-
- s3c2410_dma_ctrl(context->dma_channel, S3C2410_DMAOP_START);
-
- wait_for_completion(&context->dma_complete);
-
- s3c24xx_hcd_dma_complete(context);
- } else {
- s3c24xx_hcd_pio_complete(context);
- }
- }
- }
-
- out:
- s3c24xx_hcd_clear_sta(context);
- s3c24xx_hcd_clear_imask(context);
-
- writel(0, context->base + S3C2410_SDICMDARG);
- writel(0, context->base + S3C2410_SDICMDCON);
-
- SDIO_HandleHcdEvent(&context->hcd, EVENT_HCD_TRANSFER_DONE);
-}
-
-static void s3c24xx_hcd_irq_work(struct work_struct *work)
-{
- struct s3c24xx_hcd_context * context =
- container_of(work, struct s3c24xx_hcd_context, irq_work);
-
- disable_irq(context->io_irq);
-
- writel(S3C2410_SDIDSTA_SDIOIRQDETECT, context->base + S3C2410_SDIDSTA);
-
- SDIO_HandleHcdEvent(&context->hcd, EVENT_HCD_SDIO_IRQ_PENDING);
-
- enable_irq(context->io_irq);
-}
-
-void s3c24xx_hcd_dma_done(struct s3c2410_dma_chan *dma_ch, void *buf_id,
- int size, enum s3c2410_dma_buffresult result)
-{
- struct s3c24xx_hcd_context * context =
- (struct s3c24xx_hcd_context *) buf_id;
-
- if (result != S3C2410_RES_OK) {
- DBG_PRINT(SDDBG_ERROR, ("%s(): DMA xfer failed: %d\n", __FUNCTION__, result));
- s3c24xx_dump_regs(context);
- }
-
- context->latest_xfer_size = size;
- complete(&context->dma_complete);
-}
-
-static int s3c24xx_hcd_prepare_dma(struct s3c24xx_hcd_context * context)
-{
- PSDREQUEST req;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- int read = 0, hwcfg = S3C2410_DISRCC_INC | S3C2410_DISRCC_APB;
- enum s3c2410_dmasrc source = S3C2410_DMASRC_MEM;
-
- req = GET_CURRENT_REQUEST(&context->hcd);
- if (req == NULL) {
- DBG_PRINT(SDDBG_ERROR, ("%s(): No current request\n", __FUNCTION__));
- status = SDIO_STATUS_ERROR;
- }
-
- if (!context->dma_en) {
- DBG_PRINT(SDDBG_ERROR, ("%s(): DMA is disabled\n", __FUNCTION__));
- status = SDIO_STATUS_ERROR;
- }
-
- if (!IS_SDREQ_DATA_TRANS(req->Flags)) {
- DBG_PRINT(SDDBG_ERROR, ("%s(): No data to transfer\n", __FUNCTION__));
- status = SDIO_STATUS_ERROR;
- }
-
- if(!IS_SDREQ_WRITE_DATA(req->Flags)) {
- read = 1;
- source = S3C2410_DMASRC_HW;
- hwcfg = S3C2410_DISRCC_APB | 1;
- } else {
- memcpy(context->io_buffer, req->pDataBuffer, req->DataRemaining);
- dma_sync_single(NULL, context->io_buffer_dma,
- req->BlockCount * req->BlockLen, DMA_BIDIRECTIONAL);
-
- }
-
- s3c2410_dma_devconfig(context->dma_channel, source, hwcfg,
- (unsigned long)context->mem->start + S3C2440_SDIDATA);
-
- s3c2410_dma_config(context->dma_channel, context->data_size,
- S3C2410_DCON_CH0_SDI);
- //(S3C2410_DCON_HWTRIG | S3C2410_DCON_CH0_SDI));
-
- s3c2410_dma_set_buffdone_fn(context->dma_channel, s3c24xx_hcd_dma_done);
-
-// s3c2410_dma_setflags(context->dma_channel, S3C2410_DMAF_AUTOSTART);
-
- s3c2410_dma_ctrl(context->dma_channel, S3C2410_DMAOP_FLUSH);
-
- s3c2410_dma_enqueue(context->dma_channel, context,
- context->io_buffer_dma,
- req->DataRemaining);
-
- return 0;
-}
-
-
-static irqreturn_t s3c24xx_hcd_irq(int irq, void *dev_id)
-{
- u32 cmdsta, dsta, fsta;
- unsigned long flags, trace = 0;
- PSDREQUEST req;
- struct s3c24xx_hcd_context * context =
- (struct s3c24xx_hcd_context *)dev_id;
-
- spin_lock_irqsave(&context->lock, flags);
-
- s3c24xx_hcd_clear_imask(context);
-
- cmdsta = readl(context->base + S3C2410_SDICMDSTAT);
- dsta = readl(context->base + S3C2410_SDIDSTA);
- fsta = readl(context->base + S3C2410_SDIFSTA);
-
- context->cmdsta = cmdsta;
- context->dsta = dsta;
- context->fsta = fsta;
-
- s3c24xx_hcd_clear_csta(context);
-
- if (dsta & S3C2410_SDIDSTA_SDIOIRQDETECT) {
- writel(S3C2410_SDIDSTA_SDIOIRQDETECT, context->base + S3C2410_SDIDSTA);
-
- if (context->int_sdio) {
- u32 imask;
-
- context->int_sdio = 0;
-
- imask = readl(context->base + S3C2440_SDIIMSK);
- imask &= ~S3C2410_SDIIMSK_SDIOIRQ;
- writel(imask, context->base + S3C2440_SDIIMSK);
- schedule_work(&context->irq_work);
- }
- }
-
- req = GET_CURRENT_REQUEST(&context->hcd);
- if (req == NULL) {
- DBG_PRINT(SDDBG_TRACE, ("%s(): No current request\n", __FUNCTION__));
- goto out;
- }
-
- if (cmdsta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
- DBG_PRINT(SDDBG_ERROR, ("TIMEOUT\n"));
- printk("TIMEOUT\n");
- req->Status = SDIO_STATUS_BUS_RESP_TIMEOUT;
- writel(S3C2410_SDICMDSTAT_CMDTIMEOUT, context->base + S3C2410_SDICMDSTAT);
- schedule_work(&context->io_work);
- }
-
- if (cmdsta & S3C2410_SDICMDSTAT_CRCFAIL) {
- DBG_PRINT(SDDBG_ERROR, ("CRCFAIL 0x%x\n", cmdsta));
- printk("CRCFAIL 0x%x\n", cmdsta);
- req->Status = SDIO_STATUS_BUS_RESP_CRC_ERR;
- dump_request(context);
- writel(S3C2410_SDICMDSTAT_CRCFAIL, context->base + S3C2410_SDICMDSTAT);
- schedule_work(&context->io_work);
- }
-
-
- if (cmdsta & S3C2410_SDICMDSTAT_CMDSENT) {
- writel(S3C2410_SDICMDSTAT_CMDSENT, context->base + S3C2410_SDICMDSTAT);
-
- if (context->complete == S3C24XX_HCD_NO_RESPONSE) {
- req->Status = SDIO_STATUS_SUCCESS;
- trace = 1;
- schedule_work(&context->io_work);
- }
- }
-
- if (cmdsta & S3C2410_SDICMDSTAT_RSPFIN ||
- (IS_SDREQ_WRITE_DATA(req->Flags) && (fsta & S3C2410_SDIFSTA_TFDET)) ||
- (!IS_SDREQ_WRITE_DATA(req->Flags) && (fsta & S3C2410_SDIFSTA_RFDET))) {
-
- writel(S3C2410_SDICMDSTAT_RSPFIN, context->base + S3C2410_SDICMDSTAT);
-
- if (context->complete == S3C24XX_HCD_RESPONSE_SHORT ||
- context->complete == S3C24XX_HCD_RESPONSE_LONG ||
- context->complete == S3C24XX_HCD_DATA_READ ||
- context->complete == S3C24XX_HCD_DATA_WRITE) {
- req->Status = SDIO_STATUS_SUCCESS;
- if (trace)
- printk("IO work already scheduled, cmdsta: 0x%x\n", cmdsta);
- schedule_work(&context->io_work);
- }
- }
-
- out:
- if (dsta & S3C2410_SDIDSTA_RDYWAITREQ) {
- printk("S3C2410_SDIDSTA_RDYWAITREQ\n");
- //writel(S3C2410_SDIDSTA_RDYWAITREQ, context->base + S3C2410_SDIDSTA);
- }
-
- if (dsta & S3C2410_SDIDSTA_FIFOFAIL) {
- printk("S3C2410_SDIDSTA_FIFOFAIL\n");
- writel(S3C2410_SDIDSTA_FIFOFAIL, context->base + S3C2410_SDIDSTA);
- }
-
- if (dsta & S3C2410_SDIDSTA_CRCFAIL) {
- printk("S3C2410_SDIDSTA_CRCFAIL\n");
- writel(S3C2410_SDIDSTA_CRCFAIL, context->base + S3C2410_SDIDSTA);
- }
-
- if (dsta & S3C2410_SDIDSTA_RXCRCFAIL) {
- printk("S3C2410_SDIDSTA_RXCRCFAIL\n");
- writel(S3C2410_SDIDSTA_RXCRCFAIL, context->base + S3C2410_SDIDSTA);
- }
-
- if (dsta & S3C2410_SDIDSTA_DATATIMEOUT) {
- printk("S3C2410_SDIDSTA_DATATIMEOUT\n");
- writel(S3C2410_SDIDSTA_DATATIMEOUT, context->base + S3C2410_SDIDSTA);
- }
-
- if (dsta & S3C2410_SDIDSTA_BUSYFINISH) {
- printk("S3C2410_SDIDSTA_BUSYFINISH\n");
- writel(S3C2410_SDIDSTA_BUSYFINISH, context->base + S3C2410_SDIDSTA);
- }
-
- if (dsta & S3C2410_SDIDSTA_SBITERR) {
- printk("S3C2410_SDIDSTA_SBIERR\n");
- writel(S3C2410_SDIDSTA_SBITERR, context->base + S3C2410_SDIDSTA);
- }
-
- spin_unlock_irqrestore(&context->lock, flags);
- return IRQ_HANDLED;
-}
-
-
-SDIO_STATUS s3c24xx_hcd_config(PSDHCD hcd, PSDCONFIG config)
-{
- u32 con, imsk;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDCONFIG_SDIO_INT_CTRL_DATA int_data;
- struct s3c24xx_hcd_context * context = (struct s3c24xx_hcd_context *)hcd->pContext;
-
- switch (GET_SDCONFIG_CMD(config)){
- case SDCONFIG_GET_WP:
- DBG_PRINT(SDDBG_TRACE, ("config GET_WP\n"));
- *((SDCONFIG_WP_VALUE *)config->pData) = 0;
- status = SDIO_STATUS_SUCCESS;
- break;
- case SDCONFIG_SEND_INIT_CLOCKS:
- DBG_PRINT(SDDBG_TRACE, ("config SEND_INIT_CLOCKS\n"));
-
- /* We stop/start the clock */
- con = readl(context->base + S3C2410_SDICON);
-
- con &= ~S3C2410_SDICON_CLOCKTYPE;
- writel(con, context->base + S3C2410_SDICON);
-
- mdelay(100);
-
- con |= S3C2410_SDICON_CLOCKTYPE;
- writel(con, context->base + S3C2410_SDICON);
-
- mdelay(100);
-
- status = SDIO_STATUS_SUCCESS;
- break;
- case SDCONFIG_SDIO_INT_CTRL:
- DBG_PRINT(SDDBG_TRACE, ("config SDIO_INT_CTRL\n"));
- int_data = GET_SDCONFIG_CMD_DATA(PSDCONFIG_SDIO_INT_CTRL_DATA, config);
-
- if (int_data->SlotIRQEnable &
- (IRQ_DETECT_1_BIT | IRQ_DETECT_4_BIT | IRQ_DETECT_MULTI_BLK) ) {
- imsk = readl(context->base + S3C2440_SDIIMSK);
-
- if (int_data->SlotIRQEnable) {
- printk("SDIO_INT_CTRL enable IRQ\n");
- DBG_PRINT(SDDBG_TRACE, ("SDIO_INT_CTRL enable IRQ\n"));
- context->int_sdio = 1;
- imsk |= S3C2410_SDIIMSK_SDIOIRQ;
- writel(imsk, context->base + S3C2440_SDIIMSK);
- } else {
- printk("SDIO_INT_CTRL disable IRQ\n");
- DBG_PRINT(SDDBG_TRACE, ("SDIO_INT_CTRL disable IRQ\n"));
- context->int_sdio = 0;
- imsk &= ~S3C2410_SDIIMSK_SDIOIRQ;
- writel(imsk, context->base + S3C2440_SDIIMSK);
- }
- }
- status = SDIO_STATUS_SUCCESS;
- break;
- case SDCONFIG_SDIO_REARM_INT:
- DBG_PRINT(SDDBG_TRACE, ("config SDIO_REARM_INT\n"));
-
- context->int_sdio = 1;
- imsk = readl(context->base + S3C2440_SDIIMSK);
- imsk |= S3C2410_SDIIMSK_SDIOIRQ;
- writel(imsk, context->base + S3C2440_SDIIMSK);
-
- status = SDIO_STATUS_SUCCESS;
- break;
- case SDCONFIG_FUNC_CHANGE_BUS_MODE:
- case SDCONFIG_BUS_MODE_CTRL:
- s3c24xx_hcd_set_bus_mode(context, (PSDCONFIG_BUS_MODE_DATA)(config->pData));
- DBG_PRINT(SDDBG_TRACE, ("config BUS_MODE_CTRL\n"));
- status = SDIO_STATUS_SUCCESS;
- break;
- case SDCONFIG_POWER_CTRL:
- DBG_PRINT(SDDBG_TRACE, ("config POWER_CTRL\n"));
- status = SDIO_STATUS_SUCCESS;
- break;
- case SDCONFIG_GET_HCD_DEBUG:
- DBG_PRINT(SDDBG_TRACE, ("config GET_HCD_DEBUG\n"));
- status = SDIO_STATUS_SUCCESS;
- break;
- case SDCONFIG_SET_HCD_DEBUG:
- DBG_PRINT(SDDBG_TRACE, ("config SET_HCD_DEBUG\n"));
- status = SDIO_STATUS_SUCCESS;
- break;
- default:
- /* invalid request */
- DBG_PRINT(SDDBG_ERROR, ("%s() - unsupported command: 0x%X\n",
- __FUNCTION__, GET_SDCONFIG_CMD(config)));
- status = SDIO_STATUS_INVALID_PARAMETER;
- }
-
- return SDIOErrorToOSError(status);
-}
-
-
-SDIO_STATUS s3c24xx_hcd_request(PSDHCD hcd)
-{
- SDIO_STATUS status = SDIO_STATUS_PENDING;
- PSDREQUEST req;
- u32 cmdcon, imask;
- unsigned long flags;
- struct s3c24xx_hcd_context * context =
- (struct s3c24xx_hcd_context *)hcd->pContext;
-
- req = GET_CURRENT_REQUEST(hcd);
- DBG_ASSERT(req != NULL);
-
- if (req->Flags & SDREQ_FLAGS_DATA_SHORT_TRANSFER)
- printk("### SHORT TRANSFER ###\n");
-
- spin_lock_irqsave(&context->lock, flags);
-
- /* Clear command, data and fifo status registers */
- writel(0xFFFFFFFF, context->base + S3C2410_SDICMDSTAT);
- writel(0xFFFFFFFF, context->base + S3C2410_SDIDSTA);
- writel(0xFFFFFFFF, context->base + S3C2410_SDIFSTA);
-
- /* Enabling irqs */
- imask = S3C2410_SDIIMSK_READWAIT;
-
- cmdcon = readl(context->base + S3C2410_SDICMDCON);
-
- switch (GET_SDREQ_RESP_TYPE(req->Flags)) {
- case SDREQ_FLAGS_NO_RESP:
- cmdcon &= ~S3C2410_SDICMDCON_WAITRSP;
- context->complete = S3C24XX_HCD_NO_RESPONSE;
- imask |= S3C2410_SDIIMSK_CMDSENT;
- break;
- case SDREQ_FLAGS_RESP_R1:
- case SDREQ_FLAGS_RESP_R1B:
- case SDREQ_FLAGS_RESP_R3:
- case SDREQ_FLAGS_RESP_SDIO_R4:
- case SDREQ_FLAGS_RESP_SDIO_R5:
- case SDREQ_FLAGS_RESP_R6:
- cmdcon &= ~S3C2410_SDICMDCON_LONGRSP;
- cmdcon |= S3C2410_SDICMDCON_WAITRSP;
- context->complete = S3C24XX_HCD_RESPONSE_SHORT;
- imask |= S3C2410_SDIIMSK_CRCSTATUS | S3C2410_SDIIMSK_RESPONSEND
- | S3C2410_SDIIMSK_CMDTIMEOUT | S3C2410_SDIIMSK_RESPONSECRC;
- break;
- case SDREQ_FLAGS_RESP_R2:
- cmdcon |= S3C2410_SDICMDCON_LONGRSP;
- cmdcon |= S3C2410_SDICMDCON_WAITRSP;
- context->complete = S3C24XX_HCD_RESPONSE_LONG;
- imask |= S3C2410_SDIIMSK_CRCSTATUS | S3C2410_SDIIMSK_RESPONSEND
- | S3C2410_SDIIMSK_CMDTIMEOUT | S3C2410_SDIIMSK_RESPONSECRC;
- break;
-
- }
-
- /* There is a data part */
- if (IS_SDREQ_DATA_TRANS(req->Flags)) {
- u32 dcon = 0;
-
- if (readl(context->base + S3C2410_SDIDSTA) &
- (S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) {
- printk("##### DATA ON: 0x%x ######\n", readl(context->base + S3C2410_SDIDSTA));
- }
-
- /* Setting timer */
- writel(0x7fffff, context->base + S3C2410_SDITIMER);
-
- /* Block size */
- writel(req->BlockLen, context->base + S3C2410_SDIBSIZE);
- /* Number of blocks */
- dcon |= (0xfff & req->BlockCount);
-
- if (context->bus_width == 4)
- dcon |= S3C2410_SDIDCON_WIDEBUS;
-
- req->DataRemaining = req->BlockCount * req->BlockLen;
-
- /* Set data size, and start the transfer */
- dcon |= S3C2410_SDIDCON_IRQPERIOD;
- if (!(req->DataRemaining % 4)) {
- context->data_size = 4;
- dcon |= S3C2440_SDIDCON_DS_WORD;
- } else if (!(req->DataRemaining % 2)) {
- context->data_size = 2;
- dcon |= S3C2440_SDIDCON_DS_HALFWORD;
- } else {
- context->data_size = 1;
- dcon |= S3C2440_SDIDCON_DS_BYTE;
- }
-
-#ifdef CONFIG_SDIO_S3C24XX_DMA
- if (req->DataRemaining > 16) {
- context->dma_en = 1;
- } else
-#endif
- {
- context->dma_en = 0;
- context->data_size = 1;
- dcon |= S3C2440_SDIDCON_DS_BYTE;
- }
-
- if (context->dma_en) {
- dcon |= S3C2410_SDIDCON_DMAEN;
- s3c24xx_hcd_prepare_dma(context);
- }
-
- if (IS_SDREQ_WRITE_DATA(req->Flags)) {
- /* Data write */
- DBG_PRINT(SDDBG_TRACE, ("Start data write, block count=%d, block size=%d\n",
- req->BlockCount, req->BlockLen));
-
- /* Data configuration: transmit after resp, block mode*/
- dcon |= S3C2410_SDIDCON_TXAFTERRESP | S3C2410_SDIDCON_BLOCKMODE;
-
- /* This is a write */
- dcon |= S3C2410_SDIDCON_XFER_TXSTART;
-
- imask |= S3C2410_SDIIMSK_TXFIFOHALF | S3C2410_SDIIMSK_TXFIFOEMPTY |
- S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC |
- S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH;
-
- context->complete = S3C24XX_HCD_DATA_WRITE;
- } else {
- /* Data read */
- DBG_PRINT(SDDBG_TRACE, ("Start data read, block count=%d, block size=%d\n",
- req->BlockCount, req->BlockLen));
-
- /* Data configuration: receive after cmd, block mode*/
- dcon |= S3C2410_SDIDCON_RXAFTERCMD | S3C2410_SDIDCON_BLOCKMODE;
-
- /* This is a read */
- dcon |= S3C2410_SDIDCON_XFER_RXSTART;
-
- imask |= S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST |
- S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC |
- S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH;
-
- context->complete = S3C24XX_HCD_DATA_READ;
- }
-
- dcon |= S3C2440_SDIDCON_DATSTART;
-
- writel(dcon, context->base + S3C2410_SDIDCON);
-
- cmdcon |= S3C2410_SDICMDCON_WITHDATA;
-
- } else {
- cmdcon &= ~S3C2410_SDICMDCON_WITHDATA;
- }
-
- cmdcon |= req->Command & S3C2410_SDICMDCON_INDEX;
- cmdcon |= S3C2410_SDICMDCON_SENDERHOST | S3C2410_SDICMDCON_CMDSTART;
-
- req->Status = SDIO_STATUS_PENDING;
-
- if (context->int_sdio)
- imask |= S3C2410_SDIIMSK_SDIOIRQ;
- context->int_mask = imask;
- writel(imask, context->base + S3C2440_SDIIMSK);
- writel(req->Argument, context->base + S3C2410_SDICMDARG);
- writel(cmdcon, context->base + S3C2410_SDICMDCON);
-
- spin_unlock_irqrestore(&context->lock, flags);
-
- return status;
-}
-
-static int s3c24xx_hcd_hw_init(struct s3c24xx_hcd_context * context)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- u32 con, datacon;
-
- /* Clock */
- context->device.clock = clk_get(NULL, "sdi");
- if (IS_ERR(context->device.clock)) {
- DBG_PRINT(SDDBG_ERROR, ("Couldn't get clock\n"));
- status = PTR_ERR(context->device.clock);
- context->device.clock = NULL;
- return status;
- }
-
- status = clk_enable(context->device.clock);
- if (SDIO_IS_ERROR(status)) {
- DBG_PRINT(SDDBG_ERROR, ("Couldn't get clock\n"));
- return SDIOErrorToOSError(status);
- }
-
- context->device.max_clock_rate = clk_get_rate(context->device.clock);
- context->device.actual_clock_rate = context->device.max_clock_rate;
-
- /* I/O */
- context->mem = request_mem_region(context->mem->start,
- RESSIZE(context->mem), context->description);
-
- if (!context->mem) {
- DBG_PRINT(SDDBG_ERROR, ("Failed to request io memory region\n"));
- status = -ENOENT;
- goto out_disable_clock;
- }
-
- context->base = ioremap(context->mem->start, RESSIZE(context->mem));
- if (context->base == 0) {
- DBG_PRINT(SDDBG_ERROR, ("failed to ioremap() io memory region.\n"));
- status = -EINVAL;
- goto out_free_mem_region;
- }
-
- /* IRQ */
-#if 0
- context->cd_irq = s3c2410_gpio_getirq(GTA02v1_GPIO_nSD_DETECT);
- s3c2410_gpio_cfgpin(GTA02v1_GPIO_nSD_DETECT, S3C2410_GPIO_IRQ);
-
- if (request_irq(context->cd_irq, s3c24xx_hcd_cd_irq, 0, context->description, context)) {
- DBG_PRINT(SDDBG_ERROR, ("failed to request card detect interrupt.\n"));
- status = -ENOENT;
- goto out_unmap_mem_region;
- }
-#endif
-
- if (request_irq(context->io_irq, s3c24xx_hcd_irq, 0, context->description, context)) {
- DBG_PRINT(SDDBG_ERROR, ("failed to request mci interrupt.\n"));
- status = -ENOENT;
- goto out_unmap_mem_region;
- }
-
-
- /* DMA */
- context->io_buffer_size = 4 * 4096;
- context->io_buffer = dma_alloc_writecombine(&context->pdev->dev,
- context->io_buffer_size,
- &context->io_buffer_dma,
- GFP_KERNEL | GFP_DMA);
-
- if (context->io_buffer == NULL) {
- DBG_PRINT(SDDBG_ERROR, ("failed to allocate DMA buffer\n"));
- status = -ENOMEM;
- goto out_free_irq;
-
- }
-
- if (s3c2410_dma_request(context->dma_channel, &s3c24xx_hcd_dma_client,
- NULL) < 0) {
- DBG_PRINT(SDDBG_ERROR, ("unable to get DMA channel.\n"));
- status = -ENOENT;
- goto out_free_dma;
- }
-
-
- /* Set multiplexing */
- s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK);
- s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD);
- s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0);
- s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1);
- s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
- s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
-
- con = readl(context->base + S3C2410_SDICON);
- con |= S3C2410_SDICON_SDIOIRQ;
- writel(con, context->base + S3C2410_SDICON);
-
- datacon = readl(context->base + S3C2410_SDIDCON);
- datacon |= S3C2410_SDIDCON_WIDEBUS;
- writel(datacon, context->base + S3C2410_SDIDCON);
-
- printk("S3c24xx SDIO: IRQ:%d Detect IRQ:%d DMA channel:%d base@0x%p PCLK@%ld kHz\n",
- context->io_irq, context->cd_irq, context->dma_channel, context->base,
- context->device.max_clock_rate/1000);
-
- return SDIOErrorToOSError(status);
-
- out_free_dma:
- dma_free_writecombine(&context->pdev->dev,context->io_buffer_size,
- context->io_buffer, context->io_buffer_dma);
-
- out_free_irq:
- free_irq(context->io_irq, context);
-
- out_unmap_mem_region:
- iounmap(context->base);
-
- out_free_mem_region:
- release_mem_region(context->mem->start, RESSIZE(context->mem));
-
- out_disable_clock:
- clk_disable(context->device.clock);
-
- return SDIOErrorToOSError(status);
-}
-
-static void s3c24xx_hcd_hw_cleanup(struct s3c24xx_hcd_context * context)
-{
- clk_disable(context->device.clock);
- free_irq(context->io_irq, context);
- iounmap(context->base);
- release_mem_region(context->mem->start, RESSIZE(context->mem));
- dma_free_writecombine(&context->pdev->dev,context->io_buffer_size,
- context->io_buffer, context->io_buffer_dma);
-}
-
-static int s3c24xx_hcd_pnp_probe(struct pnp_dev *pBusDevice, const struct pnp_device_id *pId)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- status = s3c24xx_hcd_hw_init(&hcd_context);
- if (SDIO_IS_ERROR(status)) {
- DBG_PRINT(SDDBG_ERROR, ("HW Init failed\n"));
- return SDIOErrorToOSError(status);
- }
-
- status = SDIO_RegisterHostController(&hcd_context.hcd);
- if (SDIO_IS_ERROR(status)) {
- DBG_PRINT(SDDBG_ERROR, ("Host registration failed\n"));
- s3c24xx_hcd_hw_cleanup(&hcd_context);
- return SDIOErrorToOSError(status);
- }
-
- /* Our card is built-in, we force the attachement event */
- SDIO_HandleHcdEvent(&hcd_context.hcd, EVENT_HCD_ATTACH);
-
- return 0;
-}
-
-static void s3c24xx_hcd_pnp_remove(struct pnp_dev *pBusDevice)
-{
-}
-
-/* the driver context data */
-struct s3c24xx_hcd_context hcd_context = {
- .description = DESCRIPTION,
- .hcd.pName = "sdio_s3c24xx",
- .hcd.Version = CT_SDIO_STACK_VERSION_CODE,
- .hcd.pModule = THIS_MODULE,
- /* builtin card, 4 bits bus */
- .hcd.Attributes = SDHCD_ATTRIB_BUS_4BIT | SDHCD_ATTRIB_BUS_1BIT | SDHCD_ATTRIB_MULTI_BLK_IRQ,
- .hcd.SlotNumber = 0,
- .hcd.MaxSlotCurrent = 500, /* 1/2 amp */
- .hcd.SlotVoltageCaps = SLOT_POWER_3_3V, /* 3.3V */
- .hcd.SlotVoltagePreferred = SLOT_POWER_3_3V, /* 3.3V */
- .hcd.MaxClockRate = 25000000,
- .hcd.MaxBytesPerBlock = 0xfff, /* 0 - 4095 */
- .hcd.MaxBlocksPerTrans = 0xfff, /* 0 - 4095 */
- .hcd.pContext = &hcd_context,
- .hcd.pRequest = s3c24xx_hcd_request,
- .hcd.pConfigure = s3c24xx_hcd_config,
- .device.pnp_driver.name = "sdio_s3c24xx_hcd",
- .device.pnp_driver.probe = s3c24xx_hcd_pnp_probe,
- .device.pnp_driver.remove = s3c24xx_hcd_pnp_remove,
-};
-
-static int s3c24xx_hcd_probe(struct platform_device * pdev)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- struct resource *r = NULL;
-
- printk("S3c2440 SDIO Host controller\n");
-
- hcd_context.pdev = pdev;
-
- hcd_context.mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (hcd_context.mem == NULL) {
- DBG_PRINT(SDDBG_ERROR, ("No memory region\n"));
- status = SDIO_STATUS_NO_RESOURCES;
- goto out;
- }
-
- hcd_context.io_irq = platform_get_irq(pdev, 0);
- if (hcd_context.io_irq == 0) {
- DBG_PRINT(SDDBG_ERROR, ("No IRQ\n"));
- status = SDIO_STATUS_NO_RESOURCES;
- goto out;
- }
-
- r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (r == NULL) {
- DBG_PRINT(SDDBG_ERROR, ("No DMA channel\n"));
- status = SDIO_STATUS_NO_RESOURCES;
- goto out;
- }
- hcd_context.dma_channel = r->start;
- hcd_context.dma_en = 0;
-
- hcd_context.int_sdio = 0;
-
- spin_lock_init(&hcd_context.lock);
-
- init_completion(&hcd_context.dma_complete);
- init_completion(&hcd_context.xfer_complete);
-
- INIT_WORK(&hcd_context.io_work, s3c24xx_hcd_io_work);
- INIT_WORK(&hcd_context.irq_work, s3c24xx_hcd_irq_work);
-
- mdelay(100);
-
- status = SDIO_BusAddOSDevice(&hcd_context.device.dma,
- &hcd_context.device.pnp_driver,
- &hcd_context.device.pnp_device, "sdio_s3c24xx_hcd");
-
- out:
-
- return SDIOErrorToOSError(status);
-}
-
-/*
- * module cleanup
- */
-static int s3c24xx_hcd_remove(struct platform_device * pdev) {
- printk("S3C2440 SDIO host controller unloaded\n");
- SDIO_BusRemoveOSDevice(&hcd_context.device.pnp_driver, hcd_context.device.pnp_device);
- kfree(hcd_context.device.pnp_device);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-
-static int s3c24xx_hcd_suspend(struct platform_device * pdev, pm_message_t state)
-{
- struct s3c24xx_hcd_context * context = &hcd_context;
- unsigned long flags;
-
- spin_lock_irqsave(&context->lock, flags);
-
- context->suspend_regs.con = readl(context->base + S3C2410_SDICON);
- context->suspend_regs.pre = readl(context->base + S3C2410_SDIPRE);
- context->suspend_regs.cmdarg = readl(context->base + S3C2410_SDICMDARG);
- context->suspend_regs.cmdcon = readl(context->base + S3C2410_SDICMDCON);
- context->suspend_regs.cmdsta = readl(context->base + S3C2410_SDICMDSTAT);
- context->suspend_regs.r0 = readl(context->base + S3C2410_SDIRSP0);
- context->suspend_regs.r1 = readl(context->base + S3C2410_SDIRSP1);
- context->suspend_regs.r2 = readl(context->base + S3C2410_SDIRSP2);
- context->suspend_regs.r3 = readl(context->base + S3C2410_SDIRSP3);
- context->suspend_regs.timer = readl(context->base + S3C2410_SDITIMER);
- context->suspend_regs.bsize = readl(context->base + S3C2410_SDIBSIZE);
- context->suspend_regs.datcon = readl(context->base + S3C2410_SDIDCON);
- context->suspend_regs.datcnt = readl(context->base + S3C2410_SDIDCNT);
- context->suspend_regs.datsta = readl(context->base + S3C2410_SDIDSTA);
- context->suspend_regs.fsta = readl(context->base + S3C2410_SDIFSTA);
- context->suspend_regs.imask = readl(context->base + S3C2440_SDIIMSK);
-
- spin_unlock_irqrestore(&context->lock, flags);
- return 0;
-}
-
-static int s3c24xx_hcd_resume(struct platform_device * pdev)
-{
- struct s3c24xx_hcd_context * context = &hcd_context;
- unsigned long flags;
-
- spin_lock_irqsave(&context->lock, flags);
-
- writel(context->suspend_regs.con, context->base + S3C2410_SDICON);
- writel(context->suspend_regs.pre, context->base + S3C2410_SDIPRE);
- writel(context->suspend_regs.cmdarg, context->base + S3C2410_SDICMDARG);
- writel(context->suspend_regs.cmdcon, context->base + S3C2410_SDICMDCON);
- writel(context->suspend_regs.cmdsta, context->base + S3C2410_SDICMDSTAT);
- writel(context->suspend_regs.r0, context->base + S3C2410_SDIRSP0);
- writel(context->suspend_regs.r1, context->base + S3C2410_SDIRSP1);
- writel(context->suspend_regs.r2, context->base + S3C2410_SDIRSP2);
- writel(context->suspend_regs.r3, context->base + S3C2410_SDIRSP3);
- writel(context->suspend_regs.timer, context->base + S3C2410_SDITIMER);
- writel(context->suspend_regs.bsize, context->base + S3C2410_SDIBSIZE);
- writel(context->suspend_regs.datcon, context->base + S3C2410_SDIDCON);
- writel(context->suspend_regs.datcnt, context->base + S3C2410_SDIDCNT);
- writel(context->suspend_regs.datsta, context->base + S3C2410_SDIDSTA);
- writel(context->suspend_regs.fsta, context->base + S3C2410_SDIFSTA);
- writel(context->suspend_regs.imask, context->base + S3C2440_SDIIMSK);
-
- spin_unlock_irqrestore(&context->lock, flags);
- return 0;
-}
-
-#else
-#define s3c24xx_hcd_suspend = NULL
-#define s3c24xx_hcd_resume = NULL
-#endif
-
-static struct platform_driver s3c24xx_hcd_sdio =
-{
- .driver.name = "s3c24xx-sdio",
- .probe = s3c24xx_hcd_probe,
- .remove = s3c24xx_hcd_remove,
- .suspend = s3c24xx_hcd_suspend,
- .resume = s3c24xx_hcd_resume,
-};
-
-#ifdef CONFIG_DEBUG_FS
-static struct dentry *debugfs_dir;
-
-static int s3c24xx_hcd_debugfs_show(struct seq_file *s, void *data)
-{
- PSDREQUEST req;
- u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer, bsize;
- u32 datcon, datcnt, datsta, fsta, imask;
- struct s3c24xx_hcd_context * context = &hcd_context;
-
-
- con = readl(context->base + S3C2410_SDICON);
- pre = readl(context->base + S3C2410_SDIPRE);
- cmdarg = readl(context->base + S3C2410_SDICMDARG);
- cmdcon = readl(context->base + S3C2410_SDICMDCON);
- cmdsta = readl(context->base + S3C2410_SDICMDSTAT);
- r0 = readl(context->base + S3C2410_SDIRSP0);
- r1 = readl(context->base + S3C2410_SDIRSP1);
- r2 = readl(context->base + S3C2410_SDIRSP2);
- r3 = readl(context->base + S3C2410_SDIRSP3);
- timer = readl(context->base + S3C2410_SDITIMER);
- bsize = readl(context->base + S3C2410_SDIBSIZE);
- datcon = readl(context->base + S3C2410_SDIDCON);
- datcnt = readl(context->base + S3C2410_SDIDCNT);
- datsta = readl(context->base + S3C2410_SDIDSTA);
- fsta = readl(context->base + S3C2410_SDIFSTA);
- imask = readl(context->base + S3C2440_SDIIMSK);
-
- seq_printf(s, "SDICON: 0x%08x\n", con);
- seq_printf(s, "SDIPRE: 0x%08x\n", pre);
- seq_printf(s, "SDICmdArg: 0x%08x\n", cmdarg);
- seq_printf(s, "SDICmdCon: 0x%08x\n", cmdcon);
- seq_printf(s, "SDICmdSta: 0x%08x\n", cmdsta);
- seq_printf(s, "SDIRSP0: 0x%08x\n", r0);
- seq_printf(s, "SDIRSP1: 0x%08x\n", r1);
- seq_printf(s, "SDIRSP2: 0x%08x\n", r2);
- seq_printf(s, "SDIRSP3: 0x%08x\n", r3);
- seq_printf(s, "SDIDTimer: 0x%08x\n", timer);
- seq_printf(s, "SDIBSize: 0x%08x\n", bsize);
- seq_printf(s, "SDIDatCon: 0x%08x\n", datcon);
- seq_printf(s, "SDIDatCnt: 0x%08x\n", datcnt);
- seq_printf(s, "SDIDatSta: 0x%08x\n", datsta);
- seq_printf(s, "SDIFSta: 0x%08x\n", fsta);
- seq_printf(s, "SDIIntMsk: 0x%08x\n", imask);
- seq_printf(s, "\n");
-
- seq_printf(s, "Current REQ: \n");
- req = GET_CURRENT_REQUEST(&context->hcd);
- if (req == NULL) {
- seq_printf(s, " No current request\n");
- } else {
- seq_printf(s, " Command: %d\n", req->Command);
- seq_printf(s, " Args: 0x%x\n", req->Argument);
- seq_printf(s, " Flags: 0x%x\n", req->Flags);
- seq_printf(s, " %d blocks x %d bytes\n", req->BlockCount, req->BlockLen);
- seq_printf(s, " %d bytes remaining\n", req->DataRemaining);
- }
-
- seq_printf(s, "Context: \n");
- seq_printf(s, " INT mask: 0x%x\n", context->int_mask);
- seq_printf(s, " sdio INT: %d\n", context->int_sdio);
- seq_printf(s, " cmdsta: 0x%x\n", context->cmdsta);
- seq_printf(s, " dsta: 0x%x\n", context->dsta);
- seq_printf(s, " fsta: 0x%x\n", context->fsta);
-
- return 0;
-}
-
-static int s3c24xx_hcd_debugfs_open(struct inode *inode,
- struct file *file)
-{
- return single_open(file, s3c24xx_hcd_debugfs_show, NULL);
-}
-
-static const struct file_operations s3c24xx_hcd_debugfs_fops = {
- .open = s3c24xx_hcd_debugfs_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
-};
-
-
-static int s3c24xx_debugfs_init(struct s3c24xx_hcd_context * context)
-{
- debugfs_dir = debugfs_create_dir("s3c24xx_sdio", NULL);
-
- debugfs_create_file("registers", 0444, debugfs_dir,
- (void *)context,
- &s3c24xx_hcd_debugfs_fops);
-
- return 0;
-}
-
-#else
-
-static int s3c24xx_debugfs_init(struct s3c24xx_hcd_context * context)
-{
- return 0;
-}
-
-#endif
-
-static int __init s3c24xx_hcd_init(void)
-{
- int ret;
-
- ret = s3c24xx_debugfs_init(&hcd_context);
- if (ret) {
- printk("%s(): debugfs init failed\n", __FUNCTION__);
- }
-
- platform_driver_register(&s3c24xx_hcd_sdio);
-
- return 0;
-}
-
-static void __exit s3c24xx_hcd_exit(void)
-{
- platform_driver_unregister(&s3c24xx_hcd_sdio);
-}
-
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(DESCRIPTION);
-MODULE_AUTHOR(AUTHOR);
-
-module_init(s3c24xx_hcd_init);
-module_exit(s3c24xx_hcd_exit);
diff --git a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
deleted file mode 100644
index f8b0912ba56..00000000000
--- a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef __SDIO_S3C24XX_HCD_H___
-#define __SDIO_S3C24XX_HCD_H___
-
-#define S3C24XX_HCD_NO_RESPONSE 1
-#define S3C24XX_HCD_RESPONSE_SHORT 2
-#define S3C24XX_HCD_RESPONSE_LONG 3
-#define S3C24XX_HCD_DATA_READ 4
-#define S3C24XX_HCD_DATA_WRITE 5
-
-struct s3c24xx_hcd_device {
- OS_PNPDEVICE *pnp_device; /* the OS device for this HCD */
- OS_PNPDRIVER pnp_driver; /* the OS driver for this HCD */
- SDDMA_DESCRIPTION dma;
- struct clk * clock;
- unsigned long max_clock_rate;
- unsigned long actual_clock_rate;
-};
-
-
-/* driver wide data, this driver only supports one device,
- * so we include the per device data here also */
-struct s3c24xx_hcd_context {
- PTEXT description; /* human readable device decsription */
- SDHCD hcd; /* HCD description for bus driver */
- struct s3c24xx_hcd_device device; /* the single device's info */
- struct platform_device *pdev;
- struct resource *mem;
- void __iomem *base;
- UINT32 io_irq;
- UINT32 cd_irq;
- BOOL card_inserted; /* card inserted flag */
- BOOL cmd_processed; /* command phase was processed */
- UINT32 fifo_depth; /* FIFO depth for the bus mode */
- BOOL irq_masked;
- UINT32 bus_width;
- UINT32 data_size; /* Word, half word, or byte */
- UINT32 latest_xfer_size;
-
- void *io_buffer; /* Kernel address */
- dma_addr_t io_buffer_dma; /* Bus address */
- UINT32 io_buffer_size;
- UINT32 dma_channel;
- UINT32 dma_en;
- struct completion dma_complete;
- struct completion xfer_complete;
-
- UINT32 int_mask;
- UINT32 int_sdio; /* Do we have SDIO interrupt on ? */
-
- UINT32 complete;
-
- UINT32 cmdsta;
- UINT32 dsta;
- UINT32 fsta;
-
- spinlock_t lock;
-
- struct work_struct io_work;
- struct work_struct irq_work;
-
-#ifdef CONFIG_PM
- struct {
- UINT32 con;
- UINT32 pre;
- UINT32 cmdarg, cmdcon, cmdsta;
- UINT32 r0, r1, r2, r3;
- UINT32 timer;
- UINT32 bsize;
- UINT32 datcon, datcnt, datsta;
- UINT32 fsta;
- UINT32 imask;
- } suspend_regs;
-#endif
-};
-
-SDIO_STATUS s3c24xx_hcd_config(PSDHCD hcd, PSDCONFIG config);
-SDIO_STATUS s3c24xx_hcd_request(PSDHCD hcd);
-
-struct s3c24xx_hcd_context hcd_context;
-
-#endif
diff --git a/drivers/sdio/stack/Makefile b/drivers/sdio/stack/Makefile
deleted file mode 100644
index ff0e24d0176..00000000000
--- a/drivers/sdio/stack/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_SDIO) += busdriver/ lib/ \ No newline at end of file
diff --git a/drivers/sdio/stack/busdriver/Makefile b/drivers/sdio/stack/busdriver/Makefile
deleted file mode 100644
index 1130e2d9139..00000000000
--- a/drivers/sdio/stack/busdriver/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_SDIO) += sdio_busdriver.o
-sdio_busdriver-objs := sdio_bus.o sdio_function.o sdio_bus_misc.o sdio_bus_events.o sdio_bus_os.o
diff --git a/drivers/sdio/stack/busdriver/_busdriver.h b/drivers/sdio/stack/busdriver/_busdriver.h
deleted file mode 100644
index 28d3960c644..00000000000
--- a/drivers/sdio/stack/busdriver/_busdriver.h
+++ /dev/null
@@ -1,466 +0,0 @@
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-@file: _busdriver.h
-
-@abstract: internal include file for busdriver
-
-@notice: Copyright (c), 2004-2006 Atheros Communications, Inc.
-
-
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Portions of this code were developed with information supplied from the
- * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
- *
- * The following conditions apply to the release of the SD simplified specification (�Simplified
- * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
- * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
- * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
- * Specification may require a license from the SD Card Association or other third parties.
- * Disclaimers:
- * The information contained in the Simplified Specification is presented only as a standard
- * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
- * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
- * any damages, any infringements of patents or other right of the SD Card Association or any third
- * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
- * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
- * be construed as an obligation by the SD Card Association to disclose or distribute any technical
- * information, know-how or other confidential information to any third party.
- *
- *
- * The initial developers of the original code are Seung Yi and Paul Lever
- *
- * sdio@atheros.com
- *
- *
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-#ifndef ___BUSDRIVER_H___
-#define ___BUSDRIVER_H___
-#include <linux/sdio/sdio_lib.h>
-
-#define SDIODBG_FUNC_IRQ (SDDBG_TRACE + 1)
-#define SDIODBG_REQUESTS (SDDBG_TRACE + 2)
-#define SDIODBG_CD_TIMER (SDDBG_TRACE + 3)
-#define SDIODBG_HCD_EVENTS (SDDBG_TRACE + 4)
-
-#define SDIOBUS_CD_TIMER_ID 0
-
-#define SDBUS_MAX_RETRY 3
-
-/* Notes on list linkages:
- * list heads are held in BDCONTEXT
- * HcdList - SDHCD
- * one per registered host controller
- * Next - links of all HCDs
- * DeviceList SDDEVICE
- * one per inserted device
- * Next - links of all devices
- * DeviceListNext - links of all devices on a function
- * pFunction - ptr to Function supportting this device
- * pHcd - ptr to HCD with supporting this device
- * FunctionList SDFUNCTION
- * one per register function driver
- * Next - links of all functions
- * DeviceList - list of devices being support by this function
- * uses DeviceListNext in SDDEVICE to link
- *
- *
-*/
-
-#define SDMMC_DEFAULT_CMD_RETRIES 1
-#define SDMMC_DEFAULT_CARD_READY_RETRIES 200
-#define OCR_READY_CHECK_DELAY_MS 10
-#define SDMMC_POWER_SETTLE_DELAY 400 /* in milliseconds */
-#define SDBUS_DEFAULT_REQ_LIST_SIZE 16
-#define SDBUS_DEFAULT_REQ_SIG_SIZE 8
-#define CARD_DETECT_PAUSE 100
-#define SDBUS_DEFAULT_CD_POLLING_INTERVAL 1000 /* in milliseconds */
-#define MAX_CARD_DETECT_MSGS 16
-#define SDMMC_DEFAULT_BYTES_PER_BLOCK 2048
-#define SDMMC_DEFAULT_BLOCKS_PER_TRANS 512
-#define SDMMC_CMD13_POLLING_MULTIPLIER 1000 /* per block multiplier */
-#define MAX_HCD_REQ_RECURSION 5
-#define MAX_HCD_RECURSION_RUNAWAY 100
-
- /* internal signalling item */
-typedef struct _SIGNAL_ITEM{
- SDLIST SDList; /* list link*/
- OS_SIGNAL Signal; /* signal */
-}SIGNAL_ITEM, *PSIGNAL_ITEM;
-
-typedef struct _HCD_EVENT_MESSAGE {
- HCD_EVENT Event; /* the event */
- PSDHCD pHcd; /* hcd that generated the event */
-}HCD_EVENT_MESSAGE, *PHCD_EVENT_MESSAGE;
-
-/* internal data for bus driver */
-typedef struct _BDCONTEXT {
-
- /* list of SD requests and signalling semaphores and a semaphore to protect it */
- SDLIST RequestList;
- SDLIST SignalList;
- OS_CRITICALSECTION RequestListCritSection;
- /* list of host controller bus drivers, sempahore to protect it */
- SDLIST HcdList;
- OS_SEMAPHORE HcdListSem;
- /* list of inserted devices, semaphore to protect it */
- SDLIST DeviceList;
- OS_SEMAPHORE DeviceListSem;
- /* list of function drivers, semaphore to protect it */
- SDLIST FunctionList;
- OS_SEMAPHORE FunctionListSem;
- INT RequestListSize; /* default request list */
- INT SignalSemListSize; /* default signalling semaphore size */
- INT CurrentRequestAllocations; /*current count of allocated requests */
- INT CurrentSignalAllocations; /* current count of signal allocations */
- INT MaxRequestAllocations; /* max number of allocated requests to keep around*/
- INT MaxSignalAllocations; /* max number of signal allocations to keep around*/
- INT RequestRetries; /* cmd retries */
- INT CardReadyPollingRetry; /* card ready polling retry count */
- INT PowerSettleDelay; /* power settle delay */
- INT CMD13PollingMultiplier; /* CMD13 (GET STATUS) multiplier */
- SD_BUSCLOCK_RATE DefaultOperClock; /* default operation clock */
- SD_BUSMODE_FLAGS DefaultBusMode; /* default bus mode */
- UINT16 DefaultOperBlockLen; /* default operational block length per block */
- UINT16 DefaultOperBlockCount; /* default operational block count per transaction */
- UINT32 CDPollingInterval; /* card insert/removal polling interval */
- UINT8 InitMask; /* bus driver init mask */
-#define BD_TIMER_INIT 0x01
-#define HELPER_INIT 0x02
-#define RESOURCE_INIT 0x04
- BOOL CDTimerQueued; /* card detect timer queued */
- OSKERNEL_HELPER CardDetectHelper; /* card detect helper */
- PSDMESSAGE_QUEUE pCardDetectMsgQueue; /* card detect message queue */
- ULONG HcdInUseField; /* bit field of in use HCD numbers*/
- UINT32 ConfigFlags; /* bus driver configuration flags */
-#define BD_CONFIG_SDREQ_FORCE_ALL_ASYNC 0x00000001
- INT MaxHcdRecursion; /* max HCD recurion level */
-}BDCONTEXT, *PBDCONTEXT;
-
-#define BD_DEFAULT_CONFIG_FLAGS 0x00000000
-#define IsQueueBusy(pRequestQueue) (pRequestQueue)->Busy
-#define MarkQueueBusy(pRequestQueue) (pRequestQueue)->Busy = TRUE
-#define MarkQueueNotBusy(pRequestQueue) (pRequestQueue)->Busy = FALSE
-
-#define CLEAR_INTERNAL_REQ_FLAGS(pReq) (pReq)->Flags &= ~(UINT)((SDREQ_FLAGS_RESP_SPI_CONVERTED | \
- SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE))
-
-/* macros to insert request into the queue */
-#define QueueRequest(pReqQ,pReq) SDListInsertTail(&(pReqQ)->Queue,&(pReq)->SDList)
-#define QueueRequestToFront(pReqQ,pReq) SDListInsertHead(&(pReqQ)->Queue,&(pReq)->SDList)
-
-/* macros to remove an item from the head of the queue */
-static INLINE PSDREQUEST DequeueRequest(PSDREQUESTQUEUE pRequestQueue) {
- PSDLIST pItem;
- pItem = SDListRemoveItemFromHead(&pRequestQueue->Queue);
- if (pItem != NULL) {
- return CONTAINING_STRUCT(pItem, SDREQUEST, SDList);
- }
- return NULL;
-};
-
-static INLINE SDIO_STATUS InitializeRequestQueue(PSDREQUESTQUEUE pRequestQueue) {
- SDLIST_INIT(&pRequestQueue->Queue);
- MarkQueueNotBusy(pRequestQueue);
- return SDIO_STATUS_SUCCESS;
-}
-
-static INLINE void CleanupRequestQueue(PSDREQUESTQUEUE pRequestQueue) {
-
-}
-
-/* for bus driver internal use only */
-SDIO_STATUS _SDIO_BusDriverInitialize(void);
-SDIO_STATUS _SDIO_BusGetDefaultSettings(PBDCONTEXT pBdc);
-void _SDIO_BusDriverCleanup(void);
-SDIO_STATUS RemoveAllFunctions(void);
-SDIO_STATUS RemoveHcdFunctions(PSDHCD pHcd);
-PSDDEVICE AllocateDevice(PSDHCD pHcd);
-BOOL AddDeviceToList(PSDDEVICE pDevice);
-SDIO_STATUS DeleteDevices(PSDHCD pHcd);
-SDIO_STATUS NotifyDeviceRemove(PSDDEVICE pDevice);
-extern PBDCONTEXT pBusContext;
-extern const CT_VERSION_CODE g_Version;
-SDIO_STATUS _SDIO_RegisterHostController(PSDHCD pHcd);
-SDIO_STATUS _SDIO_UnregisterHostController(PSDHCD pHcd);
-SDIO_STATUS _SDIO_HandleHcdEvent(PSDHCD pHcd, HCD_EVENT Event);
-SDIO_STATUS _SDIO_RegisterFunction(PSDFUNCTION pFunction);
-SDIO_STATUS _SDIO_UnregisterFunction(PSDFUNCTION pFunction);
-SDIO_STATUS _SDIO_CheckResponse(PSDHCD pHcd, PSDREQUEST pReq, SDHCD_RESPONSE_CHECK_MODE CheckMode);
-SDIO_STATUS ProbeForFunction(PSDDEVICE pDevice, PSDHCD pHcd);
-SDIO_STATUS SDInitializeCard(PSDHCD pHcd);
-SDIO_STATUS SDQuerySDMMCInfo(PSDDEVICE pDevice);
-SDIO_STATUS SDQuerySDIOInfo(PSDDEVICE pDevice);
-SDIO_STATUS SDEnableFunction(PSDDEVICE pDevice, PSDCONFIG_FUNC_ENABLE_DISABLE_DATA pEnData);
-SDIO_STATUS SDAllocFreeSlotCurrent(PSDDEVICE pDevice, BOOL Allocate, PSDCONFIG_FUNC_SLOT_CURRENT_DATA pData);
-SDIO_STATUS SDMaskUnmaskFunctionIRQ(PSDDEVICE pDevice, BOOL Mask);
-SDIO_STATUS SDFunctionAckInterrupt(PSDDEVICE pDevice);
-SDIO_STATUS SDSPIModeEnableDisableCRC(PSDDEVICE pDevice,BOOL Enable);
-SDIO_STATUS IssueBusConfig(PSDDEVICE pDev, PSDCONFIG pConfig);
-SDIO_STATUS IssueBusRequest(PSDDEVICE pDev, PSDREQUEST pReq);
-PSDREQUEST IssueAllocRequest(PSDDEVICE pDev);
-void IssueFreeRequest(PSDDEVICE pDev, PSDREQUEST pReq);
-PSDREQUEST AllocateRequest(void);
-void FreeRequest(PSDREQUEST pReq);
-PSIGNAL_ITEM AllocateSignal(void);
-void FreeSignal(PSIGNAL_ITEM pSignal);
-SDIO_STATUS InitializeTimers(void);
-SDIO_STATUS CleanupTimers(void);
-SDIO_STATUS QueueTimer(INT TimerID, UINT32 TimeOut);
-SDIO_STATUS DeviceAttach(PSDHCD pHcd);
-SDIO_STATUS DeviceDetach(PSDHCD pHcd);
-SDIO_STATUS DeviceInterrupt(PSDHCD pHcd);
-SDIO_STATUS CardInitSetup(PSDHCD pHcd);
-void RunCardDetect(void);
-void SDIO_NotifyTimerTriggered(INT TimerID);
-SDIO_STATUS TestPresence(PSDHCD pHcd,
- CARD_INFO_FLAGS TestType,
- PSDREQUEST pReq);
-#define _IssueSimpleBusRequest(pHcd,Cmd,Arg,Flags,pReqToUse) \
- _IssueBusRequestBd((pHcd),(Cmd),(Arg),(Flags),(pReqToUse),NULL,0)
-
-SDIO_STATUS Do_OS_IncHcdReference(PSDHCD pHcd);
-SDIO_STATUS Do_OS_DecHcdReference(PSDHCD pHcd);
-SDIO_STATUS TryNoIrqPendingCheck(PSDDEVICE pDev);
-
- /* check API version compatibility of an HCD or function driver to a stack major/minor version
- if the driver version is greater than the major number, we are compatible
- if the driver version is equal, then we check if the minor is greater than or equal
- we don't have to check for the less than major, because the bus driver never loads
- drivers with different major numbers ...
- if the busdriver compiled version major is greater than the major version being checked this
- macro will resolved to ALWAYS true thus optimizing the code to not check the HCD since
- as a rule we never load an HCD with a lower major number */
-#define CHECK_API_VERSION_COMPAT(p,major,minor) \
- ((CT_SDIO_STACK_VERSION_MAJOR(CT_SDIO_STACK_VERSION_CODE) > (major)) || \
- (GET_SDIO_STACK_VERSION_MINOR((p)) >= (minor)))
-
-static INLINE SDIO_STATUS OS_IncHcdReference(PSDHCD pHcd) {
- /* this API was added in version 2.3 which requires access to a field in the HCD structure */
- if (CHECK_API_VERSION_COMPAT(pHcd,2,3)) {
- /* we can safely call the OS-dependent function */
- return Do_OS_IncHcdReference(pHcd);
- }
- return SDIO_STATUS_SUCCESS;
-}
-
-static INLINE SDIO_STATUS OS_DecHcdReference(PSDHCD pHcd) {
- /* this API was added in version 2.3 which requires access to a field in the HCD structure */
- if (CHECK_API_VERSION_COMPAT(pHcd,2,3)) {
- /* we can safely call the OS-dependent function */
- return Do_OS_DecHcdReference(pHcd);
- }
- return SDIO_STATUS_SUCCESS;
-}
-
-SDIO_STATUS _IssueBusRequestBd(PSDHCD pHcd,
- UINT8 Cmd,
- UINT32 Argument,
- SDREQUEST_FLAGS Flags,
- PSDREQUEST pReqToUse,
- PVOID pData,
- INT Length);
-
-SDIO_STATUS IssueRequestToHCD(PSDHCD pHcd,PSDREQUEST pReq);
-
-#define CALL_HCD_CONFIG(pHcd,pCfg) (pHcd)->pConfigure((pHcd),(pCfg))
- /* macro to force all requests to be asynchronous in the HCD */
-static INLINE BOOL ForceAllRequestsAsync(void) {
- return (pBusContext->ConfigFlags & BD_CONFIG_SDREQ_FORCE_ALL_ASYNC);
-}
-
-static INLINE SDIO_STATUS CallHcdRequest(PSDHCD pHcd) {
-
- if (pHcd->pCurrentRequest->Flags & SDREQ_FLAGS_PSEUDO) {
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: PSEUDO Request 0x%X \n",
- (INT)pHcd->pCurrentRequest));
- /* return successful completion so that processing can finish */
- return SDIO_STATUS_SUCCESS;
- }
-
- if (ForceAllRequestsAsync()) {
- /* all requests must be completed(indicated) in a separate context */
- pHcd->pCurrentRequest->Flags |= SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE;
- } else {
- /* otherwise perform a test on flags in the HCD */
- if (!CHECK_API_VERSION_COMPAT(pHcd,2,6) &&
- AtomicTest_Set(&pHcd->HcdFlags, HCD_REQUEST_CALL_BIT)) {
-
- /* bit was already set, this is a recursive call,
- * we need to tell the HCD to complete the
- * request in a separate context */
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Recursive CallHcdRequest \n"));
- pHcd->pCurrentRequest->Flags |= SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE;
- }
- }
- #ifdef DEBUG
- {
- SDIO_STATUS status;
- BOOL forceDeferred;
- forceDeferred = pHcd->pCurrentRequest->Flags & SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE;
- status = pHcd->pRequest(pHcd);
- if (forceDeferred) {
- /* status better be pending... */
- DBG_ASSERT(status == SDIO_STATUS_PENDING);
- }
- return status;
- }
- #else
- return pHcd->pRequest(pHcd);
- #endif
-
-}
-
-/* note the caller of this macro must take the HCD lock to protect the count */
-#define CHECK_HCD_RECURSE(pHcd,pReq) \
-{ \
- (pHcd)->Recursion++; \
- DBG_ASSERT((pHcd)->Recursion < MAX_HCD_RECURSION_RUNAWAY); \
- if ((pHcd)->Recursion > pBusContext->MaxHcdRecursion) { \
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Recursive Request Count Exceeded (%d) \n",(pHcd)->Recursion)); \
- (pReq)->Flags |= SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE; \
- } \
-}
-
-/* InternalFlags bit number settings */
-#define SDBD_INIT 1
-#define SDBD_PENDING 15
-#define SDBD_ALLOC_IRQ_SAFE 2
-
-#define SDBD_ALLOC_IRQ_SAFE_MASK (1 << SDBD_ALLOC_IRQ_SAFE)
-
-static void INLINE DoRequestCompletion(PSDREQUEST pReq, PSDHCD pHcd) {
- CLEAR_INTERNAL_REQ_FLAGS(pReq);
- if (pReq->pCompletion != NULL) {
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Calling completion on request:0x%X, CMD:%d \n",
- (INT)pReq, pReq->Command));
- /* call completion routine, mark request reusable */
- AtomicTest_Clear(&pReq->InternalFlags, SDBD_PENDING);
- pReq->pCompletion(pReq);
- } else {
- /* mark request reusable */
- AtomicTest_Clear(&pReq->InternalFlags, SDBD_PENDING);
- }
-}
-
-THREAD_RETURN CardDetectHelperFunction(POSKERNEL_HELPER pHelper);
-THREAD_RETURN SDIOIrqHelperFunction(POSKERNEL_HELPER pHelper);
-
-void ConvertSPI_Response(PSDREQUEST pReq, UINT8 *pRespBuffer);
-
-static INLINE SDIO_STATUS PostCardDetectEvent(PBDCONTEXT pSDB, HCD_EVENT Event, PSDHCD pHcd) {
- HCD_EVENT_MESSAGE message;
- SDIO_STATUS status;
- message.Event = Event;
- message.pHcd = pHcd;
-
- if (pHcd != NULL) {
- /* increment HCD reference count to process this HCD message */
- status = OS_IncHcdReference(pHcd);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
- }
- /* post card detect message */
- status = SDLIB_PostMessage(pSDB->pCardDetectMsgQueue, &message, sizeof(message));
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: PostCardDetectEvent error status %d\n",status));
- if (pHcd != NULL) {
- /* decrement count */
- OS_DecHcdReference(pHcd);
- }
- return status;
- }
- /* wake card detect helper */
- DBG_PRINT(SDIODBG_HCD_EVENTS, ("SDIO Bus Driver: PostCardDetectEvent waking\n"));
- return SD_WAKE_OS_HELPER(&pSDB->CardDetectHelper);
-};
-
-/* initialize device fields */
-static INLINE void InitDeviceData(PSDHCD pHcd, PSDDEVICE pDevice) {
- ZERO_POBJECT(pDevice);
- SDLIST_INIT(&pDevice->SDList);
- SDLIST_INIT(&pDevice->FuncListLink);
- pDevice->pRequest = IssueBusRequest;
- pDevice->pConfigure = IssueBusConfig;
- pDevice->AllocRequest = IssueAllocRequest;
- pDevice->FreeRequest = IssueFreeRequest;
- /* set card flags in the ID */
- pDevice->pId[0].CardFlags = pHcd->CardProperties.Flags;
- pDevice->pFunction = NULL;
- pDevice->pHcd = pHcd;
- SET_SDIO_STACK_VERSION(pDevice);
-}
-
-/* de-initialize device fields */
-static INLINE void DeinitDeviceData(PSDDEVICE pDevice) {
-}
-
-/* reset hcd state */
-static INLINE void ResetHcdState(PSDHCD pHcd) {
- ZERO_POBJECT(&pHcd->CardProperties);
- pHcd->PendingHelperIrqs = 0;
- pHcd->PendingIrqAcks = 0;
- pHcd->IrqsEnabled = 0;
- pHcd->pCurrentRequest = NULL;
- pHcd->IrqProcState = SDHCD_IDLE;
- /* mark this device as special */
- pHcd->pPseudoDev->pId[0].CardFlags = CARD_PSEUDO;
- pHcd->SlotCurrentAllocated = 0;
-}
-
-static INLINE SDIO_STATUS _IssueConfig(PSDHCD pHcd,
- SDCONFIG_COMMAND Command,
- PVOID pData,
- INT Length){
- SDCONFIG configHdr;
- SET_SDCONFIG_CMD_INFO(&configHdr,Command,pData,Length);
- return CALL_HCD_CONFIG(pHcd,&configHdr);
-}
-
-/* prototypes */
-#define _AcquireHcdLock(pHcd)CriticalSectionAcquireSyncIrq(&(pHcd)->HcdCritSection)
-#define _ReleaseHcdLock(pHcd)CriticalSectionReleaseSyncIrq(&(pHcd)->HcdCritSection)
-
-#define AcquireHcdLock(pDev) CriticalSectionAcquireSyncIrq(&(pDev)->pHcd->HcdCritSection)
-#define ReleaseHcdLock(pDev) CriticalSectionReleaseSyncIrq(&(pDev)->pHcd->HcdCritSection)
-
-SDIO_STATUS OS_AddDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction);
-void OS_RemoveDevice(PSDDEVICE pDevice);
-SDIO_STATUS OS_InitializeDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction);
-SDIO_STATUS SetOperationalBusMode(PSDDEVICE pDevice,
- PSDCONFIG_BUS_MODE_DATA pBusMode);
-void FreeDevice(PSDDEVICE pDevice);
-BOOL IsPotentialIdMatch(PSD_PNP_INFO pIdsDev, PSD_PNP_INFO pIdsFuncList);
-
-
-#define CHECK_FUNCTION_DRIVER_VERSION(pF) \
- (GET_SDIO_STACK_VERSION_MAJOR((pF)) == CT_SDIO_STACK_VERSION_MAJOR(g_Version))
-#define CHECK_HCD_DRIVER_VERSION(pH) \
- (GET_SDIO_STACK_VERSION_MAJOR((pH)) == CT_SDIO_STACK_VERSION_MAJOR(g_Version))
-
-/* CLARIFICATION on SDREQ_FLAGS_PSEUDO and SDREQ_FLAGS_BARRIER flags :
- *
- * A request marked as PSEUDO is synchronized with bus requests and is not a true request
- * that is issued to an HCD.
- *
- * A request marked with a BARRIER flag requires that the completion routine be called
- * before the next bus request starts. This is required for HCD requests that can change
- * bus or clock modes. Changing the clock or bus mode while a bus request is pending
- * can cause problems.
- *
- *
- *
- * */
-#define SD_PSEUDO_REQ_FLAGS \
- (SDREQ_FLAGS_PSEUDO | SDREQ_FLAGS_BARRIER | SDREQ_FLAGS_TRANS_ASYNC)
-
-#endif /*___BUSDRIVER_H___*/
diff --git a/drivers/sdio/stack/busdriver/sdio_bus.c b/drivers/sdio/stack/busdriver/sdio_bus.c
deleted file mode 100644
index ffc1e9f958d..00000000000
--- a/drivers/sdio/stack/busdriver/sdio_bus.c
+++ /dev/null
@@ -1,2120 +0,0 @@
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-@file: sdio_bus.c
-
-@abstract: OS independent bus driver support
-@category abstract: HD_Reference Host Controller Driver Interfaces.
-@category abstract: PD_Reference
- Peripheral Driver Interfaces.
-
-#notes: this file supports the HCD's and generic functions
-
-@notice: Copyright (c), 2004-2006 Atheros Communications, Inc.
-
-
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Portions of this code were developed with information supplied from the
- * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
- *
- * The following conditions apply to the release of the SD simplified specification (�Simplified
- * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
- * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
- * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
- * Specification may require a license from the SD Card Association or other third parties.
- * Disclaimers:
- * The information contained in the Simplified Specification is presented only as a standard
- * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
- * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
- * any damages, any infringements of patents or other right of the SD Card Association or any third
- * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
- * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
- * be construed as an obligation by the SD Card Association to disclose or distribute any technical
- * information, know-how or other confidential information to any third party.
- *
- *
- * The initial developers of the original code are Seung Yi and Paul Lever
- *
- * sdio@atheros.com
- *
- *
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-#define MODULE_NAME SDBUSDRIVER
-#include <linux/sdio/ctsystem.h>
-#include <linux/sdio/sdio_busdriver.h>
-#include <linux/sdio/_sdio_defs.h>
-#include <linux/sdio/sdio_lib.h>
-#include <linux/sdio/mmc_defs.h>
-#include "_busdriver.h"
-
-/* list of host controller bus drivers */
-PBDCONTEXT pBusContext = NULL;
-static void CleanUpBusResources(void);
-static SDIO_STATUS AllocateBusResources(void);
-static PSIGNAL_ITEM BuildSignal(void);
-static void DestroySignal(PSIGNAL_ITEM pSignal);
-
-const CT_VERSION_CODE g_Version = CT_SDIO_STACK_VERSION_CODE;
-/*
- * _SDIO_BusDriverInitialize - call once on driver loading
- *
-*/
-SDIO_STATUS _SDIO_BusDriverInitialize(void)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Version: %d.%d\n",
- CT_SDIO_STACK_VERSION_MAJOR(g_Version),CT_SDIO_STACK_VERSION_MINOR(g_Version)));
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: enter _SDIO_BusDriverInitialize\n"));
-
- do {
- /* allocate our internal data initialize it */
- pBusContext = KernelAlloc(sizeof(BDCONTEXT));
- if (pBusContext == NULL) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't allocate memory.\n"));
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
- memset(pBusContext,0,sizeof(BDCONTEXT));
- SDLIST_INIT(&pBusContext->RequestList);
- SDLIST_INIT(&pBusContext->HcdList);
- SDLIST_INIT(&pBusContext->DeviceList);
- SDLIST_INIT(&pBusContext->FunctionList);
- SDLIST_INIT(&pBusContext->SignalList);
-
- /* setup defaults */
- pBusContext->RequestRetries = SDMMC_DEFAULT_CMD_RETRIES;
- pBusContext->CardReadyPollingRetry = SDMMC_DEFAULT_CARD_READY_RETRIES;
- pBusContext->PowerSettleDelay = SDMMC_POWER_SETTLE_DELAY;
- pBusContext->DefaultOperClock = MMC_HS_MAX_BUS_CLOCK;
- pBusContext->DefaultBusMode = SDCONFIG_BUS_WIDTH_4_BIT;
- pBusContext->RequestListSize = SDBUS_DEFAULT_REQ_LIST_SIZE;
- pBusContext->SignalSemListSize = SDBUS_DEFAULT_REQ_SIG_SIZE;
- pBusContext->CDPollingInterval = SDBUS_DEFAULT_CD_POLLING_INTERVAL;
- pBusContext->DefaultOperBlockLen = SDMMC_DEFAULT_BYTES_PER_BLOCK;
- pBusContext->DefaultOperBlockCount = SDMMC_DEFAULT_BLOCKS_PER_TRANS;
- pBusContext->ConfigFlags = BD_DEFAULT_CONFIG_FLAGS;
- pBusContext->CMD13PollingMultiplier = SDMMC_CMD13_POLLING_MULTIPLIER;
- pBusContext->MaxHcdRecursion = MAX_HCD_REQ_RECURSION;
-
- /* get overrides for the defaults */
- status = _SDIO_BusGetDefaultSettings(pBusContext);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
-
- pBusContext->MaxRequestAllocations = pBusContext->RequestListSize << 1;
- pBusContext->MaxSignalAllocations = pBusContext->SignalSemListSize << 1;
-
- status = CriticalSectionInit(&pBusContext->RequestListCritSection);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't CriticalSectionInit.\n"));
- break;
- }
- status = SemaphoreInitialize(&pBusContext->HcdListSem, 1);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't SemaphoreInitialize HcdListSem.\n"));
- break;
- }
- status = SemaphoreInitialize(&pBusContext->DeviceListSem, 1);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't SemaphoreInitialize DeviceListSem.\n"));
- break;
- }
- status = SemaphoreInitialize(&pBusContext->FunctionListSem, 1);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't SemaphoreInitialize FunctionListSem.\n"));
- break;
- }
- status = AllocateBusResources();
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't AllocateBusResources.\n"));
- break;
- }
-
- pBusContext->InitMask |= RESOURCE_INIT;
-
- pBusContext->pCardDetectMsgQueue = SDLIB_CreateMessageQueue(MAX_CARD_DETECT_MSGS,
- sizeof(HCD_EVENT_MESSAGE));
-
- if (NULL == pBusContext->pCardDetectMsgQueue) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't CreateMessageQueue.\n"));
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
-
- status = SDLIB_OSCreateHelper(&pBusContext->CardDetectHelper,
- CardDetectHelperFunction,
- NULL);
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't OSCreateHelper.\n"));
- break;
- }
-
- pBusContext->InitMask |= HELPER_INIT;
-
- status = InitializeTimers();
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't InitializeTimers.\n"));
- break;
- }
- pBusContext->InitMask |= BD_TIMER_INIT;
- } while(FALSE);
-
- if (!SDIO_SUCCESS(status)) {
- _SDIO_BusDriverCleanup();
- }
-
- return status;
-}
-
-
-/*
- * _SDIO_BusDriverBusDriverCleanup - call once on driver unloading
- *
-*/
-void _SDIO_BusDriverCleanup(void) {
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: _SDIO_BusDriverCleanup\n"));
-
- if (pBusContext->InitMask & BD_TIMER_INIT) {
- CleanupTimers();
- }
-
- if (pBusContext->InitMask & HELPER_INIT) {
- SDLIB_OSDeleteHelper(&pBusContext->CardDetectHelper);
- }
-
- if (pBusContext->pCardDetectMsgQueue != NULL) {
- SDLIB_DeleteMessageQueue(pBusContext->pCardDetectMsgQueue);
- pBusContext->pCardDetectMsgQueue = NULL;
- }
- /* remove functions */
- RemoveAllFunctions();
- /* cleanup all devices */
- DeleteDevices(NULL);
- CleanUpBusResources();
- CriticalSectionDelete(&pBusContext->RequestListCritSection);
- SemaphoreDelete(&pBusContext->HcdListSem);
- SemaphoreDelete(&pBusContext->DeviceListSem);
- SemaphoreDelete(&pBusContext->FunctionListSem);
- KernelFree(pBusContext);
- pBusContext = NULL;
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: _SDIO_BusDriverCleanup\n"));
-}
-
-
-/* cleanup hcd */
-static void CleanupHcd(PSDHCD pHcd)
-{
- SDLIB_OSDeleteHelper(&pHcd->SDIOIrqHelper);
- CleanupRequestQueue(&pHcd->CompletedRequestQueue);
- CleanupRequestQueue(&pHcd->RequestQueue);
- CriticalSectionDelete(&pHcd->HcdCritSection);
- SemaphoreDelete(&pHcd->ConfigureOpsSem);
- pHcd->pCurrentRequest = NULL;
- if (pHcd->pPseudoDev != NULL) {
- FreeDevice(pHcd->pPseudoDev);
- pHcd->pPseudoDev = NULL;
- }
-}
-
-/* set up the hcd */
-static SDIO_STATUS SetupHcd(PSDHCD pHcd)
-{
- SDIO_STATUS status;
-
- ZERO_POBJECT(&pHcd->SDIOIrqHelper);
- ZERO_POBJECT(&pHcd->ConfigureOpsSem);
- ZERO_POBJECT(&pHcd->HcdCritSection);
- ZERO_POBJECT(&pHcd->RequestQueue);
- ZERO_POBJECT(&pHcd->CompletedRequestQueue);
- pHcd->pPseudoDev = NULL;
- pHcd->Recursion = 0;
-
- do {
-
- pHcd->pPseudoDev = AllocateDevice(pHcd);
-
- if (NULL == pHcd->pPseudoDev) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
-
- ResetHcdState(pHcd);
-
- status = SemaphoreInitialize(&pHcd->ConfigureOpsSem,1);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- status = CriticalSectionInit(&pHcd->HcdCritSection);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- status = InitializeRequestQueue(&pHcd->RequestQueue);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- status = InitializeRequestQueue(&pHcd->CompletedRequestQueue);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- /* create SDIO Irq helper */
- status = SDLIB_OSCreateHelper(&pHcd->SDIOIrqHelper,
- SDIOIrqHelperFunction,
- (PVOID)pHcd);
- } while(FALSE);
-
- if (!SDIO_SUCCESS(status)) {
- /* undo what we did */
- CleanupHcd(pHcd);
- }
- return status;
-}
-
-
-/*
- * _SDIO_RegisterHostController - register a host controller bus driver
- *
-*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Register a host controller driver with the bus driver.
-
- @function name: SDIO_RegisterHostController
- @prototype: SDIO_STATUS SDIO_RegisterHostController (PSDHCD pHcd)
- @category: HD_Reference
-
- @input: pHcd - the host controller definition structure.
-
- @output: none
-
- @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when successful.
-
- @notes: Each host controller driver must register with the bus driver when loaded.
- The driver registers an SDHCD structure initialized with hardware properties
- and callback functions for bus requests and configuration. On multi-slot
- hardware ,each slot should be registered with a separate SDHCD structure.
- The bus driver views each slot as a seperate host controller object.
- The driver should be prepared to receive configuration requests before
- this call returns. The host controller driver must unregister itself when
- shutting down.
-
- @example: Registering a host controller driver:
- static SDHCD Hcd = {
- .pName = "sdio_custom_hcd",
- .Version = CT_SDIO_STACK_VERSION_CODE, // set stack version code
- .SlotNumber = 0, // bus driver internal use
- .Attributes = SDHCD_ATTRIB_BUS_1BIT | SDHCD_ATTRIB_BUS_4BIT | SDHCD_ATTRIB_MULTI_BLK_IRQ
- SDHCD_ATTRIB_AUTO_CMD12 ,
- .MaxBytesPerBlock = 2048 // each data block can be up to 2048 bytes
- .MaxBlocksPerTrans = 1024, // each data transaction can consist of 1024 blocks
- .MaxSlotCurrent = 500, // max FET switch current rating
- .SlotVoltageCaps = SLOT_POWER_3_3V, // only 3.3V operation
- .SlotVoltagePreferred = SLOT_POWER_3_3V,
- .MaxClockRate = 24000000, // 24 Mhz max operation
- .pContext = &HcdContext, // set our driver context
- .pRequest = HcdRequest, // set SDIO bus request callback
- .pConfigure = HcdConfig, // set SDIO bus configuration callback
- };
- if (!SDIO_SUCCESS((status = SDIO_RegisterHostController(&Hcd)))) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO HCD - failed to register with host, status =%d\n",
- status));
- }
-
- @see also: SDIO_UnregisterHostController
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDIO_RegisterHostController(PSDHCD pHcd) {
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: _SDIO_RegisterHostController - %s\n",pHcd->pName));
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: Host Controller Stack Version: %d.%d \n",
- GET_SDIO_STACK_VERSION_MAJOR(pHcd),GET_SDIO_STACK_VERSION_MINOR(pHcd)));
-
- if (!CHECK_HCD_DRIVER_VERSION(pHcd)) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: HCD Major Version Mismatch (hcd = %d, bus driver = %d)\n",
- GET_SDIO_STACK_VERSION_MAJOR(pHcd), CT_SDIO_STACK_VERSION_MAJOR(g_Version)));
- return SDIO_STATUS_INVALID_PARAMETER;
- }
- /* setup hcd */
- status = SetupHcd(pHcd);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
-
- do {
- INT slotNumber;
-
- /* protect the HCD list */
- if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->HcdListSem)))) {
- break; /* wait interrupted */
- }
- /* find a unique number for this HCD, must be done under semaphore protection */
- slotNumber = FirstClearBit(&pBusContext->HcdInUseField);
- if (slotNumber < 0) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_RegisterHostController, error, slotNumber exceeded\n"));
- /* fake something */
- slotNumber = 31;
- }
- SetBit(&pBusContext->HcdInUseField, slotNumber);
- pHcd->SlotNumber = slotNumber;
- /* add HCD to the end of the internal list */
- SDListAdd(&pBusContext->HcdList , &pHcd->SDList);
- if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->HcdListSem)))) {
- break; /* wait interrupted */
- }
- if (pHcd->Attributes & SDHCD_ATTRIB_SLOT_POLLING) {
- /* post message to card detect helper to do polling */
- PostCardDetectEvent(pBusContext, EVENT_HCD_CD_POLLING, NULL);
- }
- } while (FALSE);
-
- if (!SDIO_SUCCESS(status)) {
- CleanupHcd(pHcd);
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_RegisterHostController, error 0x%X.\n", status));
- }
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: _SDIO_RegisterHostController\n"));
- return status;
-}
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Unregister a host controller driver with the bus driver.
-
- @function name: SDIO_UnregisterHostController
- @prototype: SDIO_STATUS SDIO_UnregisterHostController (PSDHCD pHcd)
- @category: HD_Reference
-
- @input: pHcd - the host controller definition structure that was registered.
-
- @output: none
-
- @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when successful.
-
- @notes: Each host controller driver must unregister with the bus driver when
- unloading. The driver is responsible for halting any outstanding I/O
- operations. The bus driver will automatically unload function drivers
- that may be attached assigned to cards inserted into slots.
-
- @example: Unregistering a host controller driver:
- if (!SDIO_SUCCESS((status = SDIO_UnregisterHostController(&Hcd)))) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO HCD - failed to unregister with host, status =%d\n",
- status));
- }
-
- @see also: SDIO_RegisterHostController
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDIO_UnregisterHostController(PSDHCD pHcd) {
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: _SDIO_UnregisterHostController\n"));
-
- /* remove functions associated with the HCD */
- RemoveHcdFunctions(pHcd);
- /* remove any devices associated with the HCD */
- DeleteDevices(pHcd);
- /* wait for the message queue to be empty, so we don't have any delayed requests going
- to this device */
- while(!SDLIB_IsQueueEmpty(pBusContext->pCardDetectMsgQueue)) {
- /* wait for the messages to be handled */
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: _SDIO_UnregisterHostController, waiting on messages\n"));
- OSSleep(250);
- }
-
- /* protect the HCD list */
- if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->HcdListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- ClearBit(&pBusContext->HcdInUseField, pHcd->SlotNumber);
- /* delete HCD from list */
- SDListRemove(&pHcd->SDList);
- if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->HcdListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- /* cleanup anything we allocated */
- CleanupHcd(pHcd);
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: _SDIO_UnregisterHostController\n"));
- return status;
-cleanup:
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_UnregisterHostController, error 0x%X.\n", status));
- return status;
-}
-
-/* documentation headers only for Request and Configure */
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: The bus driver calls the request callback to start an SDIO bus transaction.
- @function name: Request
- @prototype: SDIO_STATUS (*pRequest) (struct _SDHCD *pHcd)
- @category: HD_Reference
-
- @input: pHcd - the host controller structure that was registered
-
- @output: none
-
- @return: SDIO_STATUS
-
- @notes:
- The bus driver maintains an internal queue of SDREQUEST structures submited by function
- drivers. The driver should use request macros to obtain a pointer to the current SDREQUEST
- at the head of the queue. The driver can access the fields of the current request in order
- to program hardware appropriately. Once the request completes, the driver should update
- the current request information (final status, response bytes and/or data) and call
- SDIO_HandleHcdEvent() with the event type of EVENT_HCD_TRANSFER_DONE.
- The bus driver will remove the current request from the head of the queue and start the next
- request.
-
- @example: Example of a typical Request callback:
- SDIO_STATUS HcdRequest(PSDHCD pHcd)
- {
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDHCD_DRIVER_CONTEXT pHct = (PSDHCD_DRIVER_CONTEXT)pHcd->pContext;
- UINT32 temp = 0;
- PSDREQUEST pReq;
- // get the current request
- pReq = GET_CURRENT_REQUEST(pHcd);
- DBG_ASSERT(pReq != NULL);
- // get controller settings based on response type
- switch (GET_SDREQ_RESP_TYPE(pReq->Flags)) {
- case SDREQ_FLAGS_NO_RESP:
- break;
- case SDREQ_FLAGS_RESP_R1:
- case SDREQ_FLAGS_RESP_MMC_R4:
- case SDREQ_FLAGS_RESP_MMC_R5:
- case SDREQ_FLAGS_RESP_R6:
- case SDREQ_FLAGS_RESP_SDIO_R5:
- temp |= CMDDAT_RES_R1_R4_R5;
- break;
- case SDREQ_FLAGS_RESP_R1B:
- temp |= (CMDDAT_RES_R1_R4_R5 | CMDAT_RES_BUSY);
- break;
- case SDREQ_FLAGS_RESP_R2:
- temp |= CMDDAT_RES_R2;
- break;
- case SDREQ_FLAGS_RESP_R3:
- case SDREQ_FLAGS_RESP_SDIO_R4:
- temp |= CMDDAT_RES_R3;
- break;
- }
- // check for data
- if (pReq->Flags & SDREQ_FLAGS_DATA_TRANS){
- temp |= CMDDAT_DATA_EN;
- // set data remaining count
- pReq->DataRemaining = pReq->BlockLen * pReq->BlockCount;
- DBG_PRINT(TRACE_DATA, ("SDIO %s Data Transfer, Blocks:%d, BlockLen:%d, Total:%d \n",
- IS_SDREQ_WRITE_DATA(pReq->Flags) ? "TX":"RX",
- pReq->BlockCount, pReq->BlockLen, pReq->DataRemaining));
- if (IS_SDREQ_WRITE_DATA(pReq->Flags)) {
- // write operation
- }
- }
- // .... program hardware, interrupt handler will complete request
- return SDIO_STATUS_PENDING;
- }
-
- @see also: SDIO_HandleHcdEvent
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: The bus driver calls the configure callback to set various options
- and modes in the host controller hardware.
-
- @function name: Configure
- @prototype: SDIO_STATUS (*pConfigure) (struct _SDHCD *pHcd, PSDCONFIG pConfig)
- @category: HD_Reference
-
- @input: pHcd - the host controller structure that was registered
- @input: pConfig - configuration request structure
-
- @output: none
-
- @return: SDIO_STATUS
-
- @notes:
- The host controller driver recieves configuration requests for options
- such as slot voltage, bus width, clock rates and interrupt detection.
- The bus driver guarantees that only one configuration option request
- can be issued at a time.
-
- @example: Example of a typical configure callback:
- SDIO_STATUS HcdConfig(PSDHCD pHcd, PSDCONFIG pConfig)
- {
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDHCD_DRIVER_CONTEXT pHct = (PSDHCD_DRIVER_CONTEXT)pHcd->pContext;
- UINT16 command;
- // get command
- command = GET_SDCONFIG_CMD(pConfig);
- // decode command
- switch (command){
- case SDCONFIG_GET_WP:
- if (GetGpioPinLevel(pHct,SDIO_CARD_WP_GPIO) == WP_POLARITY) {
- *((SDCONFIG_WP_VALUE *)pConfig->pData) = 1;
- } else {
- *((SDCONFIG_WP_VALUE *)pConfig->pData) = 0;
- }
- break;
- case SDCONFIG_SEND_INIT_CLOCKS:
- ClockStartStop(pHct,CLOCK_ON);
- // sleep a little, should be at least 80 clocks at our lowest clock setting
- status = OSSleep(100);
- ClockStartStop(pHct,CLOCK_OFF);
- break;
- case SDCONFIG_SDIO_INT_CTRL:
- if (GET_SDCONFIG_CMD_DATA(PSDCONFIG_SDIO_INT_CTRL_DATA,pConfig)->SlotIRQEnable) {
- // request to enable IRQ detection
- } else {
- // request to disable IRQ detectioon
- }
- break;
- case SDCONFIG_SDIO_REARM_INT:
- // request to re-arm the card IRQ detection logic
- break;
- case SDCONFIG_BUS_MODE_CTRL:
- // request to set bus mode
- {
- // get bus mode data structure
- PSDCONFIG_BUS_MODE_DATA pBusMode =
- GET_SDCONFIG_CMD_DATA(PSDCONFIG_SDIO_INT_CTRL_DATA,pConfig);
- // set bus mode based on settings in bus mode structure
- // bus mode : pBusMode->BusModeFlags
- // clock rate : pBusMode->ClockRate
- }
- break;
- case SDCONFIG_POWER_CTRL:
- // request to set power/voltage
- {
- PSDCONFIG_POWER_CTRL_DATA pPowerSetting =
- GET_SDCONFIG_CMD_DATA(PSDCONFIG_POWER_CTRL_DATA,pConfig);
- if (pPowerSetting->SlotPowerEnable) {
- // turn on slot power
- //
- } else {
- // turn off slot power
- }
- DBG_PRINT(PXA_TRACE_CONFIG, ("SDIO PXA255 PwrControl: En:%d, VCC:0x%X \n",
- pPowerSetting->SlotPowerEnable,
- pPowerSetting->SlotPowerVoltageMask));
- }
- break;
- default:
- // unsupported
- status = SDIO_STATUS_INVALID_PARAMETER;
- }
- return status;
- }
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-
-/*
- * Allocate a Device instance
- */
-PSDDEVICE AllocateDevice(PSDHCD pHcd)
-{
- PSDDEVICE pDevice;
-
- pDevice = KernelAlloc(sizeof(SDDEVICE));
- if (pDevice != NULL) {
- InitDeviceData(pHcd,pDevice);
- }
- return pDevice;
-}
-
-
-/*
- * Free a Device instance
- */
-void FreeDevice(PSDDEVICE pDevice)
-{
- DeinitDeviceData(pDevice);
- KernelFree(pDevice);
-}
-/*
- * add this device to the list
- */
-BOOL AddDeviceToList(PSDDEVICE pDevice)
-{
- BOOL success = FALSE;
-
- do {
- /* protect the driver list */
- if (!SDIO_SUCCESS(SemaphorePendInterruptable(&pBusContext->DeviceListSem))) {
- break; /* wait interrupted */
- }
-
- /* add new device to the internal list */
- SDListAdd(&pBusContext->DeviceList , &pDevice->SDList);
-
- if (!SDIO_SUCCESS(SemaphorePost(&pBusContext->DeviceListSem))) {
- break;
- }
-
- success = TRUE;
- } while (FALSE);
-
- return success;
-}
-
-/*
- * Delete device associated with the HCD
- * if pHCD is NULL this function cleans up all devices, the caller
- * better have cleaned up functions first!
- */
-SDIO_STATUS DeleteDevices(PSDHCD pHcd)
-{
- SDIO_STATUS status;
- PSDDEVICE pDevice;
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: DeleteDevices hcd:0x%X \n", (INT)pHcd));
- /* protect the device list */
- if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->DeviceListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- SDITERATE_OVER_LIST_ALLOW_REMOVE(&pBusContext->DeviceList,pDevice,SDDEVICE,SDList) {
- /* only remove devices for the hcd or if we are cleaning up all */
- if ((NULL == pHcd) || (pDevice->pHcd == pHcd)) {
- SDListRemove(&pDevice->SDList);
- DeinitDeviceData(pDevice);
- FreeDevice(pDevice);
- }
- }SDITERATE_END;
- if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->DeviceListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: DeleteDevices \n"));
- return status;
-cleanup:
- DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: DeleteDevice, error exit 0x%X\n", status));
- return status;
-}
-
-
-static SDIO_STATUS AllocateBusResources(void)
-{
- INT ii;
- PSDREQUEST pReq;
- PSIGNAL_ITEM pSignal;
-
- DBG_PRINT(SDDBG_TRACE,
- ("+SDIO Bus Driver: AllocateBusResources (R:%d,S:%d) (CR:%d,MR:%d)(CS:%d,MS:%d) \n",
- pBusContext->RequestListSize,
- pBusContext->SignalSemListSize,
- pBusContext->CurrentRequestAllocations,pBusContext->MaxRequestAllocations,
- pBusContext->CurrentSignalAllocations,pBusContext->MaxSignalAllocations));
-
- /* allocate some initial requests */
- for (ii = 0; ii < pBusContext->RequestListSize; ii++) {
- pReq = AllocateRequest();
- if (pReq == NULL) {
- break;
- }
- /* free requests adds the request to the list */
- FreeRequest(pReq);
- }
-
- for (ii = 0; ii < pBusContext->SignalSemListSize; ii++) {
- pSignal = AllocateSignal();
- if (pSignal == NULL) {
- break;
- }
- /* freeing it adds it to the list */
- FreeSignal(pSignal);
- }
-
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: AllocateBusResources\n"));
- return SDIO_STATUS_SUCCESS;
-}
-
-
-/* cleanup bus resources */
-static void CleanUpBusResources(void)
-{
- PSDLIST pItem;
- PSDREQUEST pReq;
- PSIGNAL_ITEM pSignal;
-
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: CleanUpBusResources (CR:%d,MR:%d)(CS:%d,MS:%d) \n",
- pBusContext->CurrentRequestAllocations,pBusContext->MaxRequestAllocations,
- pBusContext->CurrentSignalAllocations,pBusContext->MaxSignalAllocations));
-
- while(1) {
- pItem = SDListRemoveItemFromHead(&pBusContext->RequestList);
- if (NULL == pItem) {
- break;
- }
- /* free the request */
- pReq = CONTAINING_STRUCT(pItem, SDREQUEST, SDList);
- if (pReq->InternalFlags & SDBD_ALLOC_IRQ_SAFE_MASK) {
- KernelFreeIrqSafe(pReq);
- } else {
- KernelFree(pReq);
- }
- pBusContext->CurrentRequestAllocations--;
- }
-
- if (pBusContext->CurrentRequestAllocations != 0) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Request allocations are not ZERO! (CR:%d)\n",
- pBusContext->CurrentRequestAllocations));
- }
-
- while(1) {
- pItem = SDListRemoveItemFromHead(&pBusContext->SignalList);
- if (NULL == pItem) {
- break;
- }
- pSignal = CONTAINING_STRUCT(pItem, SIGNAL_ITEM, SDList);
- DestroySignal(pSignal);
- pBusContext->CurrentSignalAllocations--;
- }
-
- if (pBusContext->CurrentSignalAllocations != 0) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Signal allocations are not ZERO! (CR:%d)\n",
- pBusContext->CurrentRequestAllocations));
- }
-
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: CleanUpBusResources\n"));
-}
-
-
-/* free a request to the lookaside list */
-void FreeRequest(PSDREQUEST pReq)
-{
- SDIO_STATUS status;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
- /* protect request list */
- if (!SDIO_SUCCESS(status)) {
- return;
- }
-
- if ((pBusContext->CurrentRequestAllocations <= pBusContext->MaxRequestAllocations) ||
- !(pReq->InternalFlags & SDBD_ALLOC_IRQ_SAFE_MASK)) {
- /* add it to the list */
- SDListAdd(&pBusContext->RequestList, &pReq->SDList);
- /* we will hold onto this one */
- pReq = NULL;
- } else {
- /* decrement count */
- pBusContext->CurrentRequestAllocations--;
- }
-
- status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
-
- if (pReq != NULL) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Free Request allocation (CR:%d,MR:%d)\n",
- pBusContext->CurrentRequestAllocations,pBusContext->MaxRequestAllocations));
- if (pReq->InternalFlags & SDBD_ALLOC_IRQ_SAFE_MASK) {
- KernelFreeIrqSafe(pReq);
- } else {
- /* we should never free the ones that were normally allocated */
- DBG_ASSERT(FALSE);
- }
- }
-}
-
-/* allocate a request from the lookaside list */
-PSDREQUEST AllocateRequest(void)
-{
- PSDLIST pItem;
- SDIO_STATUS status;
- PSDREQUEST pReq = NULL;
- ATOMIC_FLAGS internalflags;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
-
- status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
-
- if (!SDIO_SUCCESS(status)) {
- return NULL;
- }
-
- if (pBusContext->InitMask & RESOURCE_INIT) {
- /* check the list, we are now running... */
- pItem = SDListRemoveItemFromHead(&pBusContext->RequestList);
- } else {
- /* we are loading the list with requests at initialization */
- pItem = NULL;
- }
- status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
-
- if (pItem != NULL) {
- pReq = CONTAINING_STRUCT(pItem, SDREQUEST, SDList);
- } else {
- if (pBusContext->InitMask & RESOURCE_INIT) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Request List empty..allocating new one (irq-safe) (CR:%d,MR:%d)\n",
- pBusContext->CurrentRequestAllocations,pBusContext->MaxRequestAllocations));
- /* the resource list was already allocated, we must be running now.
- * at run-time, we allocate using the safe IRQ */
- pReq = (PSDREQUEST)KernelAllocIrqSafe(sizeof(SDREQUEST));
- /* mark that this one was created using IRQ safe allocation */
- internalflags = SDBD_ALLOC_IRQ_SAFE_MASK;
- } else {
- /* use the normal allocation since we are called at initialization */
- pReq = (PSDREQUEST)KernelAlloc(sizeof(SDREQUEST));
- internalflags = 0;
- }
-
- if (pReq != NULL) {
- pReq->InternalFlags = internalflags;
- /* keep track of allocations */
- status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
- pBusContext->CurrentRequestAllocations++;
- status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
- }
- }
-
-
- if (pReq != NULL) {
- /* preserve internal flags */
- internalflags = pReq->InternalFlags;
- ZERO_POBJECT(pReq);
- pReq->InternalFlags = internalflags;
- }
-
- return pReq;
-}
-
-void DestroySignal(PSIGNAL_ITEM pSignal)
-{
- SignalDelete(&pSignal->Signal);
- KernelFree(pSignal);
-}
-
-PSIGNAL_ITEM BuildSignal(void)
-{
- PSIGNAL_ITEM pSignal;
-
- pSignal = (PSIGNAL_ITEM)KernelAlloc(sizeof(SIGNAL_ITEM));
- if (pSignal != NULL) {
- /* initialize signal */
- if (!SDIO_SUCCESS(SignalInitialize(&pSignal->Signal))) {
- KernelFree(pSignal);
- pSignal = NULL;
- }
- }
- return pSignal;
-}
-/* free a signal*/
-void FreeSignal(PSIGNAL_ITEM pSignal)
-{
- SDIO_STATUS status;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
-
- if (!SDIO_SUCCESS(status)) {
- return;
- }
-
- if (pBusContext->CurrentSignalAllocations <= pBusContext->MaxSignalAllocations) {
- /* add it to the list */
- SDListAdd(&pBusContext->SignalList, &pSignal->SDList);
- /* flag that we are holding onto it */
- pSignal = NULL;
- } else {
- /* decrement count */
- pBusContext->CurrentSignalAllocations--;
- }
-
- status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
-
- if (pSignal != NULL) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Free signal allocation (CS:%d,MS:%d)\n",
- pBusContext->CurrentSignalAllocations,pBusContext->MaxSignalAllocations));
- DestroySignal(pSignal);
- }
-}
-
-/* allocate a signal from the list */
-PSIGNAL_ITEM AllocateSignal(void)
-{
- PSDLIST pItem;
- PSIGNAL_ITEM pSignal;
- SDIO_STATUS status;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
-
- if (!SDIO_SUCCESS(status)) {
- return NULL;
- }
-
- if (pBusContext->InitMask & RESOURCE_INIT) {
- /* check the list */
- pItem = SDListRemoveItemFromHead(&pBusContext->SignalList);
- } else {
- /* we are loading the list */
- pItem = NULL;
- }
-
- status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
- if (pItem != NULL) {
- /* return the one from the list */
- pSignal = CONTAINING_STRUCT(pItem, SIGNAL_ITEM, SDList);
- } else {
- if (pBusContext->InitMask & RESOURCE_INIT) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Signal List empty..allocating new one (CS:%d,MS:%d)\n",
- pBusContext->CurrentSignalAllocations,pBusContext->MaxSignalAllocations));
- }
- /* just allocate one */
- pSignal = BuildSignal();
- status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
- if (pSignal != NULL) {
- pBusContext->CurrentSignalAllocations++;
- }
- status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
- }
-
-
- return pSignal;
-}
-
-/*
- * Issus Bus Request (exposed to function drivers)
-*/
-PSDREQUEST IssueAllocRequest(PSDDEVICE pDev)
-{
- return AllocateRequest();
-}
-
-/*
- * Free Request (exposed to function drivers)
-*/
-void IssueFreeRequest(PSDDEVICE pDev, PSDREQUEST pReq)
-{
- FreeRequest(pReq);
-}
-
-/*
- * Issus Bus Request (exposed to function drivers)
-*/
-SDIO_STATUS IssueBusRequest(PSDDEVICE pDev, PSDREQUEST pReq)
-{
- pReq->pFunction = pDev->pFunction;
- return IssueRequestToHCD(pDev->pHcd,pReq);
-}
-
-
- /* completion routine for HCD configs, this is synchronized with normal bus requests */
-static void HcdConfigComplete(PSDREQUEST pReq)
-{
-
- pReq->Status = CALL_HCD_CONFIG((PSDHCD)pReq->pDataBuffer, (PSDCONFIG)pReq->pCompleteContext);
-
- SignalSet(&((PSIGNAL_ITEM)pReq->pHcdContext)->Signal);
-}
-
-SDIO_STATUS SendSyncedHcdBusConfig(PSDDEVICE pDevice, PSDCONFIG pConfig)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDREQUEST pReq = NULL;
- PSIGNAL_ITEM pSignal = NULL;
-
- do {
-
- pSignal = AllocateSignal();
- if (NULL == pSignal) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
-
- pReq = AllocateRequest();
- if (NULL == pReq) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
-
- /* issue pseudo request to sync this with bus requests */
- pReq->pCompletion = HcdConfigComplete;
- pReq->pCompleteContext = pConfig;
- /* re-use hcd context to store the signal since this request
- * never actually goes to an HCD */
- pReq->pHcdContext = pSignal;
- pReq->pDataBuffer = pDevice->pHcd;
- /* flag this as barrier in case it may change the bus mode of the HCD */
- pReq->Flags = SDREQ_FLAGS_PSEUDO | SDREQ_FLAGS_BARRIER | SDREQ_FLAGS_TRANS_ASYNC;
- pReq->Status = SDIO_STATUS_SUCCESS;
-
- /* issue request */
- status = IssueRequestToHCD(pDevice->pHcd,pReq);
-
- } while (FALSE);
-
- if (SDIO_SUCCESS(status)) {
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Config Request Sync-Op waiting....\n"));
- status = SignalWait(&pSignal->Signal);
-
- if (SDIO_SUCCESS(status)) {
- /* return the result of the configuration request */
- status = pReq->Status;
- }
- }
-
- /* cleanup */
- if (pReq != NULL) {
- FreeRequest(pReq);
- }
-
- if (pSignal != NULL) {
- FreeSignal(pSignal);
- }
-
- return status;
-}
-
-/*
- * Issus bus Configuration (exposed to function drivers)
-*/
-SDIO_STATUS IssueBusConfig(PSDDEVICE pDev, PSDCONFIG pConfig)
-{
- SDIO_STATUS status;
- INT cmdLength;
- UINT8 debugLevel = SDDBG_ERROR;
-
- cmdLength = GET_SDCONFIG_CMD_LEN(pConfig);
- status = SDIO_STATUS_INVALID_PARAMETER;
-
- do {
- /* check buffers and length */
- if (IS_SDCONFIG_CMD_GET(pConfig) || IS_SDCONFIG_CMD_PUT(pConfig)) {
- if ((GET_SDCONFIG_CMD_DATA(PVOID,pConfig) == NULL) || (0 == cmdLength)) {
- break;
- }
- }
-
- switch (GET_SDCONFIG_CMD(pConfig)) {
- case SDCONFIG_FUNC_ACK_IRQ:
- status = SDFunctionAckInterrupt(pDev);
- break;
- case SDCONFIG_FUNC_ENABLE_DISABLE:
- if (cmdLength < sizeof(SDCONFIG_FUNC_ENABLE_DISABLE_DATA)) {
- break;
- }
- status = SDEnableFunction(pDev,
- GET_SDCONFIG_CMD_DATA(PSDCONFIG_FUNC_ENABLE_DISABLE_DATA,pConfig));
- break;
- case SDCONFIG_FUNC_UNMASK_IRQ:
- status = SDMaskUnmaskFunctionIRQ(pDev,FALSE);
- break;
- case SDCONFIG_FUNC_MASK_IRQ:
- status = SDMaskUnmaskFunctionIRQ(pDev,TRUE);
- break;
- case SDCONFIG_FUNC_SPI_MODE_DISABLE_CRC:
- status = SDSPIModeEnableDisableCRC(pDev,FALSE);
- break;
- case SDCONFIG_FUNC_SPI_MODE_ENABLE_CRC:
- status = SDSPIModeEnableDisableCRC(pDev,TRUE);
- break;
- case SDCONFIG_FUNC_ALLOC_SLOT_CURRENT:
- status = SDAllocFreeSlotCurrent(pDev,
- TRUE,
- GET_SDCONFIG_CMD_DATA(PSDCONFIG_FUNC_SLOT_CURRENT_DATA,pConfig));
- break;
- case SDCONFIG_FUNC_FREE_SLOT_CURRENT:
- status = SDAllocFreeSlotCurrent(pDev, FALSE, NULL);
- break;
- case SDCONFIG_FUNC_CHANGE_BUS_MODE:
-
- status = SetOperationalBusMode(pDev,
- GET_SDCONFIG_CMD_DATA(PSDCONFIG_BUS_MODE_DATA,
- pConfig));
- break;
- case SDCONFIG_FUNC_NO_IRQ_PEND_CHECK:
- status = TryNoIrqPendingCheck(pDev);
- break;
- default:
-
- if (GET_SDCONFIG_CMD(pConfig) & SDCONFIG_FLAGS_HC_CONFIG) {
- /* synchronize config requests with busrequests */
- status = SendSyncedHcdBusConfig(pDev,pConfig);
- } else {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: IssueBusConfig - unknown command:0x%X \n",
- GET_SDCONFIG_CMD(pConfig)));
- status = SDIO_STATUS_INVALID_PARAMETER;
- }
- break;
- }
- } while(FALSE);
-
- if (!SDIO_SUCCESS(status)) {
-
- if(status == SDIO_STATUS_FUNC_ENABLE_TIMEOUT ){ /* reduce debug level to avoid timeout error messages */
- debugLevel = SDDBG_TRACE;
- }
-
-
- DBG_PRINT(debugLevel,
- ("SDIO Bus Driver: IssueBusConfig - Error in command:0x%X, Buffer:0x%X, Length:%d Err:%d\n",
- GET_SDCONFIG_CMD(pConfig),
- GET_SDCONFIG_CMD_DATA(INT,pConfig),
- cmdLength, status));
- }
- return status;
-}
-
-/* start a request */
-static INLINE SDIO_STATUS StartHcdRequest(PSDHCD pHcd, PSDREQUEST pReq)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- if ((pReq->pFunction != NULL) && (pReq->pFunction->Flags & SDFUNCTION_FLAG_REMOVING)) {
- /* this device or function is going away, fail any new requests */
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: StartHcdRequest, fail request 0x%X, device is removing\n", (UINT)pReq));
- pReq->Status = SDIO_STATUS_CANCELED;
- return SDIO_STATUS_SDREQ_QUEUE_FAILED;
- }
-
- status = _AcquireHcdLock(pHcd);
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to acquire HCD request lock: Err:%d\n", status));
- pReq->Status = SDIO_STATUS_SDREQ_QUEUE_FAILED;
- return SDIO_STATUS_SDREQ_QUEUE_FAILED;
- }
-
- if (pReq->Flags & SDREQ_FLAGS_QUEUE_HEAD) {
- /* caller wants this request queued to the head */
-
- /* a completion routine for a barrier request is called
- * while the queue is busy. A barrier request can
- * insert a new request at the head of the queue */
- DBG_ASSERT(IsQueueBusy(&pHcd->RequestQueue));
- QueueRequestToFront(&pHcd->RequestQueue,pReq);
- } else {
- /* insert in queue at tail */
- QueueRequest(&pHcd->RequestQueue,pReq);
-
- /* is queue busy ? */
- if (IsQueueBusy(&pHcd->RequestQueue)) {
- /* release lock */
- status = _ReleaseHcdLock(pHcd);
- /* controller is busy already, no need to call the hcd */
- return SDIO_STATUS_PENDING;
- }
- /* mark it as busy */
- MarkQueueBusy(&pHcd->RequestQueue);
- }
-
- /* remove item from head and set current request */
- SET_CURRENT_REQUEST(pHcd, DequeueRequest(&pHcd->RequestQueue));
- if (CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
- CHECK_HCD_RECURSE(pHcd, pHcd->pCurrentRequest);
- }
- /* release lock */
- status = _ReleaseHcdLock(pHcd);
- /* controller was not busy, call into HCD to process current request */
- status = CallHcdRequest(pHcd);
- return status;
-}
-
-
-/* used by CMD12,CMD13 to save the original completion routine */
-#define GET_BD_RSV_REQUEST_COMPLETION(pR) (PSDEQUEST_COMPLETION)(pR)->pBdRsv1
-#define SET_BD_RSV_REQUEST_COMPLETION(pR,c) (pR)->pBdRsv1 = (PVOID)(c)
-
-/* used by CMD12 processing to save/restore the original data transfer status */
-#define GET_BD_RSV_ORIG_STATUS(pR) (SDIO_STATUS)(pR)->pBdRsv2
-#define SET_BD_RSV_ORIG_STATUS(pR,s) (pR)->pBdRsv2 = (PVOID)(s)
-
-/* used by CMD13 processing to get/set polling count */
-#define GET_BD_RSV_STATUS_POLL_COUNT(pR) (INT)(pR)->pBdRsv2
-#define SET_BD_RSV_STATUS_POLL_COUNT(pR,s) (pR)->pBdRsv2 = (PVOID)(s)
-
-/* used by CMD55 processing to save the second part of the request */
-#define GET_BD_RSV_ORIG_REQ(pR) (PSDREQUEST)(pR)->pBdRsv1
-#define SET_BD_RSV_ORIG_REQ(pR,r) (pR)->pBdRsv1 = (PVOID)(r)
-
-/* used by all to save HCD */
-#define GET_BD_RSV_HCD(pR) (PSDHCD)(pR)->pBdRsv3
-#define SET_BD_RSV_HCD(pR,h) (pR)->pBdRsv3 = (PVOID)(h)
-
-static void CMD13CompletionBarrier(PSDREQUEST pReq);
-
-static INLINE void SetupCMD13(PSDHCD pHcd, PSDREQUEST pReq)
-{
- pReq->Command = CMD13;
- /* sequence must be atomic, queue it to the head and flag as a barrier */
- pReq->Flags = SDREQ_FLAGS_QUEUE_HEAD | SDREQ_FLAGS_BARRIER | SDREQ_FLAGS_TRANS_ASYNC;
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- pReq->Argument = 0;
- pReq->Flags |= SDREQ_FLAGS_RESP_R2;
- } else {
- pReq->Flags |= SDREQ_FLAGS_RESP_R1;
- pReq->Argument |= pHcd->CardProperties.RCA << 16;
- }
- /* insert completion */
- pReq->pCompletion = CMD13CompletionBarrier;
-}
-
-/* CMD13 (GET STATUS) completion */
-static void CMD13CompletionBarrier(PSDREQUEST pReq)
-{
- PSDEQUEST_COMPLETION pOrigCompletion = GET_BD_RSV_REQUEST_COMPLETION(pReq);
- PSDHCD pHcd = GET_BD_RSV_HCD(pReq);
- INT pollingCount = GET_BD_RSV_STATUS_POLL_COUNT(pReq);
- BOOL doCompletion = TRUE;
- UINT32 cardStatus;
-
- DBG_ASSERT(pOrigCompletion != NULL);
- DBG_ASSERT(pHcd != NULL);
- DBG_PRINT(SDIODBG_REQUESTS, ("+SDIO Bus Driver: CMD13CompletionBarrier (cnt:%d) \n",pollingCount));
-
- do {
- if (!SDIO_SUCCESS(pReq->Status)) {
- break;
- }
-
- cardStatus = SD_R1_GET_CARD_STATUS(pReq->Response);
-
- if (cardStatus & SD_CS_TRANSFER_ERRORS) {
- DBG_PRINT(SDIODBG_REQUESTS,("SDIO Bus Driver: Card transfer errors : 0x%X \n",cardStatus));
- pReq->Status = SDIO_STATUS_PROGRAM_STATUS_ERROR;
- break;
- }
-
- if (SD_CS_GET_STATE(cardStatus) != SD_CS_STATE_PRG) {
- DBG_PRINT(SDIODBG_REQUESTS,("SDIO Bus Driver: Card programming done \n"));
- break;
- }
-
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Card still programming.. \n"));
- pollingCount--;
-
- if (pollingCount < 0) {
- pReq->Status = SDIO_STATUS_PROGRAM_TIMEOUT;
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: card programming timeout!\n"));
- break;
- }
-
- doCompletion = FALSE;
- /* keep trying */
- SET_BD_RSV_STATUS_POLL_COUNT(pReq, pollingCount);
- SetupCMD13(pHcd,pReq);
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: re-issuing CMD13 \n"));
- /* re-issue */
- IssueRequestToHCD(pHcd, pReq);
-
- } while (FALSE);
-
-
- if (doCompletion) {
- /* restore original completion routine */
- pReq->pCompletion = pOrigCompletion;
- /* call original completion routine */
- pOrigCompletion(pReq);
- }
-
- DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: CMD13CompletionBarrier \n"));
-}
-
-/* command 13 (GET STATUS) preparation */
-static void PrepCMD13Barrier(PSDREQUEST pReq)
-{
- SDIO_STATUS status = pReq->Status;
- PSDHCD pHcd = GET_BD_RSV_HCD(pReq);
- INT pollingCount;
- PSDEQUEST_COMPLETION pOrigCompletion = GET_BD_RSV_REQUEST_COMPLETION(pReq);
-
- DBG_ASSERT(pHcd != NULL);
- DBG_ASSERT(pOrigCompletion != NULL);
-
- DBG_PRINT(SDIODBG_REQUESTS, ("+SDIO Bus Driver: PrepCMD13Barrier \n"));
-
- if (SDIO_SUCCESS(status)) {
- /* re-use the request for CMD13 */
- SetupCMD13(pHcd,pReq);
- /* set polling count to a multiple of the Block count, if the BlockCount was
- * zeroed by the HCD, then set it to 1X multiplier */
- pollingCount = max(pBusContext->CMD13PollingMultiplier,
- pBusContext->CMD13PollingMultiplier * (INT)pReq->BlockCount);
- /* initialize count */
- SET_BD_RSV_STATUS_POLL_COUNT(pReq, pollingCount);
- /* re-issue it, we can call IssueRequest here since we are re-using the request */
- IssueRequestToHCD(pHcd, pReq);
- } else {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Request Failure (%d) , CMD13 bypassed.\n",status));
- /* call the original completion routine */
- pOrigCompletion(pReq);
- }
-
- DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: PrepCMD13Barrier (%d) \n",status));
-}
-
-/* CMD12 completion */
-static void CMD12Completion(PSDREQUEST pReq)
-{
- PSDEQUEST_COMPLETION pOrigCompletion = GET_BD_RSV_REQUEST_COMPLETION(pReq);
-
- DBG_ASSERT(pOrigCompletion != NULL);
-
- DBG_PRINT(SDIODBG_REQUESTS, ("+SDIO Bus Driver: CMD12Completion \n"));
-
- /* restore original completion routine */
- pReq->pCompletion = pOrigCompletion;
-
- if (SDIO_SUCCESS(pReq->Status)) {
- /* if CMD12 succeeds, we want to return the result of the original
- * request */
- pReq->Status = GET_BD_RSV_ORIG_STATUS(pReq);
- DBG_PRINT(SDIODBG_REQUESTS,
- ("SDIO Bus Driver: PrepCMD12Completion original status %d \n",pReq->Status));
- }
- /* call original completion routine */
- pOrigCompletion(pReq);
-
- DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: CMD12Completion \n"));
-}
-
-/* CMD12 preparation */
-static void PrepCMD12Barrier(PSDREQUEST pReq)
-{
-
- SDIO_STATUS status = pReq->Status;
- PSDHCD pHcd = GET_BD_RSV_HCD(pReq);
- PSDEQUEST_COMPLETION pOrigCompletion = GET_BD_RSV_REQUEST_COMPLETION(pReq);
-
- DBG_ASSERT(pHcd != NULL);
- DBG_ASSERT(pOrigCompletion != NULL);
-
- DBG_PRINT(SDIODBG_REQUESTS, ("+SDIO Bus Driver: PrepCMD12Barrier \n"));
-
- if (SDIO_SUCCESS(status) || /* only issue CMD12 on success or specific bus errors */
- (SDIO_STATUS_BUS_READ_TIMEOUT == status) ||
- (SDIO_STATUS_BUS_READ_CRC_ERR == status) ||
- (SDIO_STATUS_BUS_WRITE_ERROR == status)) {
- if (!CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
- if (!ForceAllRequestsAsync()) {
- /* clear the call bit as an optimization, note clearing it wholesale here will
- * allow request processing to recurse one more level */
- AtomicTest_Clear(&pHcd->HcdFlags, HCD_REQUEST_CALL_BIT);
- }
- }
- /* re-use the request for CMD12 */
- pReq->Command = CMD12;
- pReq->Argument = 0;
-
- /* if the data transfer was successful, check for transfer check */
- if (SDIO_SUCCESS(status) &&
- (pReq->Flags & SDREQ_FLAGS_AUTO_TRANSFER_STATUS)) {
- /* original data request requires a transfer status check, which is another
- * barrier request */
- pReq->Flags = SDREQ_FLAGS_RESP_R1B | SDREQ_FLAGS_QUEUE_HEAD | SDREQ_FLAGS_BARRIER |
- SDREQ_FLAGS_TRANS_ASYNC;
- DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: PrepCMD12Barrier , chaining CMD13 \n"));
- /* switch out completion to send the CMD13 next */
- pReq->pCompletion = PrepCMD13Barrier;
- } else {
- pReq->Flags = SDREQ_FLAGS_RESP_R1B | SDREQ_FLAGS_QUEUE_HEAD | SDREQ_FLAGS_TRANS_ASYNC;
- pReq->pCompletion = CMD12Completion;
- }
-
- /* save the original data transfer request status */
- SET_BD_RSV_ORIG_STATUS(pReq,status);
- /* re-issue it, we can call IssueRequest here since we are re-using the request */
- IssueRequestToHCD(pHcd, pReq);
- } else {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Request Failure (%d) , CMD12 bypassed.\n",status));
- /* call the original completion routine */
- pOrigCompletion(pReq);
- }
-
- DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: PrepCMD12Barrier (%d) \n",status));
-}
-
-
-/* CMD55 barrier - this is a special barrier completion routine, we have to submit the second
- * part of the command command sequence atomically */
-static void CMD55CompletionBarrier(PSDREQUEST pReq)
-{
- SDIO_STATUS status = pReq->Status;
- PSDREQUEST pOrigReq = GET_BD_RSV_ORIG_REQ(pReq);
- PSDHCD pHcd = GET_BD_RSV_HCD(pReq);
- BOOL doCompletion = FALSE;
-
- DBG_ASSERT(pOrigReq != NULL);
- DBG_ASSERT(pHcd != NULL);
-
- DBG_PRINT(SDIODBG_REQUESTS, ("+SDIO Bus Driver: CMD55Completion \n"));
-
- do {
-
- if (!SDIO_SUCCESS(status)) {
- /* command 55 failed */
- pOrigReq->Status = status;
- doCompletion = TRUE;
- break;
- }
-
- if (!(SD_R1_GET_CARD_STATUS(pReq->Response) & SD_CS_APP_CMD)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Card is not accepting CMD55, status:0x%X \n",
- SD_R1_GET_CARD_STATUS(pReq->Response)));
- pOrigReq->Status = SDIO_STATUS_INVALID_COMMAND;
- doCompletion = TRUE;
- break;
- }
-
- if (!CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
- if (!ForceAllRequestsAsync()) {
- AtomicTest_Clear(&pHcd->HcdFlags, HCD_REQUEST_CALL_BIT);
- }
- }
-
- /* flag the original request to queue to the head */
- pOrigReq->Flags |= SDREQ_FLAGS_QUEUE_HEAD;
- /* submit original request, we cannot call IssueRequestHCD() here because the
- * original request has already gone through IssueRequestHCD() already */
- status = StartHcdRequest(pHcd, pOrigReq);
-
- if (SDIO_STATUS_PENDING == status) {
- break;
- }
-
- pOrigReq->Status = status;
-
- if (SDIO_STATUS_SDREQ_QUEUE_FAILED == status) {
- /* never made it to the queue */
- doCompletion = TRUE;
- break;
- }
-
- /* request completed in-line */
- _SDIO_HandleHcdEvent(pHcd, EVENT_HCD_TRANSFER_DONE);
-
- } while (FALSE);
-
- if (doCompletion) {
- DoRequestCompletion(pOrigReq, pHcd);
- }
-
- /* free the CMD55 request */
- FreeRequest(pReq);
-
- DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: CMD55Completion \n"));
-}
-
-
-/* synch completion routine */
-static void SynchCompletion(PSDREQUEST pRequest)
-{
- PSIGNAL_ITEM pSignal;
-
- pSignal = (PSIGNAL_ITEM)pRequest->pCompleteContext;
- DBG_ASSERT(pSignal != NULL);
- if (!SDIO_SUCCESS(SignalSet(&pSignal->Signal))) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: SynchCompletion - signal failed \n"));
- }
-
-}
-
-/*
- * Issue a request to the host controller
- *
- *
- * The following flags are handled internally by the bus driver to guarantee atomicity.
- *
- * SDREQ_FLAGS_APP_CMD - SD Extended commands requiring CMD55 to precede the actual command
- * SDREQ_FLAGS_AUTO_CMD12 - Memory Card Data transfer needs CMD12 to stop transfer
- * (multi-block reads/writes)
- * SDREQ_FLAGS_AUTO_TRANSFER_STATUS - Memory card data transfer needs transfer status polling
- * using CMD13
- *
- * These request flags require additional commands prepended or appended to the original command
- *
- * The order of command execution :
- *
- * Order Condition Command Issued
- * -------------------------------------------------------------
- * 1. If APP_CMD CMD55 issued.
- * 2. Always Caller command issued.
- * 3. If AUTO_CMD12 CMD12 issued.
- * 4. If AUTO_TRANSFER_STATUS CMD13 issued until card programming is complete
-*/
-SDIO_STATUS IssueRequestToHCD(PSDHCD pHcd, PSDREQUEST pReq)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSIGNAL_ITEM pSignal = NULL;
- BOOL handleFailedReqSubmit = FALSE;
-
- CLEAR_INTERNAL_REQ_FLAGS(pReq);
-
- do {
- /* mark request in-use */
- ATOMIC_FLAGS internal = AtomicTest_Set(&pReq->InternalFlags, SDBD_PENDING);
- if (internal & (1<<SDBD_PENDING)) {
- DBG_ASSERT_WITH_MSG(FALSE,
- "SDIO Bus Driver: IssueRequestToHCD - request already in use \n");
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Request already in use: 0x%X",(INT)pReq));
- }
-
- if (!(pReq->Flags & SDREQ_FLAGS_TRANS_ASYNC)) {
- /* caller wants synchronous operation, insert our completion routine */
- pReq->pCompletion = SynchCompletion;
- pSignal = AllocateSignal();
- if (NULL == pSignal) {
- status = SDIO_STATUS_NO_RESOURCES;
- pReq->Status = SDIO_STATUS_NO_RESOURCES;
- handleFailedReqSubmit = TRUE;
- /* no need to continue */
- break;
- }
- pReq->pCompleteContext = (PVOID)pSignal;
- }
-
- if ((pReq->Flags & SDREQ_FLAGS_AUTO_CMD12) &&
- !(pHcd->Attributes & SDHCD_ATTRIB_AUTO_CMD12) &&
- !(IS_HCD_BUS_MODE_SPI(pHcd) && IS_SDREQ_WRITE_DATA(pReq->Flags))) {
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Auto CMD12 on Request:0x%08X \n",(INT)pReq));
- /* caller wants CMD12 auto-issued and the HCD does not support it */
- /* setup caller's request as a barrier and replace their completion routine */
- pReq->Flags |= SDREQ_FLAGS_BARRIER;
- /* take off the flag, since the BD will be issuing it */
- pReq->Flags &= ~SDREQ_FLAGS_AUTO_CMD12;
- /* save original completion */
- SET_BD_RSV_REQUEST_COMPLETION(pReq,pReq->pCompletion);
- /* save the HCD we are on */
- SET_BD_RSV_HCD(pReq,pHcd);
- /* use completion for preping CMD12 */
- pReq->pCompletion = PrepCMD12Barrier;
- }
-
- if (pReq->Flags & SDREQ_FLAGS_AUTO_TRANSFER_STATUS) {
- /* caller wants transfer status checked. If a CMD12
- * barrier request has been setup we let the CMD12 completion take care
- * of setting up the transfer check */
- if (pReq->pCompletion != PrepCMD12Barrier) {
- /* make CMD13 prep a barrier */
- pReq->Flags |= SDREQ_FLAGS_BARRIER;
- /* save original completion */
- SET_BD_RSV_REQUEST_COMPLETION(pReq,pReq->pCompletion);
- /* save the HCD we are on */
- SET_BD_RSV_HCD(pReq,pHcd);
- /* use completion for preping CMD13 */
- pReq->pCompletion = PrepCMD13Barrier;
- }
- }
-
- /* check app command, the two command sequence must be handled atomically */
- if (pReq->Flags & SDREQ_FLAGS_APP_CMD) {
- PSDREQUEST pCmd55;
- /* allocate request to handle initial CMD55 command */
- pCmd55 = AllocateRequest();
- if (NULL == pCmd55) {
- status = SDIO_STATUS_NO_RESOURCES;
- pReq->Status = SDIO_STATUS_NO_RESOURCES;
- /* complete the caller's request with error */
- handleFailedReqSubmit = TRUE;
- /* no need to continue */
- break;
- }
- /* first submit CMD55 */
- /* set RCA */
- pCmd55->Argument = pHcd->CardProperties.RCA << 16;
- /* mark as a barrier request */
- pCmd55->Flags = SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_BARRIER | SDREQ_FLAGS_TRANS_ASYNC;
- pCmd55->Command = CMD55;
- /* call our barrier completion routine when done */
- pCmd55->pCompletion = CMD55CompletionBarrier;
- /* save request and target HCD */
- SET_BD_RSV_ORIG_REQ(pCmd55,pReq);
- SET_BD_RSV_HCD(pCmd55,pHcd);
- /* recursively start the CMD55 request, since the CMD55 is a barrier
- * request, it's completion routine will submit the actual request
- * atomically */
- status = IssueRequestToHCD(pHcd, pCmd55);
-
- } else {
- /* start the normal request */
- status = StartHcdRequest(pHcd,pReq);
- }
-
-
- if (SDIO_STATUS_SDREQ_QUEUE_FAILED == status) {
- handleFailedReqSubmit = TRUE;
- /* no need to continue, clean up at the end */
- break;
- }
-
- /* at this point, the request was either queued or was processed by the
- * HCD */
-
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: HCD returned status:%d on request: 0x%X, (CMD:%d) \n",
- status, (INT)pReq, pReq->Command));
-
- if (status != SDIO_STATUS_PENDING) {
- /* the HCD completed the request within the HCD request callback,
- * check and see if this is a synchronous request */
- if (pSignal != NULL) {
- /* it was synchronous */
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Sync-Op signal wait bypassed \n"));
- /* NULL out completion info, there's no need to
- * signal the semaphore */
- pReq->pCompletion = NULL;
-
- } else {
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Async operation completed in-line \n"));
- /* this was an async call, always return pending */
- status = SDIO_STATUS_PENDING;
- }
- /* process this completed transfer on behalf of the HCD */
- _SDIO_HandleHcdEvent(pHcd, EVENT_HCD_TRANSFER_DONE);
-
- /* done processing */
- break;
- }
- /* I/O is now pending, could be sync or async */
- /* check for synch op */
- if (pSignal != NULL) {
- /* wait for completion */
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Sync-Op signal waiting....\n"));
- /* this is not interruptable, as the HCD must complete it. */
- status = SignalWait(&pSignal->Signal);
- /* don't need the signal anymore */
- FreeSignal(pSignal);
- pSignal = NULL;
-
- /* note: it is safe to touch pReq since we own
- * the completion routine for synch transfers */
-
- /* check signal wait status */
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO Bus Driver - IssueRequestToHCD: Synch transfer - signal wait failed, cancelling req 0X%X\n",
- (UINT)pReq));
- pReq->Status = SDIO_STATUS_CANCELED;
- status = SDIO_STATUS_CANCELED;
- break;
- }
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Sync-Op woke up\n"));
- /* return the completion status of the request */
- status = pReq->Status;
- } else {
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Async operation Pending \n"));
- }
-
- } while (FALSE);
-
- /* see if we need to clean up failed submissions */
- if (handleFailedReqSubmit) {
- /* make sure this is cleared */
- AtomicTest_Clear(&pReq->InternalFlags, SDBD_PENDING);
- /* the request processing failed before it was submitted to the HCD */
- /* note: since it never made it to the queue we can touch pReq */
- if (pReq->Flags & SDREQ_FLAGS_TRANS_ASYNC) {
- /* for ASYNC requests, we need to call the completion routine */
- DoRequestCompletion(pReq, pHcd);
- /* return pending for all ASYNC requests */
- status = SDIO_STATUS_PENDING;
- }
- }
-
- /* check if we need to clean up the signal */
- if (pSignal != NULL) {
- /* make sure this is freed */
- FreeSignal(pSignal);
- }
- /* return status */
- return status;
-}
-
-/* documentation for configuration requests */
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Enable or Disable the SDIO Function
-
- @function name: SDCONFIG_FUNC_ENABLE_DISABLE
- @prototype: SDCONFIG_FUNC_ENABLE_DISABLE
- @category: PD_Reference
-
- @input: SDCONFIG_FUNC_ENABLE_DISABLE_DATA - Enable Data structure
-
- @output: none
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command
- uses the SDCONFIG_FUNC_ENABLE_DISABLE_DATA structure. The caller must set the
- EnableFlags and specify the TimeOut value in milliseconds. The TimeOut
- value is used for polling the I/O ready bit. This command returns a status
- of SDIO_STATUS_FUNC_ENABLE_TIMEOUT if the ready bit was not set/cleared
- by the card within the timeout period.
-
- @example: Example of enabling an I/O function:
- fData.EnableFlags = SDCONFIG_ENABLE_FUNC;
- fData.TimeOut = 500;
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_FUNC_ENABLE_DISABLE,
- &fData,
- sizeof(fData));
-
- @see also: SDLIB_IssueConfig
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Unmask the function's IRQ
-
- @function name: SDCONFIG_FUNC_UNMASK_IRQ
- @prototype: SDCONFIG_FUNC_UNMASK_IRQ
- @category: PD_Reference
-
- @input: none
-
- @output: none
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command
- unmasks the IRQ for the I/O function. This request sets the function's
- interrupt enable bit in the INTENABLE register in the
- common register space.
-
- @example: Example of unmasking interrupt :
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_FUNC_UNMASK_IRQ,
- NULL,
- 0);
-
- @see also: SDCONFIG_FUNC_MASK_IRQ
- @see also: SDLIB_IssueConfig
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Mask the function's IRQ
-
- @function name: SDCONFIG_FUNC_MASK_IRQ
- @prototype: SDCONFIG_FUNC_MASK_IRQ
- @category: PD_Reference
-
- @input: none
-
- @output: none
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command
- masks the IRQ for the I/O function.
-
- @example: Example of unmasking interrupt :
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_FUNC_MASK_IRQ,
- NULL,
- 0);
-
- @see also: SDCONFIG_FUNC_UNMASK_IRQ
- @see also: SDLIB_IssueConfig
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Acknowledge that the function's IRQ has been handled
-
- @function name: SDCONFIG_FUNC_ACK_IRQ
- @prototype: SDCONFIG_FUNC_ACK_IRQ
- @category: PD_Reference
-
- @input: none
-
- @output: none
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command
- indicates to the bus driver that the function driver has handled the
- interrupt. The bus driver will notify the host controller to unmask the
- interrupt source. SDIO interrupts are level triggered and are masked at the
- host controller level until all function drivers have indicated that they
- have handled their respective interrupt. This command can be issued in either
- the IRQ handler or asynchronous IRQ handler.
-
- @example: Example of acknowledging an interrupt :
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_FUNC_ACK_IRQ,
- NULL,
- 0);
-
- @see also: SDLIB_IssueConfig
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Disable SD/MMC/SDIO card CRC checking.
-
- @function name: SDCONFIG_FUNC_SPI_MODE_DISABLE_CRC
- @prototype: SDCONFIG_FUNC_SPI_MODE_DISABLE_CRC
- @category: PD_Reference
-
- @input: none
-
- @output: none
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command
- issues CMD59 to disable SPI-CRC checking and requests the host controller
- driver to stop checking the CRC. This is typically used in systems where
- CRC checking is not required and performance is improved if the CRC checking
- is ommitted (i.e. SPI implementations without hardware CRC support).
-
- @example: Example of disabling SPI CRC checking:
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_FUNC_SPI_MODE_DISABLE_CRC,
- NULL,
- 0);
-
- @see also: SDCONFIG_FUNC_SPI_MODE_ENABLE_CRC
- @see also: SDLIB_IssueConfig
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Enable SD/MMC/SDIO card CRC checking.
-
- @function name: SDCONFIG_FUNC_SPI_MODE_ENABLE_CRC
- @prototype: SDCONFIG_FUNC_SPI_MODE_ENABLE_CRC
- @category: PD_Reference
-
- @input: none
-
- @output: none
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command
- issues CMD59 to enable SPI-CRC checking and requests the host controller
- driver to generate valid CRCs for commands and data as well as
- check the CRC in responses and incomming data blocks.
-
- @example: Example of enabling SPI CRC checking:
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_FUNC_SPI_MODE_ENABLE_CRC,
- NULL,
- 0);
-
- @see also: SDCONFIG_FUNC_SPI_MODE_DISABLE_CRC
- @see also: SDLIB_IssueConfig
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Allocate slot current for a card function.
-
- @function name: SDCONFIG_FUNC_ALLOC_SLOT_CURRENT
- @prototype: SDCONFIG_FUNC_ALLOC_SLOT_CURRENT
- @category: PD_Reference
-
- @input: SDCONFIG_FUNC_SLOT_CURRENT_DATA
-
- @output: SDCONFIG_FUNC_SLOT_CURRENT_DATA
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command
- requests an allocation of slot current to satisfy the power requirements
- of the function. The command uses the SDCONFIG_FUNC_SLOT_CURRENT_DATA
- data structure to pass the required current in mA. Slot current allocation
- is not cummulative and this command should only be issued once by each function
- driver with the worse case slot current usage.
- The command returns SDIO_STATUS_NO_RESOURCES if the
- requirement cannot be met by the host hardware. The SlotCurrent field will
- contain the remaining current available to the slot. The slot current should
- be allocated before the function is enabled using SDCONFIG_FUNC_ENABLE_DISABLE.
- When a function driver is unloaded it should free the slot current allocation
- by using the SDCONFIG_FUNC_FREE_SLOT_CURRENT command.
-
- @example: Example of allocating slot current:
- slotCurrent.SlotCurrent = 150; // 150 mA
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_FUNC_ALLOC_SLOT_CURRENT,
- &slotCurrent,
- sizeof(slotCurrent));
-
-
- @see also: SDCONFIG_FUNC_FREE_SLOT_CURRENT
- @see also: SDLIB_IssueConfig
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Free slot current for a card function.
-
- @function name: SDCONFIG_FUNC_FREE_SLOT_CURRENT
- @prototype: SDCONFIG_FUNC_FREE_SLOT_CURRENT
- @category: PD_Reference
-
- @input: none
-
- @output: none
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command
- frees the allocated current for a card function. This command should be
- issued only once (per function) and only after an allocation was successfully made.
-
- @example: Example of freeing slot current:
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_FUNC_FREE_SLOT_CURRENT,
- NULL,
- 0);
-
- @see also: SDCONFIG_FUNC_ALLOC_SLOT_CURRENT
- @see also: SDLIB_IssueConfig
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Set the bus mode for the SD/SDIO card.
-
- @function name: SDCONFIG_FUNC_CHANGE_BUS_MODE
- @prototype: SDCONFIG_FUNC_CHANGE_BUS_MODE
- @category: PD_Reference
-
- @input: none
-
- @output: none
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command
- alters the card's bus mode (width and clock rate) to a driver specified
- value. The driver must read the current bus mode flags, modify if necessary
- and pass the value in the SDCONFIG_BUS_MODE_DATA structure.
- If the bus width is changed (1 or 4 bit) the caller must adjust the mode flags
- for the new width. Cards cannot be switched between 1/4 bit and SPI mode.
- Switching to or from SPI mode requires a power cycle. Adjustments to the clock
- rate is immediate on the next bus transaction. The actual clock rate value is
- limited by the host controller and is reported in the ClockRate field when the
- command completes successfully.
- The bus mode change is card wide and may affect other SDIO functions on
- multi-function cards. Use this feature with caution. This feature should NOT be
- used to dynamically control clock rates during runtime and should only be used
- at card initialization. Changing the bus mode must be done with SDIO function
- interrupts masked.
- This request can block and must only be called from a schedulable context.
-
- @example: Example of changing the clock rate:
- SDCONFIG_BUS_MODE_DATA busSettings;
- ZERO_OBJECT(busSettings);
- // get current bus flags and keep the same bus width
- busSettings.BusModeFlags = SDDEVICE_GET_BUSMODE_FLAGS(pInstance->pDevice);
- busSettings.ClockRate = 8000000; // adjust clock to 8 Mhz
- // issue config request to override clock rate
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_FUNC_CHANGE_BUS_MODE,
- &busSettings,
- sizeof(SDCONFIG_BUS_MODE_DATA));
-
- @see also: SDDEVICE_GET_BUSMODE_FLAGS
- @see also: SDLIB_IssueConfig
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Get the debug level of the underlying host controller driver.
-
- @function name: SDCONFIG_GET_HCD_DEBUG
- @prototype: SDCONFIG_GET_HCD_DEBUG
- @category: PD_Reference
-
- @input: none
-
- @output: CT_DEBUG_LEVEL
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command
- requests the current debug level of the HCD driver. This API is useful for
- saving the current debug level of the HCD prior to issuing SDCONFIG_SET_HCD_DEBUG
- in order to increase the verbosity of the HCD. This API should be used only for
- debugging purposes. If multiple functions attempt to save and set the HCD debug
- level simultanously, the final debug level will be unknown. Not all HCDs support
- this command.
-
- @example: Example of saving the debug level:
- CT_DEBUG_LEVEL savedDebug;
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_GET_HCD_DEBUG,
- &savedDebug,
- sizeof(savedDebug));
-
- @see also: SDCONFIG_SET_HCD_DEBUG
- @see also: SDLIB_IssueConfig
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Set the debug level of the underlying host controller driver.
-
- @function name: SDCONFIG_SET_HCD_DEBUG
- @prototype: SDCONFIG_SET_HCD_DEBUG
- @category: PD_Reference
-
- @input: CT_DEBUG_LEVEL
-
- @output: none
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command
- sets the current debug level of the HCD driver. This API is useful for
- setting the debug level of the HCD programatically for debugging purposes.
- If multiple functions attempt to save and set the HCD debug
- level simultanously, the final debug level will be unknown. Not all HCDs support
- this request.
-
- @example: Example of setting the debug level:
- CT_DEBUG_LEVEL setDebug = 15;
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_GET_HCD_DEBUG,
- &setDebug,
- sizeof(setDebug));
-
- @see also: SDCONFIG_GET_HCD_DEBUG
- @see also: SDLIB_IssueConfig
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Instruct the bus driver to not check the SDIO card interrupt pending
- register on card interrupts, if possible.
-
- @function name: SDCONFIG_FUNC_NO_IRQ_PEND_CHECK
- @prototype: SDCONFIG_FUNC_NO_IRQ_PEND_CHECK
- @category: PD_Reference
-
- @input: none
-
- @output: none
-
- @return: SDIO Status
-
- @notes: This command code is used in the SDLIB_IssueConfig() API. The command instructs the
- bus driver to skip checking the card interrupt pending register on each card
- interrupt. The bus driver will assume the function is interrupting and immediately start
- the interrupt processing stage. This option is only valid for single function cards.
- The bus driver will reject the command for a card with more than 1 function.
- For single function cards, this can improve interrupt response time.
-
- @example: Example of skipping IRQ pending checks:
-
- status = SDLIB_IssueConfig(pInstance->pDevice,
- SDCONFIG_FUNC_NO_IRQ_PEND_CHECK,
- NULL,
- 0);
-
- @see also: SDLIB_IssueConfig
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
diff --git a/drivers/sdio/stack/busdriver/sdio_bus_events.c b/drivers/sdio/stack/busdriver/sdio_bus_events.c
deleted file mode 100644
index 5b3148d6752..00000000000
--- a/drivers/sdio/stack/busdriver/sdio_bus_events.c
+++ /dev/null
@@ -1,1040 +0,0 @@
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-@file: sdio_bus_events.c
-
-@abstract: OS independent bus driver support
-
-#notes: this file contains various event handlers and helpers
-
-@notice: Copyright (c), 2004-2006 Atheros Communications, Inc.
-
-
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Portions of this code were developed with information supplied from the
- * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
- *
- * The following conditions apply to the release of the SD simplified specification (�Simplified
- * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
- * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
- * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
- * Specification may require a license from the SD Card Association or other third parties.
- * Disclaimers:
- * The information contained in the Simplified Specification is presented only as a standard
- * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
- * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
- * any damages, any infringements of patents or other right of the SD Card Association or any third
- * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
- * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
- * be construed as an obligation by the SD Card Association to disclose or distribute any technical
- * information, know-how or other confidential information to any third party.
- *
- *
- * The initial developers of the original code are Seung Yi and Paul Lever
- *
- * sdio@atheros.com
- *
- *
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-#define MODULE_NAME SDBUSDRIVER
-#include <linux/sdio/ctsystem.h>
-#include <linux/sdio/sdio_busdriver.h>
-#include <linux/sdio/sdio_lib.h>
-#include "_busdriver.h"
-#include <linux/sdio/_sdio_defs.h>
-#include <linux/sdio/mmc_defs.h>
-
-static SDIO_STATUS ScanSlotForCard(PSDHCD pHcd,
- PBOOL pCardPresent);
-static void GetPendingIrqComplete(PSDREQUEST pReq);
-static void ProcessPendingIrqs(PSDHCD pHcd, UINT8 IntPendingMsk);
-
-/*
- * DeviceDetach - tell core a device was removed from a slot
-*/
-SDIO_STATUS DeviceDetach(PSDHCD pHcd)
-{
- SDCONFIG_SDIO_INT_CTRL_DATA irqData;
-
- ZERO_OBJECT(irqData);
-
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: DeviceDetach\n"));
- /* tell any function drivers we are gone */
- RemoveHcdFunctions(pHcd);
- /* delete the devices associated with this HCD */
- DeleteDevices(pHcd);
- /* check and see if there are any IRQs that were left enabled */
- if (pHcd->IrqsEnabled) {
- irqData.SlotIRQEnable = FALSE;
- /* turn off IRQ detection in HCD */
- _IssueConfig(pHcd,SDCONFIG_SDIO_INT_CTRL,(PVOID)&irqData, sizeof(irqData));
- }
-
- /* reset hcd state */
- ResetHcdState(pHcd);
-
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: DeviceDetach\n"));
- return SDIO_STATUS_SUCCESS;
-}
-
-/*
- * DeviceAttach - tell core a device was inserted into a slot
-*/
-SDIO_STATUS DeviceAttach(PSDHCD pHcd)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDDEVICE pDevice = NULL;
- UINT ii;
-
-
- if (IS_CARD_PRESENT(pHcd)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: DeviceAttach called on occupied slot!\n"));
- return SDIO_STATUS_ERROR;
- }
-
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: DeviceAttach bdctxt:0x%X \n", (UINT32)pBusContext));
-
- if (IS_HCD_RAW(pHcd)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: RAW HCD (%s) device attach \n",pHcd->pName));
- /* this is a raw HCD */
- memset(&pHcd->CardProperties,0,sizeof(pHcd->CardProperties));
- pHcd->CardProperties.Flags = CARD_RAW;
- pHcd->CardProperties.IOFnCount = 0;
- /* for raw HCD, set up minimum parameters
- * since we cannot determine these values using any standard, use values
- * reported by the HCD */
- /* the operational rate is just the max clock rate reported */
- pHcd->CardProperties.OperBusClock = pHcd->MaxClockRate;
- /* the max bytes per data transfer is just the max bytes per block */
- pHcd->CardProperties.OperBlockLenLimit = pHcd->MaxBytesPerBlock;
- /* if the raw HCD uses blocks to transfer, report the operational size
- * from the HCD max value */
- pHcd->CardProperties.OperBlockCountLimit = pHcd->MaxBlocksPerTrans;
- /* set the slot preferred voltage */
- pHcd->CardProperties.CardVoltage = pHcd->SlotVoltagePreferred;
- } else {
- /* initialize this card and get card properties */
- if (!SDIO_SUCCESS((status = SDInitializeCard(pHcd)))) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: DeviceAttach, failed to initialize card, %d\n",
- status));
- return status;
- }
- }
-
- /* check for SD or MMC, this must be done first as the query may involve
- * de-selecting the card */
- do {
- if (!(pHcd->CardProperties.Flags & (CARD_MMC | CARD_SD | CARD_RAW))) {
- /* none of these were discovered */
- break;
- }
- pDevice = AllocateDevice(pHcd);
- if (NULL == pDevice) {
- break;
- }
- if (pHcd->CardProperties.Flags & CARD_RAW) {
- /* set function number to 1 for IRQ processing */
- SDDEVICE_SET_SDIO_FUNCNO(pDevice,1);
- } else {
- /* get the ID info for the SD/MMC Card */
- if (!SDIO_SUCCESS((status = SDQuerySDMMCInfo(pDevice)))) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: DeviceAttach, query SDMMC Info failed \n"));
- FreeDevice(pDevice);
- break;
- }
- }
- AddDeviceToList(pDevice);
- /* look for a function driver to handle this card */
- ProbeForFunction(pDevice, pHcd);
- } while (FALSE);
-
- /* create a device for each I/O function */
- for(ii= 1; ii <= pHcd->CardProperties.IOFnCount; ii++) {
- pDevice = AllocateDevice(pHcd);
- if (NULL == pDevice) {
- break;
- }
- /* set the function number */
- SDDEVICE_SET_SDIO_FUNCNO(pDevice,ii);
- /* get the ID info for each I/O function */
- if (!SDIO_SUCCESS((status = SDQuerySDIOInfo(pDevice)))) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: DeviceAttach, could not query SDIO Info, funcNo:%d status:%d \n",
- ii, status));
- FreeDevice(pDevice);
- /* keep loading other functions */
- continue;
- }
- AddDeviceToList(pDevice);
- /* look for a function driver to handle this card */
- ProbeForFunction(pDevice, pHcd);
- }
-
-
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: DeviceAttach \n"));
- return status;
-}
-
-static INLINE void CompleteRequestCheckCancel(PSDHCD pHcd, PSDREQUEST pReqToComplete)
-{
- BOOL cancel = FALSE;
- PSDFUNCTION pFunc = NULL;
-
- /* handle cancel of current request */
- if (pReqToComplete->Flags & SDREQ_FLAGS_CANCELED) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - _SDIO_HandleHcdEvent: cancelling req 0X%X\n", (UINT)pReqToComplete));
- cancel = TRUE;
- pReqToComplete->Status = SDIO_STATUS_CANCELED;
- pFunc = pReqToComplete->pFunction;
- DBG_ASSERT(pFunc != NULL);
- }
-
- DoRequestCompletion(pReqToComplete, pHcd);
-
- if (cancel) {
- SignalSet(&pFunc->CleanupReqSig);
- }
-}
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Indicate to the SDIO bus driver (core) of an event in the host controller
- driver.
-
- @function name: SDIO_HandleHcdEvent
- @prototype: SDIO_STATUS SDIO_HandleHcdEvent(PSDHCD pHcd, HCD_EVENT Event)
- @category: HD_Reference
-
- @input: pHcd - the host controller structure that was registered
- HCD_EVENT - event code
-
- @output: none
-
- @return: SDIO_STATUS
-
- @notes:
- The host controller driver can indicate asynchronous events by calling this
- function with an appropriate event code. Refer to the HDK help manual for
- more information on the event types
-
- @example: Example of indicating a card insertion event:
- SDIO_HandleHcdEvent(&Hcd, EVENT_HCD_ATTACH);
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDIO_HandleHcdEvent(PSDHCD pHcd, HCD_EVENT Event)
-{
- PSDREQUEST pReq;
- PSDREQUEST pReqToComplete = NULL;
- PSDREQUEST pNextReq = NULL;
- SDIO_STATUS status;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- DBG_PRINT(SDIODBG_HCD_EVENTS, ("SDIO Bus Driver: _SDIO_HandleHcdEvent, event type 0x%X, HCD:0x%X\n",
- Event, (UINT)pHcd));
-
- if (Event == EVENT_HCD_TRANSFER_DONE) {
- pReq = GET_CURRENT_REQUEST(pHcd);
- if (NULL == pReq) {
- DBG_ASSERT(FALSE);
- return SDIO_STATUS_ERROR;
- }
-
- status = _AcquireHcdLock(pHcd);
- if (SDIO_SUCCESS(status)) {
- /* null out the current request */
- SET_CURRENT_REQUEST(pHcd, NULL);
- status = _ReleaseHcdLock(pHcd);
- } else {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: SDIO_HandleHcdEvent Failed to acquire HCD lock \n"));
- return SDIO_STATUS_ERROR;
- }
-
- /* note: the queue is still marked busy to prevent other threads/tasks from starting
- * new requests while we are handling completion , some completed requests are
- * marked as barrier requests which must be handled atomically */
-
- status = pReq->Status;
- DBG_PRINT(SDIODBG_REQUESTS,
- ("+SDIO Bus Driver: Handling Transfer Done (CMD:%d, Status:%d) from HCD:0x%08X \n",
- pReq->Command, status, (INT)pHcd));
- /* check SPI mode conversion */
- if (IS_HCD_BUS_MODE_SPI(pHcd) && SDIO_SUCCESS(status)) {
- if (!(pReq->Flags & SDREQ_FLAGS_RESP_SKIP_SPI_FILT) && !(pReq->Flags & SDREQ_FLAGS_PSEUDO) &&
- (GET_SDREQ_RESP_TYPE(pReq->Flags) != SDREQ_FLAGS_NO_RESP)) {
- ConvertSPI_Response(pReq, NULL);
- }
- }
-
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Completing Request:0x%08X \n",(INT)pReq));
-
- if (!SDIO_SUCCESS(status) &&
- (status != SDIO_STATUS_CANCELED) &&
- !(pReq->Flags & SDREQ_FLAGS_CANCELED) &&
- (pReq->RetryCount > 0)) {
- /* retry the request if it failed, was NOT cancelled and the retry count
- * is greater than zero */
- pReq->RetryCount--;
- pReqToComplete = NULL;
- /* clear SPI converted flag */
- pReq->Flags &= ~SDREQ_FLAGS_RESP_SPI_CONVERTED;
- pNextReq = pReq;
- } else {
- /* complete the request */
- if (pReq->Flags & SDREQ_FLAGS_BARRIER) {
- /* a barrier request must be completed before the next bus request is
- * started */
- CompleteRequestCheckCancel(pHcd, pReq);
- if (!ForceAllRequestsAsync()) {
- if (CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
- /* the request was completed, decrement recursion count */
- status = _AcquireHcdLock(pHcd);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
- pHcd->Recursion--;
- DBG_ASSERT(pHcd->Recursion >= 0);
- status = _ReleaseHcdLock(pHcd);
- } else {
- /* reset bit */
- AtomicTest_Clear(&pHcd->HcdFlags, HCD_REQUEST_CALL_BIT);
- }
- }
- pReqToComplete = NULL;
- } else {
- /* complete this after the next request has
- * been started */
- pReqToComplete = pReq;
- }
- }
-
- /* acquire the hcd lock to look at the queues */
- status = _AcquireHcdLock(pHcd);
- if (SDIO_SUCCESS(status)) {
- if (pReqToComplete != NULL) {
- /* queue the request that was completed */
- QueueRequest(&pHcd->CompletedRequestQueue, pReqToComplete);
- }
- if (NULL == pNextReq) {
- /* check the queue for the next request */
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Checking queue.. \n"));
- /* check to see if the HCD was already working on one. This occurs if
- * the current request being completed was a barrier request and the
- * barrier completion routine submitted a new request to the head of the
- * queue */
- if (GET_CURRENT_REQUEST(pHcd) == NULL) {
- pNextReq = DequeueRequest(&pHcd->RequestQueue);
- if (NULL == pNextReq) {
- /* nothing in the queue, mark it not busy */
- MarkQueueNotBusy(&pHcd->RequestQueue);
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Queue idle \n"));
- } else {
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Next request in queue: 0x%X \n",
- (INT)pNextReq));
- }
- } else {
- DBG_PRINT(SDIODBG_REQUESTS,
- ("SDIO Bus Driver: Busy Queue from barrier request \n"));
- }
- }
-
- if (pNextReq != NULL) {
- /* a new request will be submitted to the HCD below,
- * check recursion while we have the lock */
- if (CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
- CHECK_HCD_RECURSE(pHcd,pNextReq);
- }
- }
- status = _ReleaseHcdLock(pHcd);
- } else {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: SDIO_HandleHcdEvent Failed to acquire HCD lock \n"));
- return SDIO_STATUS_ERROR;
- }
- /* check for the next request to issue */
- if (pNextReq != NULL) {
- DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Starting Next Request: 0x%X \n",
- (INT)pNextReq));
- SET_CURRENT_REQUEST(pHcd,pNextReq);
- status = CallHcdRequest(pHcd);
- /* check and see if the HCD completed the request in the callback */
- if (status != SDIO_STATUS_PENDING) {
- /* recurse and process the request */
- _SDIO_HandleHcdEvent(pHcd, EVENT_HCD_TRANSFER_DONE);
- }
- }
-
- /* now empty the completed request queue
- * - this guarantees in-order completion even during recursion */
- status = _AcquireHcdLock(pHcd);
- if (SDIO_SUCCESS(status)) {
- while (1) {
- pReqToComplete = DequeueRequest(&pHcd->CompletedRequestQueue);
- status = _ReleaseHcdLock(pHcd);
- if (pReqToComplete != NULL) {
- CompleteRequestCheckCancel(pHcd, pReqToComplete);
- if (!CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
- if (!ForceAllRequestsAsync()) {
- /* reset bit */
- AtomicTest_Clear(&pHcd->HcdFlags, HCD_REQUEST_CALL_BIT);
- }
- }
- /* re-acquire lock */
- status = _AcquireHcdLock(pHcd);
- if (!SDIO_SUCCESS(status)) {
- return SDIO_STATUS_ERROR;
- }
- if (CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
- if (!ForceAllRequestsAsync()) {
- /* while we have the lock, decrement recursion count each time
- * we complete a request */
- pHcd->Recursion--;
- DBG_ASSERT(pHcd->Recursion >= 0);
- }
- }
- } else {
- /* we're done */
- break;
- }
- }
- } else {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: SDIO_HandleHcdEvent Failed to acquire HCD lock \n"));
- return SDIO_STATUS_ERROR;
- }
- DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: Transfer Done Handled \n"));
- return SDIO_STATUS_SUCCESS;
- }
-
- switch(Event) {
- case EVENT_HCD_ATTACH:
- case EVENT_HCD_DETACH:
- /* card detect helper does the actual attach detach */
- return PostCardDetectEvent(pBusContext,Event,pHcd);
- case EVENT_HCD_SDIO_IRQ_PENDING:
- return DeviceInterrupt(pHcd);
- default:
- DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: SDIO_HandleHcdEvent, invalid event type 0x%X, HCD:0x%X\n",
- Event, (UINT)pHcd));
- return SDIO_STATUS_INVALID_PARAMETER;
- }
-
-}
-
-/* card detect helper function */
-THREAD_RETURN CardDetectHelperFunction(POSKERNEL_HELPER pHelper)
-{
- SDIO_STATUS status;
- HCD_EVENT_MESSAGE message;
- INT length;
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - CardDetectHelperFunction starting up: 0x%X \n", (INT)pHelper));
-
- while (1) {
-
- /* wait for wake up event */
- status = SD_WAIT_FOR_WAKEUP(pHelper);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver - Card Detect Helper Semaphore Pend Error:%d \n",
- status));
- break;
- }
-
- if (SD_IS_HELPER_SHUTTING_DOWN(pHelper)) {
- /* cleanup message queue on shutdown */
- while (1) {
- length = sizeof(message);
- /* get a message */
- status = SDLIB_GetMessage(pBusContext->pCardDetectMsgQueue,
- &message, &length);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- if (message.pHcd != NULL) {
- /* decrement HCD reference count */
- OS_DecHcdReference(message.pHcd);
- }
- }
-
- break;
- }
-
- while (1) {
- length = sizeof(message);
- /* get a message */
- status = SDLIB_GetMessage(pBusContext->pCardDetectMsgQueue,
- &message, &length);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
-
- switch (message.Event) {
- case EVENT_HCD_ATTACH:
- DeviceAttach(message.pHcd);
- break;
- case EVENT_HCD_DETACH:
- DeviceDetach(message.pHcd);
- break;
- case EVENT_HCD_CD_POLLING:
- /* run detector */
- RunCardDetect();
- break;
- default:
- DBG_ASSERT(FALSE);
- break;
- }
-
- if (message.pHcd != NULL) {
- /* message was processed, decrement reference count */
- OS_DecHcdReference(message.pHcd);
- }
- }
- }
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - Card Detect Helper Exiting.. \n"));
- return 0;
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- RunCardDetect - run card detect on host controller slots that require polling
- Input:
- Output:
- Return:
- Notes: This function is called from the card detect timer thread
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void RunCardDetect(void)
-{
- BOOL CDPollingRequired = FALSE;
- PSDLIST pListItem;
- PSDHCD pHcd;
- BOOL cardPresent;
-
- DBG_PRINT(SDIODBG_CD_TIMER, ("+SDIO Bus Driver: RunCardDetect\n"));
-
- /* protect the HCD list */
- if (!SDIO_SUCCESS(SemaphorePendInterruptable(&pBusContext->HcdListSem))) {
- DBG_ASSERT(FALSE);
- return; /* wait interrupted */
- }
- /* while we are running the detector we are blocking HCD removal*/
- SDITERATE_OVER_LIST(&pBusContext->HcdList, pListItem) {
- pHcd = CONTAINING_STRUCT(pListItem, SDHCD, SDList);
- /* does the HCD require polling ? */
- if (pHcd->Attributes & SDHCD_ATTRIB_SLOT_POLLING) {
- DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO Bus Driver: Found HCD requiring polling \n"));
- /* set flag to queue the timer */
- CDPollingRequired = TRUE;
- if (IS_CARD_PRESENT(pHcd)) {
- /* there is a device in the slot */
- cardPresent = TRUE;
- if (SDIO_SUCCESS(ScanSlotForCard(pHcd,&cardPresent))) {
- if (!cardPresent) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver CD Polling.. Card Removal Detected\n"));
- DeviceDetach(pHcd);
- }
- }
- } else {
- cardPresent = FALSE;
- if (SDIO_SUCCESS(ScanSlotForCard(pHcd,&cardPresent))) {
- if (cardPresent) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver CD Polling.. Card Detected\n"));
- DeviceAttach(pHcd);
- }
- }
- }
- }
-
- DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO Bus Driver: moving to next hcd:0x%X \n",
- (INT)pListItem->pNext));
- }
-
- /* check if we need to queue the timer */
- if (CDPollingRequired && !pBusContext->CDTimerQueued) {
- pBusContext->CDTimerQueued = TRUE;
- DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO Bus Driver: Queuing Card detect timer \n"));
- if (!SDIO_SUCCESS(
- QueueTimer(SDIOBUS_CD_TIMER_ID, pBusContext->CDPollingInterval))) {
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: failed to queue CD timer \n"));
- pBusContext->CDTimerQueued = FALSE;
- }
- }
- /* release HCD list lock */
- SemaphorePost(&pBusContext->HcdListSem);
- DBG_PRINT(SDIODBG_CD_TIMER, ("-SDIO Bus Driver: RunCardDetect\n"));
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ScanSlotForCard - scan slot for a card
- Input: pHcd - the hcd
- Output: pCardPresent - card present flag (set/cleared on return)
- Return:
- Notes:
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static SDIO_STATUS ScanSlotForCard(PSDHCD pHcd,PBOOL pCardPresent)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- UINT8 temp;
-
- DBG_PRINT(SDIODBG_CD_TIMER, ("+SDIO Bus Driver: ScanSlotForCard\n"));
-
- do {
- if (!IS_CARD_PRESENT(pHcd)) {
- INT dbgLvl;
- dbgLvl = DBG_GET_DEBUG_LEVEL();
- DBG_SET_DEBUG_LEVEL(SDDBG_WARN);
- status = CardInitSetup(pHcd);
- DBG_SET_DEBUG_LEVEL(dbgLvl);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- /* issue go-idle */
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,NULL);
- } else {
- _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,NULL);
- }
- /* try SDIO */
- status = TestPresence(pHcd,CARD_SDIO,NULL);
- if (SDIO_SUCCESS(status)) {
- *pCardPresent = TRUE;
- break;
- }
- /* issue go-idle */
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,NULL);
- } else {
- _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,NULL);
- }
- /* try SD */
- status = TestPresence(pHcd,CARD_SD,NULL);
- if (SDIO_SUCCESS(status)) {
- *pCardPresent = TRUE;
- break;
- }
- /* issue go-idle */
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,NULL);
- } else {
- _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,NULL);
- }
- /* try MMC */
- status = TestPresence(pHcd,CARD_MMC,NULL);
- if (SDIO_SUCCESS(status)) {
- *pCardPresent = TRUE;
- break;
- }
- } else {
- if (pHcd->CardProperties.Flags & CARD_SDIO) {
-#ifdef DUMP_INT_PENDING
- temp = 0;
- /* handy debug prints to check interrupt status and print pending register */
- status = Cmd52ReadByteCommon(pHcd->pPseudoDev, SDIO_INT_ENABLE_REG, &temp);
- if (SDIO_SUCCESS(status) && (temp != 0)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: INT Enable Reg: 0x%2.2X\n", temp));
- status = Cmd52ReadByteCommon(pHcd->pPseudoDev, SDIO_INT_PENDING_REG, &temp);
- if (SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: INT Pend Reg: 0x%2.2X\n", temp));
- }
- }
-#endif
- /* for SDIO cards, read the revision register */
- status = Cmd52ReadByteCommon(pHcd->pPseudoDev, CCCR_SDIO_REVISION_REG, &temp);
- } else if (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC)) {
- /* for SD/MMC cards, issue SEND_STATUS */
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* SPI uses the SPI R2 response */
- status = _IssueSimpleBusRequest(pHcd,
- CMD13,
- 0,
- SDREQ_FLAGS_RESP_R2,
- NULL);
- } else {
- status = _IssueSimpleBusRequest(pHcd,
- CMD13,
- (pHcd->CardProperties.RCA << 16),
- SDREQ_FLAGS_RESP_R1,NULL);
- }
- } else {
- DBG_ASSERT(FALSE);
- }
- if (!SDIO_SUCCESS(status)) {
- /* card is gone */
- *pCardPresent = FALSE;
- }
- }
- } while (FALSE);
-
- if (status == SDIO_STATUS_BUS_RESP_TIMEOUT) {
- status = SDIO_STATUS_SUCCESS;
- }
-
- DBG_PRINT(SDIODBG_CD_TIMER, ("-SDIO Bus Driver: ScanSlotForCard status:%d\n",
- status));
-
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- DeviceInterrupt - handle device interrupt
- Input: pHcd - host controller
- Output:
- Return:
- Notes:
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS DeviceInterrupt(PSDHCD pHcd)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- SDIO_STATUS status2;
- PSDREQUEST pReq = NULL;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("+SDIO Bus Driver: DeviceInterrupt\n"));
-
- if (!IS_CARD_PRESENT(pHcd)) {
- DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: Device interrupt asserted on empty slot!\n"));
- return SDIO_STATUS_ERROR;
- }
-
- do {
- /* for RAW HCDs or HCDs flagged for single-function IRQ optimization */
- if (IS_HCD_RAW(pHcd) || (pHcd->HcdFlags & (1 << HCD_IRQ_NO_PEND_CHECK))) {
- status = _AcquireHcdLock(pHcd);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
- if (pHcd->IrqProcState != SDHCD_IDLE) {
- status = SDIO_STATUS_ERROR;
- status2 = _ReleaseHcdLock(pHcd);
- } else {
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver : Device Interrupt \n"));
- /* mark that we are processing */
- pHcd->IrqProcState = SDHCD_IRQ_PENDING;
- status2 = _ReleaseHcdLock(pHcd);
- /* process Irqs for raw hcds or HCDs with the single function optimization */
- /* force processing of function 1 interrupt */
- ProcessPendingIrqs(pHcd, (1 << 1));
- }
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("-SDIO Bus Driver: DeviceInterrupt: %d\n", status));
- /* done with RAW irqs */
- return status;
- }
-
- /* pre-allocate a request to get the pending bits, we have to do this outside the
- * hcd lock acquisition */
- pReq = AllocateRequest();
-
- if (NULL == pReq) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
-
- status = _AcquireHcdLock(pHcd);
-
- if (!SDIO_SUCCESS(status)) {
- break;
- }
-
- if (pHcd->IrqProcState != SDHCD_IDLE) {
- status = SDIO_STATUS_ERROR;
- } else {
- /* mark that we are processing */
- pHcd->IrqProcState = SDHCD_IRQ_PENDING;
- /* build argument to read IRQ pending register */
- SDIO_SET_CMD52_READ_ARG(pReq->Argument,0,SDIO_INT_PENDING_REG);
- pReq->Command = CMD52;
- pReq->Flags = SDREQ_FLAGS_TRANS_ASYNC | SDREQ_FLAGS_RESP_SDIO_R5;
- pReq->pCompleteContext = (PVOID)pHcd;
- pReq->pCompletion = GetPendingIrqComplete;
- pReq->RetryCount = SDBUS_MAX_RETRY;
- }
-
- status2 = _ReleaseHcdLock(pHcd);
-
- if (!SDIO_SUCCESS(status2)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: lock release error: %d\n", status2));
- }
-
- } while (FALSE);
-
- if (SDIO_SUCCESS(status)) {
- DBG_ASSERT(pReq != NULL);
- IssueRequestToHCD(pHcd,pReq);
- status = SDIO_STATUS_PENDING;
- } else {
- if (pReq != NULL) {
- FreeRequest(pReq);
- }
- }
-
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("-SDIO Bus Driver: DeviceInterrupt: %d\n", status));
- return status;
-}
-
-
-/* SDIO IRQ helper */
-THREAD_RETURN SDIOIrqHelperFunction(POSKERNEL_HELPER pHelper)
-{
- PSDHCD pHcd;
- SDIO_STATUS status;
- PSDLIST pListItem;
- PSDDEVICE pDevice;
- UINT8 funcMask;
- PSDDEVICE pDeviceIRQ[7];
- UINT deviceIrqCount = 0;
- UINT ii;
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - SDIOIrqHelperFunction starting up \n"));
-
- pHcd = (PSDHCD)pHelper->pContext;
- DBG_ASSERT(pHcd != NULL);
-
- while (1) {
-
- /* wait for wake up event */
- status = SD_WAIT_FOR_WAKEUP(pHelper);
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver - SDIOIrqHelperFunction Pend Error:%d \n",
- status));
- break;
- }
-
- if (SD_IS_HELPER_SHUTTING_DOWN(pHelper)) {
- break;
- }
-
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver - Pending IRQs:0x%X \n",
- pHcd->PendingHelperIrqs));
-
- /* take the device list lock as we iterate through the list, this blocks
- * device removals */
- status = SemaphorePendInterruptable(&pBusContext->DeviceListSem);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- /* walk through the device list matching HCD and interrupting function */
- SDITERATE_OVER_LIST(&pBusContext->DeviceList, pListItem) {
- pDevice = CONTAINING_STRUCT(pListItem, SDDEVICE, SDList);
- /* check if device belongs to the HCD */
- if (pDevice->pHcd != pHcd){
- /* not on this hcd */
- continue;
- }
- funcMask = 1 << SDDEVICE_GET_SDIO_FUNCNO(pDevice);
- /* check device function against the pending mask */
- if (!(funcMask & pHcd->PendingHelperIrqs)) {
- /* this one is not scheduled for the helper */
- continue;
- }
- /* clear bit */
- pHcd->PendingHelperIrqs &= ~funcMask;
- /* check for sync IRQ and call handler */
- if (pDevice->pIrqFunction != NULL) {
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: Calling IRQ Handler. Fn:%d\n",
- SDDEVICE_GET_SDIO_FUNCNO(pDevice)));
- /* save the device so we can process it without holding any locks */
- pDeviceIRQ[deviceIrqCount++] = pDevice;
- } else {
- /* this is actually okay if the device is removing, the callback
- * is NULLed out */
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: No IRQ handler Fn:%d\n",
- SDDEVICE_GET_SDIO_FUNCNO(pDevice)));
- }
- }
- /* should have handled all these */
- DBG_ASSERT(pHcd->PendingHelperIrqs == 0);
- pHcd->PendingHelperIrqs = 0;
- SemaphorePost(&pBusContext->DeviceListSem);
- for (ii = 0; ii < deviceIrqCount; ii++) {
- /* now call the function */
- SDDEVICE_CALL_IRQ_HANDLER(pDeviceIRQ[ii]);
- }
- deviceIrqCount = 0;
- }
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - SDIOIrqHelperFunction Exiting.. \n"));
- return 0;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- GetPendingIrqComplete - completion routine for getting pending IRQs
- Input: pRequest - completed request
- Output:
- Return:
- Notes:
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static void GetPendingIrqComplete(PSDREQUEST pReq)
-{
- UINT8 intPendingMsk;
- PSDHCD pHcd;
-
- do {
- pHcd = (PSDHCD)pReq->pCompleteContext;
- DBG_ASSERT(pHcd != NULL);
-
- if (!SDIO_SUCCESS(pReq->Status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get Interrupt pending register Err:%d\n",
- pReq->Status));
- break;
- }
-
- if (SD_R5_GET_RESP_FLAGS(pReq->Response) & SD_R5_ERRORS) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: CMD52 resp error: 0x%X \n",
- SD_R5_GET_RESP_FLAGS(pReq->Response)));
- break;
- }
- /* extract the pending mask */
- intPendingMsk = SD_R5_GET_READ_DATA(pReq->Response) & SDIO_INT_PEND_MASK;
- /* process them */
- ProcessPendingIrqs(pHcd, intPendingMsk);
-
- } while (FALSE);
-
- FreeRequest(pReq);
-
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("-SDIO Bus Driver: GetPendingIrqComplete \n"));
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ProcessPendingIrqs - processing pending Irqs
- Input: pHcd - host controller
- Input: IntPendingMsk - pending irq bit mask
- Output:
- Return:
- Notes:
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static void ProcessPendingIrqs(PSDHCD pHcd, UINT8 IntPendingMsk)
-{
- PSDLIST pListItem;
- PSDDEVICE pDevice;
- UINT8 funcMask;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("+SDIO Bus Driver: ProcessPendingIrqs \n"));
- do {
- /* acquire lock to protect configuration and irq enables */
- status = _AcquireHcdLock(pHcd);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
-
- /* sanity check */
- if ((IntPendingMsk & pHcd->IrqsEnabled) != IntPendingMsk) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: IRQs asserting when not enabled : curr:0x%X , card reports: 0x%X\n",
- pHcd->IrqsEnabled, IntPendingMsk));
- /* remove the pending IRQs that are not enabled */
- IntPendingMsk &= pHcd->IrqsEnabled;
- /* fall through */
- }
-
- if (!IntPendingMsk) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: No interrupts on HCD:0x%X \n", (INT)pHcd));
- pHcd->IrqProcState = SDHCD_IDLE;
- if (pHcd->IrqsEnabled) {
- /* only re-arm if there are IRQs enabled */
- _IssueConfig(pHcd,SDCONFIG_SDIO_REARM_INT,NULL,0);
- }
- status = _ReleaseHcdLock(pHcd);
- break;
- }
- /* reset helper IRQ bits */
- pHcd->PendingHelperIrqs = 0;
- /* save pending IRQ acks */
- pHcd->PendingIrqAcks = IntPendingMsk;
- status = _ReleaseHcdLock(pHcd);
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: INTs Pending - 0x%2.2X \n", IntPendingMsk));
- /* take the device list lock as we iterate through the list, this blocks
- * device removals */
- status = SemaphorePendInterruptable(&pBusContext->DeviceListSem);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- /* walk through the device list matching HCD and interrupting function */
- SDITERATE_OVER_LIST(&pBusContext->DeviceList, pListItem) {
- pDevice = CONTAINING_STRUCT(pListItem, SDDEVICE, SDList);
- /* check if device belongs to the HCD */
- if (pDevice->pHcd != pHcd){
- /* not on this hcd */
- continue;
- }
- funcMask = 1 << SDDEVICE_GET_SDIO_FUNCNO(pDevice);
- /* check device function against the pending mask */
- if (!(funcMask & IntPendingMsk)) {
- /* this one is not interrupting */
- continue;
- }
- /* check for async IRQ and call handler */
- if (pDevice->pIrqAsyncFunction != NULL) {
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: Calling Async IRQ Handler. Fn:%d\n",
- SDDEVICE_GET_SDIO_FUNCNO(pDevice)));
- SDDEVICE_CALL_IRQ_ASYNC_HANDLER(pDevice);
- } else {
- /* this one needs the helper */
- pHcd->PendingHelperIrqs |= funcMask;
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: No Async IRQ, Pending Helper Fn:%d\n",
- SDDEVICE_GET_SDIO_FUNCNO(pDevice)));
- }
- }
- /* release HCD list lock */
- SemaphorePost(&pBusContext->DeviceListSem);
- /* check for helper IRQs */
- if (pHcd->PendingHelperIrqs) {
- pHcd->IrqProcState = SDHCD_IRQ_HELPER;
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: Waking IRQ Helper \n"));
- if (!SDIO_SUCCESS(SD_WAKE_OS_HELPER(&pHcd->SDIOIrqHelper))) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: failed to wake helper! \n"));
- }
- }
- } while (FALSE);
-
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("-SDIO Bus Driver: ProcessPendingIrqs \n"));
-}
-
-SDIO_STATUS TryNoIrqPendingCheck(PSDDEVICE pDevice)
-{
- if (pDevice->pHcd->CardProperties.IOFnCount > 1) {
- /* not supported on multi-function cards */
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: IRQ Pending Check cannot be bypassed, (Funcs:%d)\n",
- pDevice->pHcd->CardProperties.IOFnCount));
- return SDIO_STATUS_UNSUPPORTED;
- }
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: pending IRQ check bypassed \n"));
- /* set flag to optimize this */
- AtomicTest_Set(&pDevice->pHcd->HcdFlags, HCD_IRQ_NO_PEND_CHECK);
- return SDIO_STATUS_SUCCESS;
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SDIO_NotifyTimerTriggered - notification handler that a timer expired
- Input: TimerID - ID of timer that expired
- Output:
- Return:
- Notes:
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void SDIO_NotifyTimerTriggered(INT TimerID)
-{
-
- switch (TimerID) {
- case SDIOBUS_CD_TIMER_ID:
- pBusContext->CDTimerQueued = FALSE;
- /* post an HCD polling event to the helper thread */
- PostCardDetectEvent(pBusContext, EVENT_HCD_CD_POLLING, NULL);
- break;
- default:
- DBG_ASSERT(FALSE);
- }
-
-}
diff --git a/drivers/sdio/stack/busdriver/sdio_bus_misc.c b/drivers/sdio/stack/busdriver/sdio_bus_misc.c
deleted file mode 100644
index d89a5962270..00000000000
--- a/drivers/sdio/stack/busdriver/sdio_bus_misc.c
+++ /dev/null
@@ -1,3122 +0,0 @@
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-@file: sdio_bus_misc.c
-
-@abstract: OS independent bus driver support
-
-#notes: this file contains miscellaneous control functions
-
-@notice: Copyright (c), 2004-2006 Atheros Communications, Inc.
-
-
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Portions of this code were developed with information supplied from the
- * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
- *
- * The following conditions apply to the release of the SD simplified specification (�Simplified
- * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
- * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
- * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
- * Specification may require a license from the SD Card Association or other third parties.
- * Disclaimers:
- * The information contained in the Simplified Specification is presented only as a standard
- * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
- * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
- * any damages, any infringements of patents or other right of the SD Card Association or any third
- * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
- * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
- * be construed as an obligation by the SD Card Association to disclose or distribute any technical
- * information, know-how or other confidential information to any third party.
- *
- *
- * The initial developers of the original code are Seung Yi and Paul Lever
- *
- * sdio@atheros.com
- *
- *
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-#define MODULE_NAME SDBUSDRIVER
-#include <linux/sdio/ctsystem.h>
-#include <linux/sdio/sdio_busdriver.h>
-#include <linux/sdio/sdio_lib.h>
-#include "_busdriver.h"
-#include <linux/sdio/_sdio_defs.h>
-#include <linux/sdio/mmc_defs.h>
-
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- IssueBusRequestBd - issue a bus request
- Input: pHcd - HCD object
- Cmd - command to issue
- Argument - command argument
- Flags - request flags
-
- Output: pReqToUse - request to use (if caller wants response data)
- Return: SDIO Status
- Notes: This function only issues 1 block data transfers
- This function issues the request synchronously
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _IssueBusRequestBd(PSDHCD pHcd,
- UINT8 Cmd,
- UINT32 Argument,
- SDREQUEST_FLAGS Flags,
- PSDREQUEST pReqToUse,
- PVOID pData,
- INT Length)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDREQUEST pReq;
-
- if (NULL == pReqToUse) {
- /* caller doesn't care about the response data, allocate locally */
- pReq = AllocateRequest();
- if (NULL == pReq) {
- return SDIO_STATUS_NO_RESOURCES;
- }
- } else {
- /* use the caller's request buffer */
- pReq = pReqToUse;
- }
-
- pReq->Argument = Argument;
- pReq->Flags = Flags;
- pReq->Command = Cmd;
- if (pReq->Flags & SDREQ_FLAGS_DATA_TRANS) {
- pReq->pDataBuffer = pData;
- pReq->BlockCount = 1;
- pReq->BlockLen = Length;
- }
-
- status = IssueRequestToHCD(pHcd,pReq);
-
- if (NULL == pReqToUse) {
- DBG_ASSERT(pReq != NULL);
- FreeRequest(pReq);
- }
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ConvertVoltageCapsToOCRMask - initialize card
- Input: VoltageCaps - voltage cap to look up
- Return: 32 bit OCR mask
- Notes: this function sets voltage for +- 10%
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static UINT32 ConvertVoltageCapsToOCRMask(SLOT_VOLTAGE_MASK VoltageCaps)
-{
- UINT32 ocrMask;
-
- ocrMask = 0;
-
- if (VoltageCaps & SLOT_POWER_3_3V) {
- ocrMask |= SD_OCR_3_2_TO_3_3_VDD | SD_OCR_3_3_TO_3_4_VDD;
- }
- if (VoltageCaps & SLOT_POWER_3_0V) {
- ocrMask |= SD_OCR_2_9_TO_3_0_VDD | SD_OCR_3_0_TO_3_1_VDD;
- }
- if (VoltageCaps & SLOT_POWER_2_8V) {
- ocrMask |= SD_OCR_2_7_TO_2_8_VDD | SD_OCR_2_8_TO_2_9_VDD;
- }
- if (VoltageCaps & SLOT_POWER_2_0V) {
- ocrMask |= SD_OCR_1_9_TO_2_0_VDD | SD_OCR_2_0_TO_2_1_VDD;
- }
- if (VoltageCaps & SLOT_POWER_1_8V) {
- ocrMask |= SD_OCR_1_7_TO_1_8_VDD | SD_OCR_1_8_TO_1_9_VDD;
- }
- if (VoltageCaps & SLOT_POWER_1_6V) {
- ocrMask |= SD_OCR_1_6_TO_1_7_VDD;
- }
-
- return ocrMask;
-}
-
-static UINT32 GetUsableOCRValue(UINT32 CardOCR, UINT32 SlotOCRMask)
-{
- INT i;
- UINT32 mask = 0;
-
- for (i = 0; i < 32; i++) {
- mask = 1 << i;
- if ((SlotOCRMask & mask) && (CardOCR & mask)) {
- return mask;
- }
- }
-
- return mask;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- GetPowerSetting - power up the SDIO card
- Input: pHcd - HCD object
- pOCRvalue - OCR value of the card
- Output: pOCRvalue - OCR to actually use
- Return: power setting for HCD based on card's OCR, zero indicates unsupported
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static SLOT_VOLTAGE_MASK GetPowerSetting(PSDHCD pHcd, UINT32 *pOCRvalue)
-{
- UINT32 ocrMask;
- SLOT_VOLTAGE_MASK hcdVoltage = 0;
- SLOT_VOLTAGE_MASK hcdVMask;
- INT i;
-
- /* check preferred value */
- ocrMask = ConvertVoltageCapsToOCRMask(pHcd->SlotVoltagePreferred);
- if (ocrMask & *pOCRvalue) {
- /* using preferred voltage */
- *pOCRvalue = GetUsableOCRValue(*pOCRvalue, ocrMask);
- hcdVoltage = pHcd->SlotVoltagePreferred;
- } else {
- /* walk through the slot voltage caps and find a match */
- for (i = 0; i < 8; i++) {
- hcdVMask = (1 << i);
- if (hcdVMask & pHcd->SlotVoltageCaps) {
- ocrMask = ConvertVoltageCapsToOCRMask((SLOT_VOLTAGE_MASK)(pHcd->SlotVoltageCaps & hcdVMask));
- if (ocrMask & *pOCRvalue) {
- /* found a match */
- *pOCRvalue = GetUsableOCRValue(*pOCRvalue, ocrMask);
- hcdVoltage = pHcd->SlotVoltageCaps & hcdVMask;
- break;
- }
- }
- }
- }
-
- return hcdVoltage;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- TestPresence - test the presence of a card/function
- Input: pHcd - HCD object
- TestType - type of test to perform
- Output: pReq - Request to use (optional)
- Return:
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS TestPresence(PSDHCD pHcd,
- CARD_INFO_FLAGS TestType,
- PSDREQUEST pReq)
-{
- SDIO_STATUS status = SDIO_STATUS_ERROR;
-
- switch (TestType) {
- case CARD_SDIO:
- /* issue CMD5 */
- status = _IssueSimpleBusRequest(pHcd,CMD5,0,
- SDREQ_FLAGS_RESP_SDIO_R4 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT,pReq);
- break;
- case CARD_SD:
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* ACMD41 just starts initialization when in SPI mode, argument is ignored
- * Note: In SPI mode ACMD41 uses an R1 response */
- status = _IssueSimpleBusRequest(pHcd,ACMD41,0,
- SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R1,pReq);
-
- } else {
- /* issue ACMD41 with OCR value of zero */
- /* ACMD41 on SD uses an R3 response */
- status = _IssueSimpleBusRequest(pHcd,ACMD41,0,
- SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R3,pReq);
- }
- break;
- case CARD_MMC:
- /* issue CMD1 */
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* note: in SPI mode an R1 response is used */
- status = _IssueSimpleBusRequest(pHcd,CMD1,0,SDREQ_FLAGS_RESP_R1,pReq);
- } else {
- status = _IssueSimpleBusRequest(pHcd,CMD1,0,SDREQ_FLAGS_RESP_R3,pReq);
- }
- break;
- default:
- DBG_ASSERT(FALSE);
- break;
- }
-
- return status;
-}
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ReadOCR - read the OCR
- Input: pHcd - HCD object
- ReadType - type of read to perform
- OCRValue - OCR value to use as an argument
- Output: pReq - Request to use
- pOCRValueRd - OCR value read back (can be NULL)
- Return:
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static SDIO_STATUS ReadOCR(PSDHCD pHcd,
- CARD_INFO_FLAGS ReadType,
- PSDREQUEST pReq,
- UINT32 OCRValue,
- UINT32 *pOCRValueRd)
-{
- SDIO_STATUS status = SDIO_STATUS_ERROR;
-
- switch (ReadType) {
- case CARD_SDIO:
- /* CMD5 for SDIO cards */
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* skip the SPI filter, we will decode the response here */
- status = _IssueSimpleBusRequest(pHcd,CMD5,
- OCRValue,
- SDREQ_FLAGS_RESP_SDIO_R4 |
- SDREQ_FLAGS_RESP_SKIP_SPI_FILT,
- pReq);
- } else {
- /* native SD */
- status = _IssueSimpleBusRequest(pHcd,CMD5,
- OCRValue,
- SDREQ_FLAGS_RESP_SDIO_R4,
- pReq);
- }
- break;
- case CARD_SD:
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* CMD58 is used to read the OCR */
- status = _IssueSimpleBusRequest(pHcd,CMD58,
- 0, /* argument ignored */
- (SDREQ_FLAGS_RESP_R3 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT),
- pReq);
- } else {
- /* SD Native uses ACMD41 */
- status = _IssueSimpleBusRequest(pHcd,ACMD41,
- OCRValue,
- SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R3,
- pReq);
- }
- break;
- case CARD_MMC:
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* CMD58 is used to read the OCR */
- status = _IssueSimpleBusRequest(pHcd,CMD58,
- 0, /* argument ignored */
- (SDREQ_FLAGS_RESP_R3 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT),
- pReq);
- } else {
- /* MMC Native uses CMD1 */
- status = _IssueSimpleBusRequest(pHcd,CMD1,
- OCRValue, SDREQ_FLAGS_RESP_R3,
- pReq);
- }
- break;
- default:
- DBG_ASSERT(FALSE);
- break;
- }
-
- if (SDIO_SUCCESS(status) && (pOCRValueRd != NULL)) {
- *pOCRValueRd = 0;
- /* someone wants the OCR read back */
- switch (ReadType) {
- case CARD_SDIO:
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- *pOCRValueRd = SPI_SDIO_R4_GET_OCR(pReq->Response);
- } else {
- *pOCRValueRd = SD_SDIO_R4_GET_OCR(pReq->Response);
- }
- break;
- case CARD_SD:
- case CARD_MMC:
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- *pOCRValueRd = SPI_R3_GET_OCR(pReq->Response);
- } else {
- *pOCRValueRd = SD_R3_GET_OCR(pReq->Response);
- }
- break;
- default:
- DBG_ASSERT(FALSE);
- break;
- }
- }
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- PollCardReady - poll card till it's ready
- Input: pHcd - HCD object
- OCRValue - OCR value to poll with
- PollType - polling type (based on card type)
- Output:
- Return:
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS PollCardReady(PSDHCD pHcd, UINT32 OCRValue, CARD_INFO_FLAGS PollType)
-{
- INT cardReadyRetry;
- SDIO_STATUS status;
- PSDREQUEST pReq;
-
- if (!((PollType == CARD_SDIO) || (PollType == CARD_SD) || (PollType == CARD_MMC))) {
- DBG_ASSERT(FALSE);
- return SDIO_STATUS_INVALID_PARAMETER;
- }
-
- pReq = AllocateRequest();
- if (NULL == pReq) {
- return SDIO_STATUS_NO_RESOURCES;
- }
-
- status = SDIO_STATUS_SUCCESS;
- cardReadyRetry = pBusContext->CardReadyPollingRetry;
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Polling card ready, Using OCR:0x%8.8X, Poll Type:0x%X\n",
- OCRValue,PollType));
-
- /* now issue CMD with the actual OCR as an argument until the card is ready */
- while (cardReadyRetry) {
- if (IS_HCD_BUS_MODE_SPI(pHcd) && !(PollType == CARD_SDIO)) {
- if (PollType == CARD_MMC) {
- /* under SPI mode for MMC cards, we need to issue CMD1 and
- * check the response for the "in-idle" bit */
- status = _IssueSimpleBusRequest(pHcd,
- CMD1,
- 0,
- SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT,
- pReq);
- } else if (PollType == CARD_SD) {
- /* under SPI mode for SD cards, we need to issue ACMD41 and
- * check the response for the "in-idle" bit */
- status = _IssueSimpleBusRequest(pHcd,
- ACMD41,
- 0,
- SDREQ_FLAGS_RESP_R1 |
- SDREQ_FLAGS_APP_CMD |
- SDREQ_FLAGS_RESP_SKIP_SPI_FILT,
- pReq);
- } else {
- DBG_ASSERT(FALSE);
- }
- } else {
- /* for SD/MMC in native mode and SDIO (all modes) we need to read the OCR register */
- /* read the OCR using the supplied OCR value as an argument, we don't care about the
- * actual OCR read-back, but we are interested in the response */
- status = ReadOCR(pHcd,PollType,pReq,OCRValue,NULL);
- }
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to issue CMD to poll ready \n"));
- break;
- }
- if (PollType == CARD_SDIO) {
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- if (SPI_SDIO_R4_IS_CARD_READY(pReq->Response)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SDIO Card Ready! (SPI) \n"));
- break;
- }
- } else {
- if (SD_SDIO_R4_IS_CARD_READY(pReq->Response)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SDIO Card Ready! \n"));
- break;
- }
- }
- } else if ((PollType == CARD_SD) || (PollType == CARD_MMC)) {
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* check response when MMC or SD cards operate in SPI mode */
- if (!(GET_SPI_R1_RESP_TOKEN(pReq->Response) & SPI_CS_STATE_IDLE)) {
- /* card is no longer in idle */
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD/MMC Card (SPI mode) is ready! \n"));
- break;
- }
- } else {
- /* check the OCR busy bit */
- if (SD_R3_IS_CARD_READY(pReq->Response)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD/MMC (Native Mode) Card Ready! \n"));
- break;
- }
- }
- } else {
- DBG_ASSERT(FALSE);
- }
- cardReadyRetry--;
- /* delay */
- status = OSSleep(OCR_READY_CHECK_DELAY_MS);
- if (!SDIO_SUCCESS(status)){
- break;
- }
- }
-
- if (0 == cardReadyRetry) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Card Ready timeout! \n"));
- status = SDIO_STATUS_DEVICE_ERROR;
- }
-
- FreeRequest(pReq);
-
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- AdjustSlotPower - adjust slot power
- Input: pHcd - HCD object
- Output: pOCRvalue - ocr value to use
- Return:
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static SDIO_STATUS AdjustSlotPower(PSDHCD pHcd, UINT32 *pOCRvalue)
-{
- SDCONFIG_POWER_CTRL_DATA pwrSetting;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- ZERO_OBJECT(pwrSetting);
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO Bus Driver: Adjusting Slot Power, Requesting adjustment for OCR:0x%8.8X \n",
- *pOCRvalue));
-
- do {
- pwrSetting.SlotPowerEnable = TRUE;
- /* get optimal power setting */
- pwrSetting.SlotPowerVoltageMask = GetPowerSetting(pHcd, pOCRvalue);
- if (0 == pwrSetting.SlotPowerVoltageMask) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: No matching voltage for OCR \n"));
- status = SDIO_STATUS_DEVICE_ERROR;
- break;
- }
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Slot Pwr Mask 0x%X for OCR:0x%8.8X \n",
- pwrSetting.SlotPowerVoltageMask,*pOCRvalue));
- status = _IssueConfig(pHcd,SDCONFIG_POWER_CTRL,&pwrSetting,sizeof(pwrSetting));
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set power in hcd \n"));
- break;
- }
- /* delay for power to settle */
- OSSleep(pBusContext->PowerSettleDelay);
- /* save off for drivers */
- pHcd->CardProperties.CardVoltage = pwrSetting.SlotPowerVoltageMask;
-
- } while (FALSE);
-
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ConvertEncodedTransSpeed - convert encoded TRANS_SPEED value to a clock rate
- Input: TransSpeedValue - encoded transfer speed value
- Output:
- Return: appropriate SD clock rate
- Notes: This function returns a rate of 0, if it could not be determined.
- This function can check tran speed values for SD,SDIO and MMC cards
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static SD_BUSCLOCK_RATE ConvertEncodedTransSpeed(UINT8 TransSpeedValue)
-{
- SD_BUSCLOCK_RATE transfMul = 0;
- UINT8 timeVal = 0;
-
- switch (TransSpeedValue & TRANSFER_UNIT_MULTIPIER_MASK) {
- case 0:
- transfMul = 10000;
- break;
- case 1:
- transfMul = 100000;
- break;
- case 2:
- transfMul = 1000000;
- break;
- case 3:
- transfMul = 10000000;
- break;
- default:
- transfMul = 0;
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Card transfer multipler is wrong (val=0x%X)! \n",
- TransSpeedValue));
- break;
- }
-
- switch ((TransSpeedValue & TIME_VALUE_MASK) >> TIME_VALUE_SHIFT) {
- case 1: timeVal = 10; break;
- case 2: timeVal = 12; break;
- case 3: timeVal = 13; break;
- case 4: timeVal = 15; break;
- case 5: timeVal = 20; break;
- case 6: timeVal = 25; break;
- case 7: timeVal = 30; break;
- case 8: timeVal = 35; break;
- case 9: timeVal = 40; break;
- case 10: timeVal = 45; break;
- case 11: timeVal = 50; break;
- case 12: timeVal = 55; break;
- case 13: timeVal = 60; break;
- case 14: timeVal = 70; break;
- case 15: timeVal = 80; break;
- default: timeVal = 0;
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Card time value is wrong (val=0x%X)! \n",
- TransSpeedValue));
- break;
- }
-
- if ((transfMul != 0) && (timeVal != 0)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Card Reported Max: %d Hz (0x%X) \n",
- (timeVal*transfMul), TransSpeedValue));
- return timeVal*transfMul;
- }
-
- return 0;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SelectDeselectCard - Select or deselect a card
- Input: pHcd - HCD object
- Select - select the card
- Output:
- Return: status
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static SDIO_STATUS SelectDeselectCard(PSDHCD pHcd, BOOL Select)
-{
- SDIO_STATUS status;
-
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* SPI mode cards do not support selection */
- status = SDIO_STATUS_SUCCESS;
- } else {
- if (!Select) {
- /* deselect, note that deselecting a card does not return a response */
- status = _IssueSimpleBusRequest(pHcd,
- CMD7,0,
- SDREQ_FLAGS_NO_RESP,NULL);
- } else {
- /* select */
- status = _IssueSimpleBusRequest(pHcd,
- CMD7,(pHcd->CardProperties.RCA << 16),
- SDREQ_FLAGS_RESP_R1B,NULL);
- }
- }
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Failed to %s card, RCA:0x%X Err:%d \n",
- (Select ? "Select":"Deselect"), pHcd->CardProperties.RCA, status));
- }
- return status;
-}
-
-/* reorder a buffer by swapping MSB with LSB */
-static void ReorderBuffer(UINT8 *pBuffer, INT Bytes)
-{
- UINT8 *pEnd;
- UINT8 temp;
-
- DBG_ASSERT(!(Bytes & 1));
- /* point to the end */
- pEnd = &pBuffer[Bytes - 1];
- /* divide in half */
- Bytes = Bytes >> 1;
-
- while (Bytes) {
- temp = *pBuffer;
- /* swap bytes */
- *pBuffer = *pEnd;
- *pEnd = temp;
- pBuffer++;
- pEnd--;
- Bytes--;
- }
-}
-
-#define ADJUST_OPER_CLOCK(pBusMode,Clock) \
- (pBusMode)->ClockRate = min((SD_BUSCLOCK_RATE)(Clock),(pBusMode)->ClockRate)
-#define ADJUST_OPER_BLOCK_LEN(pCaps,Length) \
- (pCaps)->OperBlockLenLimit = min((UINT16)(Length),(pCaps)->OperBlockLenLimit)
-#define ADJUST_OPER_BLOCK_COUNT(pCaps,Count) \
- (pCaps)->OperBlockCountLimit = min((UINT16)(Count),(pCaps)->OperBlockCountLimit)
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- GetBusParameters - Get bus parameters for a card
- Input: pHcd - HCD object
- pBusMode - current bus mode on entry
- Output: pBusMode - new adjusted bus mode
- Return: status
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-static SDIO_STATUS GetBusParameters(PSDHCD pHcd, PSDCONFIG_BUS_MODE_DATA pBusMode)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- UINT8 temp;
- UINT32 tplAddr;
- struct SDIO_FUNC_EXT_COMMON_TPL func0ext;
- UINT8 scrRegister[SD_SCR_BYTES];
- SD_BUSCLOCK_RATE cardReportedRate = 0;
- PSDREQUEST pReq = NULL;
- BOOL spiMode = FALSE;
-
-
- if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_SPI) {
- spiMode = TRUE;
- }
-
- if (!spiMode) {
- /* set highest bus mode bus driver is allowing (non-SPI), the code below will
- * adjust to lower or equal settings */
- pBusMode->BusModeFlags = pBusContext->DefaultBusMode;
- }
- /* set operational parameters */
- pBusMode->ClockRate = pBusContext->DefaultOperClock;
- pHcd->CardProperties.OperBlockLenLimit = pBusContext->DefaultOperBlockLen;
- pHcd->CardProperties.OperBlockCountLimit = pBusContext->DefaultOperBlockCount;
-
- /* adjust operational block counts and length to match HCD */
- ADJUST_OPER_BLOCK_LEN(&pHcd->CardProperties,pHcd->MaxBytesPerBlock);
- ADJUST_OPER_BLOCK_COUNT(&pHcd->CardProperties,pHcd->MaxBlocksPerTrans);
- /* limit operational clock to the max clock rate */
- ADJUST_OPER_CLOCK(pBusMode,pHcd->MaxClockRate);
-
- if (!spiMode) {
- /* check HCD bus mode */
- if (!(pHcd->Attributes & SDHCD_ATTRIB_BUS_4BIT) ||
- ((pHcd->CardProperties.Flags & CARD_SDIO) &&
- (pHcd->Attributes & SDHCD_ATTRIB_NO_4BIT_IRQ)) ) {
-
- if (pHcd->Attributes & SDHCD_ATTRIB_BUS_4BIT) {
- DBG_PRINT(SDDBG_WARN,
- ("SDIO Card Detected, but host does not support IRQs in 4 bit mode - dropping to 1 bit. \n"));
- }
- /* force to 1 bit mode */
- SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);
- }
- }
-
- /* now do various card inquiries to drop the bus mode or clock
- * none of these checks can raise the bus mode or clock higher that what
- * was initialized above */
- do {
- if (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC)) {
- /* allocate a request for response data we'll need */
- pReq = AllocateRequest();
- if (NULL == pReq) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
- }
-
- if (!spiMode && (pHcd->CardProperties.Flags & CARD_MMC)) {
- /* MMC cards all run in 1 bit mode */
- SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);
- }
-
- if (pHcd->CardProperties.Flags & CARD_SD) {
- DBG_ASSERT(pReq != NULL);
- DBG_PRINT(SDDBG_TRACE, ("Getting SCR from SD Card..\n"));
- /* read SCR (requires data transfer) to get supported modes */
- status = _IssueBusRequestBd(pHcd,ACMD51,0,
- SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_APP_CMD |
- SDREQ_FLAGS_DATA_TRANS,
- pReq,&scrRegister,SD_SCR_BYTES);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_WARN, ("SD card does not have SCR. \n"));
- if (!spiMode) {
- /* switch it to 1 bit mode */
- SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);
- }
- status = SDIO_STATUS_SUCCESS;
- } else {
- /* we have to reorder this buffer since the SCR is sent MSB first on the data
- * data bus */
- ReorderBuffer(scrRegister,SD_SCR_BYTES);
- /* got the SCR */
- DBG_PRINT(SDDBG_TRACE, ("SD SCR StructRev:0x%X, Flags:0x%X \n",
- GET_SD_SCR_STRUCT_VER(scrRegister),
- GET_SD_SCR_BUSWIDTHS_FLAGS(scrRegister)));
- /* set the revision */
- switch (GET_SD_SCR_SDSPEC_VER(scrRegister)) {
- case SCR_SD_SPEC_1_00:
- DBG_PRINT(SDDBG_TRACE, ("SD Spec Revision 1.01 \n"));
- pHcd->CardProperties.SD_MMC_Revision = SD_REVISION_1_01;
- break;
- case SCR_SD_SPEC_1_10:
- DBG_PRINT(SDDBG_TRACE, ("SD Spec Revision 1.10 \n"));
- pHcd->CardProperties.SD_MMC_Revision = SD_REVISION_1_10;
- break;
- default:
- DBG_PRINT(SDDBG_WARN, ("SD Spec Revision is greater than 1.10 \n"));
- pHcd->CardProperties.SD_MMC_Revision = SD_REVISION_1_10;
- break;
- }
-
- if (!(GET_SD_SCR_BUSWIDTHS(scrRegister) & SCR_BUS_SUPPORTS_4_BIT)) {
- if (!spiMode) {
- DBG_PRINT(SDDBG_WARN, ("SD SCR reports 1bit only Mode \n"));
- /* switch it to 1 bit mode */
- SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);
- }
- }
- }
- }
-
- if (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC)) {
- DBG_ASSERT(pReq != NULL);
- /* de-select the card in order to get the CSD */
- status = SelectDeselectCard(pHcd,FALSE);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to deselect card before getting CSD \n"));
- break;
- }
- /* Get CSD for SD or MMC cards */
- if (spiMode) {
- /* in SPI mode, getting the CSD requires a read data transfer */
- status = _IssueBusRequestBd(pHcd,CMD9,0,
- SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,
- pReq,
- pHcd->CardProperties.CardCSD,
- MAX_CSD_CID_BYTES);
- if (SDIO_SUCCESS(status)) {
- /* when the CSD is sent over in SPI data mode, it comes to us in MSB first
- * and thus is not ordered correctly as defined in the SD spec */
- ReorderBuffer(pHcd->CardProperties.CardCSD,MAX_CSD_CID_BYTES);
- }
- } else {
- status = _IssueSimpleBusRequest(pHcd,
- CMD9,
- (pHcd->CardProperties.RCA << 16),
- SDREQ_FLAGS_RESP_R2,
- pReq);
- if (SDIO_SUCCESS(status)) {
- /* save the CSD */
- memcpy(pHcd->CardProperties.CardCSD,pReq->Response,MAX_CARD_RESPONSE_BYTES);
- }
- }
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get CSD, Err:%d \n",
- status));
- break;
- }
- /* for MMC cards, the spec version is in the CSD */
- if (pHcd->CardProperties.Flags & CARD_MMC) {
- DBG_PRINT(SDDBG_TRACE, ("MMC Spec version : (0x%2.2X) \n",
- GET_MMC_SPEC_VERSION(pHcd->CardProperties.CardCSD)));
- switch (GET_MMC_SPEC_VERSION(pHcd->CardProperties.CardCSD)) {
- case MMC_SPEC_1_0_TO_1_2:
- case MMC_SPEC_1_4:
- case MMC_SPEC_2_0_TO_2_2:
- DBG_PRINT(SDDBG_WARN, ("MMC Spec version less than 3.1 \n"));
- pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_1_0_2_2;
- break;
- case MMC_SPEC_3_1:
- DBG_PRINT(SDDBG_TRACE, ("MMC Spec version 3.1 \n"));
- pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_3_1;
- break;
- case MMC_SPEC_4_0_TO_4_1:
- DBG_PRINT(SDDBG_TRACE, ("MMC Spec version 4.0-4.1 \n"));
- pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_4_0;
- break;
- default:
- pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_3_1;
- DBG_PRINT(SDDBG_WARN, ("MMC Spec version greater than 4.1\n"));
- break;
- }
- }
- /* re-select the card */
- status = SelectDeselectCard(pHcd,TRUE);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to re-select card after getting CSD \n"));
- break;
- }
- }
-
- if ((pHcd->CardProperties.Flags & CARD_SD) &&
- !(pHcd->CardProperties.Flags & CARD_SDIO) &&
- SDDEVICE_IS_SD_REV_GTEQ_1_10(pHcd->pPseudoDev) &&
- (pHcd->Attributes & SDHCD_ATTRIB_SD_HIGH_SPEED) &&
- !spiMode) {
- UINT32 arg;
- PUINT8 pSwitchStatusBlock = KernelAlloc(SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
-
- if (NULL == pSwitchStatusBlock) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
-
- arg = SD_SWITCH_FUNC_ARG_GROUP_CHECK(SD_SWITCH_HIGH_SPEED_GROUP,
- SD_SWITCH_HIGH_SPEED_FUNC_NO);
-
- /* for 1.10 SD cards, check if high speed mode is supported */
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Checking SD Card for switchable functions (CMD6 arg:0x%X)\n",arg));
-
- /* issue simple data transfer request to read the switch status */
- status = _IssueBusRequestBd(pHcd,
- CMD6,
- arg,
- SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,
- pReq,
- pSwitchStatusBlock,
- SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
-
- if (SDIO_SUCCESS(status)) {
- UINT16 switchGroupMask;
- /* need to reorder this since cards send this MSB first */
- ReorderBuffer(pSwitchStatusBlock,SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
- switchGroupMask = SD_SWITCH_FUNC_STATUS_GET_GRP_BIT_MASK(pSwitchStatusBlock,SD_SWITCH_HIGH_SPEED_GROUP);
- DBG_PRINT(SDDBG_TRACE, ("SD Card Switch Status Group1 Mask:0x%X Max Current:%d\n",
- switchGroupMask, SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock) ));
- if (SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock) == 0) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: SD Switch Status block has zero max current \n"));
- SDLIB_PrintBuffer(pSwitchStatusBlock,
- SD_SWITCH_FUNC_STATUS_BLOCK_BYTES,
- "SDIO Bus Driver: SD Switch Status Block Error");
- } else {
- /* check HS support */
- if (switchGroupMask & (1 << SD_SWITCH_HIGH_SPEED_FUNC_NO)) {
- DBG_PRINT(SDDBG_TRACE, ("SD Card Supports High Speed Mode\n"));
- /* set the rate, this will override the CSD value */
- cardReportedRate = SD_HS_MAX_BUS_CLOCK;
- pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_SD_HS;
- }
- }
- } else {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get SD Switch Status block (%d)\n", status));
- /* just fall through, we'll handle this like a normal SD card */
- status = SDIO_STATUS_SUCCESS;
- }
-
- KernelFree(pSwitchStatusBlock);
- }
-
- if ((pHcd->CardProperties.Flags & CARD_MMC) &&
- SDDEVICE_IS_MMC_REV_GTEQ_4_0(pHcd->pPseudoDev) &&
- (pHcd->Attributes & SDHCD_ATTRIB_MMC_HIGH_SPEED) &&
- !spiMode) {
- /* for MMC cards, get the Extended CSD to get the High speed and
- * wide bus paramaters */
-
- PUINT8 pExtData = KernelAlloc(MMC_EXT_CSD_SIZE);
-
- if (NULL == pExtData) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
- /* issue simple data transfer request to read the extended CSD */
- status = _IssueBusRequestBd(pHcd,MMC_CMD8,0,
- SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,
- pReq,
- pExtData,
- MMC_EXT_CSD_SIZE);
- if (SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_TRACE, ("MMC Ext CSD Version: 0x%X Card Type: 0x%X\n",
- pExtData[MMC_EXT_VER_OFFSET],pExtData[MMC_EXT_CARD_TYPE_OFFSET]));
- /* check HS support */
- if (pExtData[MMC_EXT_CARD_TYPE_OFFSET] & MMC_EXT_CARD_TYPE_HS_52) {
- /* try 52 Mhz */
- cardReportedRate = 52000000;
- pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_MMC_HS;
- } else if (pExtData[MMC_EXT_CARD_TYPE_OFFSET] & MMC_EXT_CARD_TYPE_HS_26) {
- /* try 26MHZ */
- cardReportedRate = 26000000;
- pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_MMC_HS;
- } else {
- /* doesn't report high speed capable */
- cardReportedRate = 0;
- }
-
- if (cardReportedRate && !spiMode) {
- /* figure out the bus mode */
- if (pHcd->Attributes & SDHCD_ATTRIB_BUS_MMC8BIT) {
- SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_MMC8_BIT);
- } else if (pHcd->Attributes & SDHCD_ATTRIB_BUS_4BIT) {
- SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_4_BIT);
- } else {
- /* we leave it to default to 1 bit mode */
- }
- }
- } else {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get MMC Extended CSD \n"));
- /* just fall through, we'll do without the extended information
- * and run it like a legacy MMC card */
- status = SDIO_STATUS_SUCCESS;
- }
-
- KernelFree(pExtData);
- }
-
- if (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC)) {
-
- if (0 == cardReportedRate) {
- /* extract rate from CSD only if it was not set by earlier tests */
- cardReportedRate = ConvertEncodedTransSpeed(
- GET_SD_CSD_TRANS_SPEED(pHcd->CardProperties.CardCSD));
- /* fall through and test for zero again */
- }
-
- if (cardReportedRate != 0) {
- /* adjust clock based on what the card can handle */
- ADJUST_OPER_CLOCK(pBusMode,cardReportedRate);
- } else {
- /* something is wrong with the CSD */
- if (DBG_GET_DEBUG_LEVEL() >= SDDBG_TRACE) {
- SDLIB_PrintBuffer(pHcd->CardProperties.CardCSD,
- MAX_CARD_RESPONSE_BYTES,
- "SDIO Bus Driver: CSD Dump");
- }
- /* can't figure out the card rate, so set reasonable defaults */
- if (pHcd->CardProperties.Flags & CARD_SD) {
- ADJUST_OPER_CLOCK(pBusMode,SD_MAX_BUS_CLOCK);
- } else {
- ADJUST_OPER_CLOCK(pBusMode,MMC_MAX_BUS_CLOCK);
- }
- }
- }
-
- /* note, we do SDIO card "after" SD in case this is a combo card */
- if (pHcd->CardProperties.Flags & CARD_SDIO) {
- /* read card capabilities */
- status = Cmd52ReadByteCommon(pHcd->pPseudoDev,
- SDIO_CARD_CAPS_REG,
- &pHcd->CardProperties.SDIOCaps);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- DBG_PRINT(SDDBG_TRACE, ("SDIO Card Caps: 0x%X \n",pHcd->CardProperties.SDIOCaps));
- if (pHcd->CardProperties.SDIOCaps & SDIO_CAPS_LOW_SPEED) {
- /* adjust max clock for LS device */
- ADJUST_OPER_CLOCK(pBusMode,SDIO_LOW_SPEED_MAX_BUS_CLOCK);
- /* adjust bus if LS device does not support 4 bit mode */
- if (!(pHcd->CardProperties.SDIOCaps & SDIO_CAPS_4BIT_LS)) {
- if (!spiMode) {
- /* low speed device does not support 4 bit mode, force us to 1 bit */
- SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags,
- SDCONFIG_BUS_WIDTH_1_BIT);
- }
- }
- }
-
- /* check if 1.2 card supports high speed mode, checking HCD as well*/
- if (SDDEVICE_IS_SDIO_REV_GTEQ_1_20(pHcd->pPseudoDev) &&
- (pHcd->Attributes & SDHCD_ATTRIB_SD_HIGH_SPEED) &&
- !spiMode) {
- UCHAR hsControl = 0;
-
- status = Cmd52ReadByteCommon(pHcd->pPseudoDev,
- SDIO_HS_CONTROL_REG,
- &hsControl);
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO Failed to read high speed control (%d) \n",status));
- /* reset status and continue */
- status = SDIO_STATUS_SUCCESS;
- } else {
- if (hsControl & SDIO_HS_CONTROL_SHS) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Card Supports High Speed Mode\n"));
- pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_SD_HS;
- }
- }
-
- }
-
- cardReportedRate = 0;
- temp = sizeof(func0ext);
- tplAddr = pHcd->CardProperties.CommonCISPtr;
- /* get the FUNCE tuple */
- status = SDLIB_FindTuple(pHcd->pPseudoDev,
- CISTPL_FUNCE,
- &tplAddr,
- (PUINT8)&func0ext,
- &temp);
- if (!SDIO_SUCCESS(status) || (temp < sizeof(func0ext))) {
- DBG_PRINT(SDDBG_WARN, ("SDIO Function 0 Ext. Tuple Missing (Got size:%d) \n", temp));
- /* reset status */
- status = SDIO_STATUS_SUCCESS;
- } else {
- /* convert encoded value to rate */
- cardReportedRate = ConvertEncodedTransSpeed(func0ext.MaxTransSpeed);
- }
-
- if (cardReportedRate != 0) {
- if (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) {
- if (cardReportedRate <= SD_MAX_BUS_CLOCK) {
- DBG_PRINT(SDDBG_WARN,
- ("SDIO Function tuple reports clock:%d Hz, with advertised High Speed support \n", cardReportedRate));
- /* back off high speed support */
- pBusMode->BusModeFlags &= ~SDCONFIG_BUS_MODE_SD_HS;
- }
- } else {
- if (cardReportedRate > SD_MAX_BUS_CLOCK) {
- DBG_PRINT(SDDBG_WARN,
- ("SDIO Function tuple reports clock:%d Hz, without advertising High Speed support..using 25Mhz \n", cardReportedRate));
- cardReportedRate = SD_MAX_BUS_CLOCK;
- }
- }
- /* adjust clock based on what the card can handle */
- ADJUST_OPER_CLOCK(pBusMode,cardReportedRate);
-
- } else {
- /* set a reasonable default */
- ADJUST_OPER_CLOCK(pBusMode,SD_MAX_BUS_CLOCK);
- }
- }
- } while (FALSE);
-
- if (pReq != NULL) {
- FreeRequest(pReq);
- }
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SetOperationalBusMode - set operational bus mode
- Input: pDevice - pDevice that is requesting the change
- pBusMode - operational bus mode
- Output: pBusMode - on return will have the actual clock rate set
- Return: status
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS SetOperationalBusMode(PSDDEVICE pDevice,
- PSDCONFIG_BUS_MODE_DATA pBusMode)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- UCHAR regData;
- UINT32 arg;
- UINT32 switcharg;
- PSDHCD pHcd = pDevice->pHcd;
-
- /* synchronize access for updating bus mode settings */
- status = SemaphorePendInterruptable(&pDevice->pHcd->ConfigureOpsSem);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
-
- do {
-
- if (!IS_CARD_PRESENT(pHcd)) {
- /* for an empty slot (a Pseudo dev was passed in) we still allow the
- * bus mode to be set for the card detect
- * polling */
- status = _IssueConfig(pHcd,SDCONFIG_BUS_MODE_CTRL,pBusMode,sizeof(SDCONFIG_BUS_MODE_DATA));
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus mode in hcd : Err:%d \n",
- status));
- }
- /* nothing more to do */
- break;
- }
-
-
- if ((pBusMode->BusModeFlags == SDDEVICE_GET_BUSMODE_FLAGS(pDevice)) &&
- (pBusMode->ClockRate == SDDEVICE_GET_OPER_CLOCK(pDevice))) {
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO Bus Driver: Bus mode already set, nothing to do\n"));
- pBusMode->ActualClockRate = SDDEVICE_GET_OPER_CLOCK(pDevice);
- break;
- }
-
- if (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_MMC_HS) {
- if (!(pHcd->Attributes & SDHCD_ATTRIB_MMC_HIGH_SPEED)) {
- status = SDIO_STATUS_INVALID_PARAMETER;
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: HCD does not support MMC High Speed\n"));
- break;
- }
- }
-
- if (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) {
- if (!(pHcd->Attributes & SDHCD_ATTRIB_SD_HIGH_SPEED)) {
- status = SDIO_STATUS_INVALID_PARAMETER;
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: HCD does not support SD High Speed\n"));
- break;
- }
- }
-
- /* before we set the operational clock and mode, configure the clock for high
- * speed mode on the card , if necessary */
- if ((pHcd->CardProperties.Flags & CARD_MMC) &&
- (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_MMC_HS) &&
- !(SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_MMC_HS)) {
-
- switcharg = MMC_SWITCH_BUILD_ARG(MMC_SWITCH_CMD_SET0,
- MMC_SWITCH_WRITE_BYTE,
- MMC_EXT_HS_TIMING_OFFSET,
- MMC_EXT_HS_TIMING_ENABLE);
- status = _IssueSimpleBusRequest(pHcd,
- MMC_CMD_SWITCH,
- switcharg,
- SDREQ_FLAGS_RESP_R1B,
- NULL);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: Failed to switch MMC High Speed Mode (arg:0x%X): %d \n",
- switcharg, status));
- break;
- }
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: High Speed MMC enabled (arg:0x%X)\n",
- switcharg));
- }
-
- /* before setting bus mode and clock in the HCD, switch card to high speed mode
- * if necessary */
- if ((pHcd->CardProperties.Flags & CARD_SD) &&
- (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) &&
- !(SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_SD_HS)) {
- UINT32 arg;
- PUINT8 pSwitchStatusBlock;
-
- pSwitchStatusBlock = KernelAlloc(SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
-
- if (NULL == pSwitchStatusBlock) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
-
- /* set high speed group */
- arg = SD_SWITCH_FUNC_ARG_GROUP_SET(SD_SWITCH_HIGH_SPEED_GROUP,
- SD_SWITCH_HIGH_SPEED_FUNC_NO);
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Setting SD Card for High Speed mode (CMD6 arg:0x%X)\n",arg));
-
- /* issue simple data transfer request to switch modes */
- status = _IssueBusRequestBd(pHcd,
- CMD6,
- arg,
- SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,
- NULL,
- pSwitchStatusBlock,
- SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
-
- if (SDIO_SUCCESS(status)) {
- ReorderBuffer(pSwitchStatusBlock,SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD High Speed Result, Got Max Current:%d mA, SwitchResult:0x%X \n",
- SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock),
- SDSwitchGetSwitchResult(pSwitchStatusBlock, SD_SWITCH_HIGH_SPEED_GROUP)));
- if (SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock) == 0) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Error in Status Block after High Speed Switch (current==0) \n"));
- status = SDIO_STATUS_DEVICE_ERROR;
- }
- if (SDSwitchGetSwitchResult(pSwitchStatusBlock, SD_SWITCH_HIGH_SPEED_GROUP) !=
- SD_SWITCH_HIGH_SPEED_FUNC_NO) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: Error in Status Block after High Speed Switch (Group1 did not switch) \n"));
- status = SDIO_STATUS_DEVICE_ERROR;
- }
- if (SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD High Speed Mode Enabled \n"));
- } else {
- SDLIB_PrintBuffer(pSwitchStatusBlock,
- SD_SWITCH_FUNC_STATUS_BLOCK_BYTES,
- "SDIO Bus Driver: SD Switch Status Block Error");
- }
- } else {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to Set SD High Speed Mode (%d) \n",status));
- }
- KernelFree(pSwitchStatusBlock);
-
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- }
-
- /* enable/disable high speed mode for SDIO card */
- if (pHcd->CardProperties.Flags & CARD_SDIO) {
- BOOL doSet = TRUE;
-
- if ((pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) &&
- !(SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_SD_HS)) {
- /* enable */
- regData = SDIO_HS_CONTROL_EHS;
- } else if (!(pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) &&
- (SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_SD_HS)) {
- /* disable */
- regData = 0;
- } else {
- /* do nothing */
- doSet = FALSE;
- }
-
- if (doSet) {
- status = Cmd52WriteByteCommon(pDevice,
- SDIO_HS_CONTROL_REG,
- &regData);
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to %s HS mode in SDIO card : Err:%d\n",
- (SDIO_HS_CONTROL_EHS == regData) ? "enable":"disable" , status));
- break;
- } else {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver:SDIO Card %s for High Speed mode \n",
- (SDIO_HS_CONTROL_EHS == regData) ? "enabled":"disabled" ));
- }
- }
- }
-
- /* use synchronize-with-bus request version, this may have been requested by a
- * function driver */
- status = SDLIB_IssueConfig(pDevice,
- SDCONFIG_BUS_MODE_CTRL,
- pBusMode,
- sizeof(SDCONFIG_BUS_MODE_DATA));
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus mode in hcd : Err:%d \n",
- status));
- break;
- }
-
- /* check requested bus width against the current mode */
- if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) ==
- SDCONFIG_GET_BUSWIDTH(pHcd->CardProperties.BusMode)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Bus mode set, no width change\n"));
- break;
- }
-
- if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_SPI) {
- /* nothing more to do for SPI */
- break;
- }
-
- /* set the bus width for SD and combo cards */
- if (pHcd->CardProperties.Flags & CARD_SD) {
- if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) {
- /* turn off card detect resistor */
- status = _IssueSimpleBusRequest(pHcd,
- ACMD42,
- 0, /* disable CD */
- SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R1,
- NULL);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Failed to disable CD Res: %d \n",
- status)); /* this should be okay */
- }
- arg = SD_ACMD6_BUS_WIDTH_4_BIT;
- } else {
- /* don't need to turn off CD in 1 bit mode, just set mode */
- arg = SD_ACMD6_BUS_WIDTH_1_BIT;
-
- }
- /* set the bus width */
- status = _IssueSimpleBusRequest(pHcd,
- ACMD6,
- arg, /* set bus mode */
- SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R1,
- NULL);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus width: %d \n",
- status));
- break;
- }
- }
- /* set bus width for SDIO cards */
- if (pHcd->CardProperties.Flags & CARD_SDIO) {
- /* default */
- regData = CARD_DETECT_DISABLE | SDIO_BUS_WIDTH_1_BIT;
-
- if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) {
- /* turn off card detect resistor and set buswidth */
- regData = CARD_DETECT_DISABLE | SDIO_BUS_WIDTH_4_BIT;
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Enabling 4 bit mode on card \n"));
- } else {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Enabling 1 bit mode on card \n"));
- }
- status = Cmd52WriteByteCommon(pDevice,
- SDIO_BUS_IF_REG,
- &regData);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus mode in Card : Err:%d\n",
- status));
- break;
- }
-
- /* check for 4-bit interrupt detect mode */
- if ((SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) &&
- (pHcd->CardProperties.SDIOCaps & SDIO_CAPS_INT_MULTI_BLK) &&
- (pHcd->Attributes & SDHCD_ATTRIB_MULTI_BLK_IRQ)) {
- /* enable interrupts between blocks, this doesn't actually turn on interrupts
- * it merely allows interrupts to be asserted in the inter-block gap */
- pHcd->CardProperties.SDIOCaps |= SDIO_CAPS_ENB_INT_MULTI_BLK;
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: 4-Bit Multi-blk Interrupt support enabled\n"));
- } else {
- /* make sure this is disabled */
- pHcd->CardProperties.SDIOCaps &= ~SDIO_CAPS_ENB_INT_MULTI_BLK;
- }
-
- status = Cmd52WriteByteCommon(pDevice,
- SDIO_CARD_CAPS_REG,
- &pHcd->CardProperties.SDIOCaps);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to update Card Caps register Err:%d\n",
- status));
- break;
- }
- }
-
- /* set data bus width for MMC */
- if (pHcd->CardProperties.Flags & CARD_MMC) {
- UINT8 buswidth = 0;
-
- if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) {
- buswidth = MMC_EXT_BUS_WIDTH_4_BIT;
- } else if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_MMC8_BIT) {
- buswidth = MMC_EXT_BUS_WIDTH_8_BIT;
- } else {
- /* normal 1 bit mode .. nothing to do */
- break;
- }
- /* now set the bus mode on the card */
- switcharg = MMC_SWITCH_BUILD_ARG(MMC_SWITCH_CMD_SET0,
- MMC_SWITCH_WRITE_BYTE,
- MMC_EXT_BUS_WIDTH_OFFSET,
- buswidth);
-
- status = _IssueSimpleBusRequest(pHcd,
- MMC_CMD_SWITCH,
- switcharg,
- SDREQ_FLAGS_RESP_R1B,
- NULL);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set MMC bus width (arg:0x%X): %d \n",
- switcharg, status));
- break;
- }
-
- if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: 4 bit MMC mode enabled (arg:0x%X) \n",
- switcharg));
- } else if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_MMC8_BIT) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: 8-Bit MMC mode enabled (arg:0x%X) \n",
- switcharg));
- }
- }
-
- } while (FALSE);
-
- if (SDIO_SUCCESS(status)) {
- /* set the operating mode */
- pHcd->CardProperties.BusMode = pBusMode->BusModeFlags;
- /* set the actual clock rate */
- pHcd->CardProperties.OperBusClock = pBusMode->ActualClockRate;
- }
-
- SemaphorePost(&pDevice->pHcd->ConfigureOpsSem);
-
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- CardInitSetup - setup host for card initialization
- Input: pHcd - HCD object
- Output:
- Return:
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS CardInitSetup(PSDHCD pHcd)
-{
- SDCONFIG_INIT_CLOCKS_DATA initClocks;
- SDCONFIG_BUS_MODE_DATA busMode;
- UINT32 OCRvalue;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- ZERO_OBJECT(initClocks);
- ZERO_OBJECT(busMode);
- /* setup defaults */
- initClocks.NumberOfClocks = SDMMC_MIN_INIT_CLOCKS;
- busMode.ClockRate = SD_INIT_BUS_CLOCK;
-
- /* check for SPI only */
- if (pHcd->Attributes & SDHCD_ATTRIB_BUS_SPI) {
- /* SPI cards startup in non-CRC mode with the exception of CMD0, the
- * HCDs must issue CMD0 with the correct CRC , the spec shows that a
- * CMD 0 sequence is 0x40,0x00,0x00,0x00,0x00,0x95 */
- busMode.BusModeFlags = SDCONFIG_BUS_WIDTH_SPI | SDCONFIG_BUS_MODE_SPI_NO_CRC;
- }
- /* check if host supports 1 bit mode */
- /* TODO : if host supports power switching, we can
- * could initialize cards in SPI mode first */
- if (pHcd->Attributes & SDHCD_ATTRIB_BUS_1BIT) {
- busMode.BusModeFlags = SDCONFIG_BUS_WIDTH_1_BIT;
- }
-
- /* set initial VDD, starting at the highest allowable voltage and working
- * our way down */
- if (pHcd->SlotVoltageCaps & SLOT_POWER_3_3V) {
- OCRvalue = SD_OCR_3_2_TO_3_3_VDD;
- } else if (pHcd->SlotVoltageCaps & SLOT_POWER_3_0V) {
- OCRvalue = SD_OCR_2_9_TO_3_0_VDD;
- } else if (pHcd->SlotVoltageCaps & SLOT_POWER_2_8V) {
- OCRvalue = SD_OCR_2_7_TO_2_8_VDD;
- } else if (pHcd->SlotVoltageCaps & SLOT_POWER_2_0V) {
- OCRvalue = SD_OCR_1_9_TO_2_0_VDD;
- } else if (pHcd->SlotVoltageCaps & SLOT_POWER_1_8V) {
- OCRvalue = SD_OCR_1_7_TO_1_8_VDD;
- } else if (pHcd->SlotVoltageCaps & SLOT_POWER_1_6V) {
- OCRvalue = SD_OCR_1_6_TO_1_7_VDD;
- } else {
- DBG_ASSERT(FALSE);
- OCRvalue = 0;
- }
-
- do {
- /* power up the card */
- status = AdjustSlotPower(pHcd, &OCRvalue);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to adjust slot power \n"));
- break;
- }
- status = SetOperationalBusMode(pHcd->pPseudoDev,&busMode);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus mode \n"));
- break;
- }
- status = _IssueConfig(pHcd,SDCONFIG_SEND_INIT_CLOCKS,&initClocks,sizeof(initClocks));
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to send init clocks in hcd \n"));
- break;
- }
-
- } while(FALSE);
-
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SDInitializeCard - initialize card
- Input: pHcd - HCD object
- Output: pProperties - card properties
- Return:
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS SDInitializeCard(PSDHCD pHcd)
-{
- SDCONFIG_BUS_MODE_DATA busMode;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDREQUEST pReq = NULL;
- UINT32 OCRvalue;
- UINT32 tplAddr;
- UINT8 temp;
- struct SDIO_MANFID_TPL manfid;
- SDCONFIG_WP_VALUE wpValue;
- UINT8 cisBuffer[3];
-
- OCRvalue = 0;
-
- do {
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Initializing card in SPI mode \n"));
- } else {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Initializing card in MMC/SD mode \n"));
- }
-
- pReq = AllocateRequest();
- if (NULL == pReq) {
- status = SDIO_STATUS_NO_RESOURCES;
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: failed to allocate bus request \n"));
- break;
- }
- memset(pReq, 0, sizeof(SDREQUEST));
-
- status = CardInitSetup(pHcd);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to setup card \n"));
- break;
- }
- status = _IssueConfig(pHcd,SDCONFIG_GET_WP,&wpValue,sizeof(wpValue));
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: host doesn't support Write Protect \n"));
- } else {
- if (wpValue) {
- pHcd->CardProperties.Flags |= CARD_SD_WP;
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: SD WP switch is on \n"));
- }
- }
-
- if (!(pHcd->Attributes & SDHCD_ATTRIB_SLOT_POLLING) &&
- IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* for non-slot polling HCDs operating in SPI mode
- * issue CMD0 to reset card state and to place the card
- * in SPI mode. If slot polling is used, the polling thread
- * will have already issued a CMD0 to place the card in SPI mode*/
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- INT ii = 256;
- status = SDIO_STATUS_ERROR;
- /* if the CMD0 fails, retry it. Some cards have a hard time getting into SPI mode.*/
- while ((!SDIO_SUCCESS(status)) && (ii-- >= 0)) {
- status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,pReq);
- OSSleep(20);
- }
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: cmd0 go SPI retries:(256) %d\n", ii));
-
- } else {
- status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,pReq);
- }
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: go-idle failed! \n"));
- break;
- }
- }
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Looking for SDIO.. \n"));
- /* check for SDIO card by trying to read it's OCR */
- status = ReadOCR(pHcd,CARD_SDIO,pReq,0,&OCRvalue);
- if (SDIO_SUCCESS(status)) {
- /* we got a response, this is an SDIO card */
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* handle SPI */
- pHcd->CardProperties.IOFnCount = SPI_SDIO_R4_GET_IO_FUNC_COUNT(pReq->Response);
- if (SPI_SDIO_R4_IS_MEMORY_PRESENT(pReq->Response)) {
- /* flag an SD function exists */
- pHcd->CardProperties.Flags |= CARD_SD;
- }
- } else {
- /* handle native SD */
- pHcd->CardProperties.IOFnCount = SD_SDIO_R4_GET_IO_FUNC_COUNT(pReq->Response);
- if (SD_SDIO_R4_IS_MEMORY_PRESENT(pReq->Response)) {
- /* flag an SD function exists */
- pHcd->CardProperties.Flags |= CARD_SD;
- }
-
- }
- if (0 == pHcd->CardProperties.IOFnCount) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SDIO Card reports no functions \n"));
- status = SDIO_STATUS_DEVICE_ERROR;
- pHcd->CardProperties.Flags = 0;
- break;
- }
- pHcd->CardProperties.Flags |= CARD_SDIO;
-
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO Bus Driver: SDIO Card, Functions: %d Card Info Flags:0x%X OCR:0x%8.8X\n",
- pHcd->CardProperties.IOFnCount, pHcd->CardProperties.Flags, OCRvalue));
- /* adjust slot power for this SDIO card */
- status = AdjustSlotPower(pHcd, &OCRvalue);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set power in hcd \n"));
- break;
- }
- /* poll for SDIO card ready */
- status = PollCardReady(pHcd,OCRvalue,CARD_SDIO);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- } else if (status != SDIO_STATUS_BUS_RESP_TIMEOUT){
- /* major error in hcd, bail */
- break;
- }
-
- /* check if this is an SDIO-only card before continuing */
- if (!(pHcd->CardProperties.Flags & CARD_SD) && (pHcd->CardProperties.Flags & CARD_SDIO)) {
- /* this is an SDIO card with no memory function */
- goto prepareCard;
- }
-
- if (!(pHcd->CardProperties.Flags & CARD_SDIO)) {
- /* issue go idle only if we did not find an SDIO function in our earlier test */
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,pReq);
- } else {
- status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,pReq);
- }
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: go-idle failed! \n"));
- break;
- }
- }
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Looking for SD Memory.. \n"));
- /* SD Memory Card checking */
- /* test for present of SD card (stand-alone or combo card) */
- status = TestPresence(pHcd, CARD_SD, pReq);
- if (SDIO_SUCCESS(status)) {
- /* there is an SD Card present, could be part of a combo system */
- pHcd->CardProperties.Flags |= CARD_SD;
- if (0 == OCRvalue) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD Memory card detected. \n"));
- /* no OCR value on entry this is a stand-alone card, go and get it*/
- status = ReadOCR(pHcd,CARD_SD,pReq,0,&OCRvalue);
- if (!SDIO_SUCCESS(status) || (OCRvalue == 0)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get OCR (status:%d) \n",
- status));
- break;
- }
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD Card Reports OCR:0x%8.8X \n", OCRvalue));
- status = AdjustSlotPower(pHcd, &OCRvalue);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to adjust power \n"));
- break;
- }
- } else {
- DBG_ASSERT((pHcd->CardProperties.Flags & (CARD_SD | CARD_SDIO)));
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SDIO Combo Card detected \n"));
- }
- /* poll for SD card ready */
- status = PollCardReady(pHcd,OCRvalue,CARD_SD);
- if (!SDIO_SUCCESS(status)) {
- /* check if this card has an SDIO function */
- if (pHcd->CardProperties.Flags & CARD_SDIO) {
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Combo Detected but SD memory function failed \n"));
- /* allow SDIO functions to load normally */
- status = SDIO_STATUS_SUCCESS;
- /* remove SD flag */
- pHcd->CardProperties.Flags &= ~CARD_SD;
- } else {
- break;
- }
- } else {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD Memory ready. \n"));
- }
- /* we're done, no need to check for MMC */
- goto prepareCard;
- } else if (status != SDIO_STATUS_BUS_RESP_TIMEOUT){
- /* major error in hcd, bail */
- break;
- }
-
- /* MMC card checking */
- /* if we get here, these better not be set */
- DBG_ASSERT(!(pHcd->CardProperties.Flags & (CARD_SD | CARD_SDIO)));
- /* issue go idle */
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,pReq);
- } else {
- status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,pReq);
- }
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: go-idle failed! \n"));
- break;
- }
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Looking for MMC.. \n"));
- status = TestPresence(pHcd, CARD_MMC, pReq);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: unknown card detected \n"));
- break;
- }
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: MMC Card Detected \n"));
- pHcd->CardProperties.Flags |= CARD_MMC;
- /* read the OCR value */
- status = ReadOCR(pHcd,CARD_MMC,pReq,0,&OCRvalue);
- if (!SDIO_SUCCESS(status) || (OCRvalue == 0)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Failed to get OCR (status:%d)",
- status));
- break;
- }
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: MMC Card Reports OCR:0x%8.8X \n", OCRvalue));
- /* adjust power */
- status = AdjustSlotPower(pHcd, &OCRvalue);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to adjust power \n"));
- break;
- }
- /* poll for MMC card ready */
- status = PollCardReady(pHcd,OCRvalue,CARD_MMC);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- /* fall through and prepare MMC card */
-
-prepareCard:
- /* we're done figuring out what was inserted, and setting up
- * optimal slot voltage, now we need to prepare the card */
- if (!IS_HCD_BUS_MODE_SPI(pHcd) &&
- (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC))) {
- /* non-SPI SD or MMC cards need to be moved to the "ident" state before we can get the
- * RCA or select the card using the new RCA */
- status = _IssueSimpleBusRequest(pHcd,CMD2,0,SDREQ_FLAGS_RESP_R2,pReq);
- if (!SDIO_SUCCESS(status)){
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: failed to move SD/MMC card into ident state \n"));
- break;
- }
- }
-
- if (!IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* non-SPI mode cards need their RCA's setup */
- if (pHcd->CardProperties.Flags & (CARD_SD | CARD_SDIO)) {
- /* issue CMD3 to get RCA on SD/SDIO cards */
- status = _IssueSimpleBusRequest(pHcd,CMD3,0,SDREQ_FLAGS_RESP_R6,pReq);
- if (!SDIO_SUCCESS(status)){
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: failed to get RCA for SD/SDIO card \n"));
- break;
- }
- pHcd->CardProperties.RCA = SD_R6_GET_RCA(pReq->Response);
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD/SDIO RCA:0x%X \n",
- pHcd->CardProperties.RCA));
- } else if (pHcd->CardProperties.Flags & CARD_MMC) {
- /* for MMC cards, we have to assign a relative card address */
- /* just a non-zero number */
- pHcd->CardProperties.RCA = 1;
- /* issue CMD3 to set the RCA for MMC cards */
- status = _IssueSimpleBusRequest(pHcd,
- CMD3,(pHcd->CardProperties.RCA << 16),
- SDREQ_FLAGS_RESP_R1,pReq);
- if (!SDIO_SUCCESS(status)){
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: failed to set RCA for MMC card! (err=%d) \n",status));
- break;
- }
- } else {
- DBG_ASSERT(FALSE);
- }
- }
- /* select the card in order to get the rest of the card info, applies
- * to SDIO/SD/MMC cards*/
- status = SelectDeselectCard(pHcd, TRUE);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: failed to select card! \n"));
- break;
- }
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver, Card now Selected.. \n"));
-
- if (pHcd->CardProperties.Flags & CARD_SDIO) {
- /* read SDIO revision register */
- status = Cmd52ReadByteCommon(pHcd->pPseudoDev, CCCR_SDIO_REVISION_REG, &temp);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- DBG_PRINT(SDDBG_TRACE, ("SDIO Revision Reg: 0x%X \n", temp));
- switch (temp & SDIO_REV_MASK) {
- case SDIO_REV_1_00:
- DBG_PRINT(SDDBG_TRACE, ("SDIO Spec Revision 1.00 \n"));
- pHcd->CardProperties.SDIORevision = SDIO_REVISION_1_00;
- break;
- case SDIO_REV_1_10:
- DBG_PRINT(SDDBG_TRACE, ("SDIO Spec Revision 1.10 \n"));
- pHcd->CardProperties.SDIORevision = SDIO_REVISION_1_10;
- break;
- case SDIO_REV_1_20:
- DBG_PRINT(SDDBG_TRACE, ("SDIO Spec Revision 1.20 \n"));
- pHcd->CardProperties.SDIORevision = SDIO_REVISION_1_20;
- break;
- default:
- DBG_PRINT(SDDBG_WARN, ("SDIO Warning: unknown SDIO revision, treating like 1.0 device \n"));
- pHcd->CardProperties.SDIORevision = SDIO_REVISION_1_00;
- break;
- }
- /* get the common CIS ptr */
- status = Cmd52ReadMultipleCommon(pHcd->pPseudoDev,
- SDIO_CMN_CIS_PTR_LOW_REG,
- cisBuffer,
- 3);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get CIS ptr, Err:%d", status));
- break;
- }
- /* this is endian-safe*/
- pHcd->CardProperties.CommonCISPtr = ((UINT32)cisBuffer[0]) |
- (((UINT32)cisBuffer[1]) << 8) |
- (((UINT32)cisBuffer[2]) << 16);
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Card CIS Ptr: 0x%X \n", pHcd->CardProperties.CommonCISPtr));
- temp = sizeof(manfid);
- tplAddr = pHcd->CardProperties.CommonCISPtr;
- /* get the MANFID tuple */
- status = SDLIB_FindTuple(pHcd->pPseudoDev,
- CISTPL_MANFID,
- &tplAddr,
- (PUINT8)&manfid,
- &temp);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Failed to get MANFID tuple err:%d \n", status));
- status = SDIO_STATUS_SUCCESS;
- } else {
- /* save this off so that it can be copied into each SDIO Func's SDDEVICE structure */
- pHcd->CardProperties.SDIO_ManufacturerCode =
- CT_LE16_TO_CPU_ENDIAN(manfid.ManufacturerCode);
- pHcd->CardProperties.SDIO_ManufacturerID =
- CT_LE16_TO_CPU_ENDIAN(manfid.ManufacturerInfo);
- DBG_PRINT(SDDBG_TRACE, ("SDIO MANFID:0x%X, MANFINFO:0x%X \n",
- pHcd->CardProperties.SDIO_ManufacturerID,
- pHcd->CardProperties.SDIO_ManufacturerCode));
- }
-
- if (pHcd->CardProperties.SDIORevision >= SDIO_REVISION_1_10) {
- /* read power control */
- status = Cmd52ReadByteCommon(pHcd->pPseudoDev, SDIO_POWER_CONTROL_REG, &temp);
- if (SDIO_SUCCESS(status)) {
- /* check for power control support which indicates the card may use more
- * than 200 mA */
- if (temp & SDIO_POWER_CONTROL_SMPC) {
- /* check that the host can support this. */
- if (pHcd->MaxSlotCurrent >= SDIO_EMPC_CURRENT_THRESHOLD) {
- temp = SDIO_POWER_CONTROL_EMPC;
- /* enable power control on the card */
- status = Cmd52WriteByteCommon(pHcd->pPseudoDev, SDIO_POWER_CONTROL_REG, &temp);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Busdriver: failed to enable power control (%d) \n",status));
- break;
- }
- /* mark that the card is high power */
- pHcd->CardProperties.Flags |= CARD_HIPWR;
-
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO Busdriver: Power Control Enabled on SDIO (1.10 or greater) card \n"));
- } else {
- DBG_PRINT(SDDBG_WARN,
- ("SDIO Busdriver: Card can operate higher than 200mA, host cannot (max:%d) \n",
- pHcd->MaxSlotCurrent));
- /* this is not fatal, the card should operate at a reduced rate */
- }
- } else {
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO Busdriver: SDIO 1.10 (or greater) card draws less than 200mA \n"));
- }
- } else {
- DBG_PRINT(SDDBG_WARN,
- ("SDIO Busdriver: failed to get POWER CONTROL REG (%d) \n",status));
- /* fall through and continue on at reduced mode */
- }
- }
- }
- /* get the current bus parameters */
- busMode.BusModeFlags = pHcd->CardProperties.BusMode;
- busMode.ClockRate = pHcd->CardProperties.OperBusClock;
- /* get the rest of the bus parameters like clock and supported bus width */
- status = GetBusParameters(pHcd,&busMode);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
-
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- /* check HCD if it wants to run without SPI CRC */
- if (pHcd->Attributes & SDHCD_ATTRIB_NO_SPI_CRC) {
- /* hcd would rather not run with CRC we don't need to tell the card since SPI mode
- * cards power up with CRC initially disabled */
- busMode.BusModeFlags |= SDCONFIG_BUS_MODE_SPI_NO_CRC;
- } else {
- /* first enable SPI CRC checking if the HCD can handle it */
- status = SDSPIModeEnableDisableCRC(pHcd->pPseudoDev, TRUE);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: Failed to set Enable SPI CRC on card \n"));
- break;
- }
- }
- }
-
- status = SetOperationalBusMode(pHcd->pPseudoDev, &busMode);
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set operational bus mode\n"));
- break;
- }
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Oper. Mode: Clock:%d, Bus:0x%X \n",
- pHcd->CardProperties.OperBusClock,pHcd->CardProperties.BusMode));
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Card in TRANS state, Ready: CardInfo Flags 0x%X \n",
- pHcd->CardProperties.Flags));
-
- } while (FALSE);
-
- if (pReq != NULL) {
- FreeRequest(pReq);
- }
-
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SDQuerySDMMCInfo - query MMC card info
- Input: pDevice - device
- Output:
- Return:
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS SDQuerySDMMCInfo(PSDDEVICE pDevice)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDREQUEST pReq = NULL;
- UINT8 CID[MAX_CSD_CID_BYTES];
-
- do {
- pReq = AllocateRequest();
- if (NULL == pReq) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
- /* de-select the card */
- status = SelectDeselectCard(pDevice->pHcd,FALSE);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to deselect card before getting CID \n"));
- break;
- }
-
- if (SDDEVICE_IS_BUSMODE_SPI(pDevice)) {
- /* in SPI mode, getting the CSD requires a data transfer */
- status = _IssueBusRequestBd(pDevice->pHcd,CMD10,0,
- SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,
- pReq,
- CID,
- MAX_CSD_CID_BYTES);
- if (SDIO_SUCCESS(status)) {
- /* in SPI mode we need to reorder to the CID since SPI data comes in MSB first*/
- ReorderBuffer(CID,MAX_CSD_CID_BYTES);
- }
- } else {
- /* get the CID */
- status = _IssueSimpleBusRequest(pDevice->pHcd,
- CMD10,
- (SDDEVICE_GET_CARD_RCA(pDevice) << 16),
- SDREQ_FLAGS_RESP_R2,
- pReq);
- if (SDIO_SUCCESS(status)) {
- /* extract it from the reponse */
- memcpy(CID,pReq->Response,MAX_CSD_CID_BYTES);
- }
- }
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_WARN, ("SDQuerySDMMCInfo: failed to get CID. \n"));
- status = SDIO_STATUS_SUCCESS;
- } else {
- pDevice->pId[0].SDMMC_ManfacturerID = GET_SD_CID_MANFID(CID);
- pDevice->pId[0].SDMMC_OEMApplicationID = GET_SD_CID_OEMID(CID);
-#ifdef DEBUG
- {
- char pBuf[7];
-
- pBuf[0] = GET_SD_CID_PN_1(CID);
- pBuf[1] = GET_SD_CID_PN_2(CID);
- pBuf[2] = GET_SD_CID_PN_3(CID);
- pBuf[3] = GET_SD_CID_PN_4(CID);
- pBuf[4] = GET_SD_CID_PN_5(CID);
- if (pDevice->pHcd->CardProperties.Flags & CARD_MMC) {
- pBuf[5] = GET_SD_CID_PN_6(CID);
- pBuf[6] = 0;
- } else {
- pBuf[5] = 0;
- }
- DBG_PRINT(SDDBG_TRACE, ("SDQuerySDMMCInfo: Product String: %s\n", pBuf));
- }
-#endif
- DBG_PRINT(SDDBG_TRACE, ("SDQuerySDMMCInfo: ManfID: 0x%X, OEMID:0x%X \n",
- pDevice->pId[0].SDMMC_ManfacturerID, pDevice->pId[0].SDMMC_OEMApplicationID));
- }
- /* re-select card */
- status = SelectDeselectCard(pDevice->pHcd,TRUE);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to re-select card after getting CID \n"));
- break;
- }
- } while (FALSE);
-
- if (pReq != NULL) {
- FreeRequest(pReq);
- }
-
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SDQuerySDIOInfo - query SDIO card info
- Input: pDevice - the device
- Output:
- Return:
- Notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS SDQuerySDIOInfo(PSDDEVICE pDevice)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- UINT32 faddress;
- UINT8 fInfo;
- UINT32 nextTpl;
- UINT8 tplLength;
- UINT8 cisPtrBuffer[3];
- struct SDIO_FUNC_EXT_FUNCTION_TPL_1_1 funcTuple;
-
- /* use the card-wide SDIO manufacturer code and ID previously read.*/
- pDevice->pId[0].SDIO_ManufacturerCode = pDevice->pHcd->CardProperties.SDIO_ManufacturerCode;
- pDevice->pId[0].SDIO_ManufacturerID = pDevice->pHcd->CardProperties.SDIO_ManufacturerID;
-
- /* calculate function base address */
- faddress = CalculateFBROffset(SDDEVICE_GET_SDIO_FUNCNO(pDevice));
- DBG_ASSERT(faddress != 0);
-
- do {
- status = Cmd52ReadByteCommon(pDevice,
- FBR_FUNC_INFO_REG_OFFSET(faddress),
- &fInfo);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get function info, Err:%d , using Class:UNKNOWN\n", status));
- fInfo = 0;
- pDevice->pId[0].SDIO_FunctionClass = 0;
- status = SDIO_STATUS_SUCCESS;
- } else {
- pDevice->pId[0].SDIO_FunctionClass = fInfo & FUNC_INFO_DEVICE_CODE_MASK;
- }
-
- if ((FUNC_INFO_DEVICE_CODE_LAST == pDevice->pId[0].SDIO_FunctionClass) &&
- SDDEVICE_IS_SDIO_REV_GTEQ_1_10(pDevice)) {
- /* if the device code is the last one, check for 1.1 revision and get the
- * extended code */
- status = Cmd52ReadByteCommon(pDevice,
- FBR_FUNC_EXT_DEVICE_CODE_OFFSET(faddress),
- &(pDevice->pId[0].SDIO_FunctionClass));
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get 1.1 extended DC, Err:%d\n",
- status));
- break;
- }
- }
-
- /* get the function CIS ptr */
- status = Cmd52ReadMultipleCommon(pDevice,
- FBR_FUNC_CIS_LOW_OFFSET(faddress),
- cisPtrBuffer,
- 3);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get FN CIS ptr, Err:%d\n", status));
- break;
- }
- /* endian safe */
- pDevice->DeviceInfo.AsSDIOInfo.FunctionCISPtr = ((UINT32)cisPtrBuffer[0]) |
- (((UINT32)cisPtrBuffer[1]) << 8) |
- (((UINT32)cisPtrBuffer[2]) << 16);
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Function:%d, Class:%d FnCISPtr:0x%X \n",
- SDDEVICE_GET_SDIO_FUNCNO(pDevice),
- pDevice->pId[0].SDIO_FunctionClass,pDevice->DeviceInfo.AsSDIOInfo.FunctionCISPtr));
-
- if (fInfo & FUNC_INFO_SUPPORTS_CSA_MASK) {
- /* get the function CSA ptr */
- status = Cmd52ReadMultipleCommon(pDevice,
- FBR_FUNC_CSA_LOW_OFFSET(faddress),
- cisPtrBuffer,
- 3);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get FN CSA ptr, Err:%d \n", status));
- break;
- }
- /* endian safe */
- pDevice->DeviceInfo.AsSDIOInfo.FunctionCSAPtr = ((UINT32)cisPtrBuffer[0]) |
- (((UINT32)cisPtrBuffer[1]) << 8) |
- (((UINT32)cisPtrBuffer[2]) << 16);
-
- }
-
- nextTpl = SDDEVICE_GET_SDIO_FUNC_CISPTR(pDevice);
- /* look for the funce TPL */
- tplLength = sizeof(funcTuple);
- /* go get the func CE tuple */
- status = SDLIB_FindTuple(pDevice,
- CISTPL_FUNCE,
- &nextTpl,
- (PUINT8)&funcTuple,
- &tplLength);
-
- if (!SDIO_SUCCESS(status)){
- /* handles case of bad CIS or missing tupple, allow function driver to handle */
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Failed to get FuncCE Tuple: %d \n", status));
- status = SDIO_STATUS_SUCCESS;
- break;
- }
- /* set the max block size */
- pDevice->DeviceInfo.AsSDIOInfo.FunctionMaxBlockSize =
- CT_LE16_TO_CPU_ENDIAN(funcTuple.CommonInfo.MaxBlockSize);
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Function:%d, MaxBlocks:%d \n",
- SDDEVICE_GET_SDIO_FUNCNO(pDevice),
- pDevice->DeviceInfo.AsSDIOInfo.FunctionMaxBlockSize));
-
- /* check for MANFID function tuple (SDIO 1.1 or greater) */
- if (SDDEVICE_IS_SDIO_REV_GTEQ_1_10(pDevice)) {
- struct SDIO_MANFID_TPL manfid;
- nextTpl = SDDEVICE_GET_SDIO_FUNC_CISPTR(pDevice);
- tplLength = sizeof(manfid);
- /* get the MANFID tuple */
- status = SDLIB_FindTuple(pDevice,
- CISTPL_MANFID,
- &nextTpl,
- (PUINT8)&manfid,
- &tplLength);
- if (SDIO_SUCCESS(status)) {
- /* this function has a MANFID tuple */
- pDevice->pId[0].SDIO_ManufacturerCode =
- CT_LE16_TO_CPU_ENDIAN(manfid.ManufacturerCode);
- pDevice->pId[0].SDIO_ManufacturerID =
- CT_LE16_TO_CPU_ENDIAN(manfid.ManufacturerInfo);
- DBG_PRINT(SDDBG_TRACE, ("SDIO 1.1 (Function Specific) MANFID:0x%X, MANFINFO:0x%X \n",
- pDevice->pId[0].SDIO_ManufacturerID,
- pDevice->pId[0].SDIO_ManufacturerCode));
- } else {
- DBG_PRINT(SDDBG_WARN, ("SDIO 1.1, No CISTPL_MANFID Tuple in FUNC CIS \n"));
- status = SDIO_STATUS_SUCCESS;
- }
- }
- } while (FALSE);
-
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SDEnableFunction - enable function
- Input: pDevice - the device/function
- pEnData - enable data;
- Output:
- Return: status
- Notes: Note, this performs synchronous calls
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS SDEnableFunction(PSDDEVICE pDevice, PSDCONFIG_FUNC_ENABLE_DISABLE_DATA pEnData)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- UINT8 registerValue;
- UINT8 mask;
- FUNC_ENABLE_TIMEOUT retry;
-
- /* take the configure op lock to make this atomic */
- status = SemaphorePendInterruptable(&pDevice->pHcd->ConfigureOpsSem);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
-
- status = SDIO_STATUS_INVALID_PARAMETER;
- do {
- if (!(pDevice->pHcd->CardProperties.Flags & CARD_SDIO)){
- /* nothing to do if it's not an SDIO card */
- break;
- }
-
- if (!((SDDEVICE_GET_SDIO_FUNCNO(pDevice) >= SDIO_FIRST_FUNCTION_NUMBER) &&
- (SDDEVICE_GET_SDIO_FUNCNO(pDevice) <= SDIO_LAST_FUNCTION_NUMBER))){
- DBG_ASSERT(FALSE);
- break;
- }
- /* make sure there is a timeout value */
- if (0 == pEnData->TimeOut) {
- break;
- }
-
- mask = 1 << SDDEVICE_GET_SDIO_FUNCNO(pDevice);
- /* read the enable register */
- status = Cmd52ReadByteCommon(pDevice, SDIO_ENABLE_REG, &registerValue);
- if (!SDIO_SUCCESS(status)){
- break;
- }
- if (pEnData->EnableFlags & SDCONFIG_ENABLE_FUNC) {
- /* set the enable register bit */
- registerValue |= mask;
- } else {
- /* clear the bit */
- registerValue &= ~mask;
- }
-
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO Bus Driver %s Function, Mask:0x%X Enable Reg Value:0x%2.2X\n",
- (pEnData->EnableFlags & SDCONFIG_ENABLE_FUNC) ? "Enabling":"Disabling",
- mask,
- registerValue));
-
- /* write it back out */
- status = Cmd52WriteByteCommon(pDevice, SDIO_ENABLE_REG, &registerValue);
- if (!SDIO_SUCCESS(status)){
- break;
- }
- /* now poll the ready bit until it sets or clears */
- retry = pEnData->TimeOut;
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Function Enable/Disable Polling: %d retries \n",
- retry));
- while (retry) {
- status = Cmd52ReadByteCommon(pDevice, SDIO_READY_REG, &registerValue);
- if (!SDIO_SUCCESS(status)){
- break;
- }
- if (pEnData->EnableFlags & SDCONFIG_ENABLE_FUNC) {
- /* if the bit is set, the device is ready */
- if (registerValue & mask) {
- /* device ready */
- break;
- }
- } else {
- if (!(registerValue & mask)) {
- /* device is no longer ready */
- break;
- }
- }
- /* sleep before trying again */
- status = OSSleep(1);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("OSSleep Failed! \n"));
- break;
- }
- retry--;
- }
-
- if (0 == retry) {
- status = SDIO_STATUS_FUNC_ENABLE_TIMEOUT;
- break;
- }
-
- } while (FALSE);
-
- SemaphorePost(&pDevice->pHcd->ConfigureOpsSem);
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SDAllocFreeSlotCurrent - allocate or free slot current
- Input: pDevice - the device/function
- Allocate - Allocate current, else free
- pData - slotcurrent data (non-NULL if Allocate is TRUE)
- Output:
- Return: status
- Notes: if the function returns SDIO_STATUS_NO_RESOURCES, the pData->SlotCurrent field is
- updated with the available current
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS SDAllocFreeSlotCurrent(PSDDEVICE pDevice, BOOL Allocate, PSDCONFIG_FUNC_SLOT_CURRENT_DATA pData)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: SDAllocFreeSlotCurrent\n"));
-
- /* take the configure op lock to make this atomic */
- status = SemaphorePendInterruptable(&pDevice->pHcd->ConfigureOpsSem);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
-
- status = SDIO_STATUS_INVALID_PARAMETER;
- do {
- /* check the current budget and allocate */
- if (Allocate) {
- if (0 == pData->SlotCurrent) {
- /* caller must specify current requirement for the power mode */
- break;
- }
- if (pDevice->SlotCurrentAlloc != 0) {
- /* slot current has already been allocated, caller needs to free
- * first */
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Slot Current Already allocated! \n"));
- break;
- }
- if (((UINT32)pDevice->pHcd->SlotCurrentAllocated + (UINT32)pData->SlotCurrent) >
- (UINT32)pDevice->pHcd->MaxSlotCurrent) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Slot Current Budget exceeded, Requesting: %d, Allocated already: %d, Max: %d \n",
- pData->SlotCurrent, pDevice->pHcd->SlotCurrentAllocated,
- pDevice->pHcd->MaxSlotCurrent));
- status = SDIO_STATUS_NO_RESOURCES;
- /* return remaining */
- pData->SlotCurrent = pDevice->pHcd->MaxSlotCurrent -
- pDevice->pHcd->SlotCurrentAllocated;
- break;
- }
- /* bump up allocation */
- pDevice->pHcd->SlotCurrentAllocated += pData->SlotCurrent;
- /* save this off for the call to free slot current */
- pDevice->SlotCurrentAlloc = pData->SlotCurrent;
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Slot Current Requested: %d, New Total: %d, Max: %d \n",
- pData->SlotCurrent, pDevice->pHcd->SlotCurrentAllocated,
- pDevice->pHcd->MaxSlotCurrent));
-
- } else {
- if (0 == pDevice->SlotCurrentAlloc) {
- /* no allocation */
- break;
- }
- /* return the allocation back */
- if (pDevice->SlotCurrentAlloc <= pDevice->pHcd->SlotCurrentAllocated) {
- pDevice->pHcd->SlotCurrentAllocated -= pDevice->SlotCurrentAlloc;
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Slot Current Freed: %d, New Total: %d, Max: %d \n",
- pDevice->SlotCurrentAlloc, pDevice->pHcd->SlotCurrentAllocated,
- pDevice->pHcd->MaxSlotCurrent));
- } else {
- DBG_ASSERT(FALSE);
- }
-
- /* make sure this is zeroed */
- pDevice->SlotCurrentAlloc = 0;
- }
-
- status = SDIO_STATUS_SUCCESS;
-
- } while (FALSE);
-
- SemaphorePost(&pDevice->pHcd->ConfigureOpsSem);
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: SDAllocFreeSlotCurrent, %d\n", status));
- return status;
-}
-
-static void RawHcdIrqControl(PSDHCD pHcd, BOOL Enable)
-{
- SDIO_STATUS status;
- SDCONFIG_SDIO_INT_CTRL_DATA irqData;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- ZERO_OBJECT(irqData);
-
- status = _AcquireHcdLock(pHcd);
- if (!SDIO_SUCCESS(status)) {
- return;
- }
-
- do {
- /* for raw devices, we simply enable/disable in the HCD only */
- if (Enable) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver (RAW) Unmasking Int \n"));
- irqData.IRQDetectMode = IRQ_DETECT_RAW;
- irqData.SlotIRQEnable = TRUE;
- } else {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver (RAW) Masking Int \n"));
- irqData.SlotIRQEnable = FALSE;
- }
-
- status = _IssueConfig(pHcd,SDCONFIG_SDIO_INT_CTRL,
- (PVOID)&irqData, sizeof(irqData));
-
- if (!SDIO_SUCCESS(status)){
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver failed to enable/disable IRQ in (RAW) hcd :%d\n",
- status));
- }
-
- } while (FALSE);
-
- status = _ReleaseHcdLock(pHcd);
-}
-
-static void RawHcdEnableIrqPseudoComplete(PSDREQUEST pReq)
-{
- if (SDIO_SUCCESS(pReq->Status)) {
- RawHcdIrqControl((PSDHCD)pReq->pCompleteContext, TRUE);
- }
- FreeRequest(pReq);
-}
-
-static void RawHcdDisableIrqPseudoComplete(PSDREQUEST pReq)
-{
- RawHcdIrqControl((PSDHCD)pReq->pCompleteContext, FALSE);
- FreeRequest(pReq);
-}
-
-static void HcdIrqControl(PSDHCD pHcd, BOOL Enable)
-{
- SDIO_STATUS status;
- SDCONFIG_SDIO_INT_CTRL_DATA irqData;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- ZERO_OBJECT(irqData);
-
- status = _AcquireHcdLock(pHcd);
- if (!SDIO_SUCCESS(status)) {
- return;
- }
-
- do {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: HcdIrqControl (%s), IrqsEnabled:0x%X \n",
- Enable ? "Enable":"Disable",pHcd->IrqsEnabled ));
-
- if (Enable) {
- irqData.SlotIRQEnable = TRUE;
- } else {
- irqData.SlotIRQEnable = FALSE;
- }
- /* setup HCD to enable/disable it's detection hardware */
- if (irqData.SlotIRQEnable) {
- /* set the IRQ detection mode */
- switch (SDCONFIG_GET_BUSWIDTH(pHcd->CardProperties.BusMode)) {
- case SDCONFIG_BUS_WIDTH_SPI:
- irqData.IRQDetectMode = IRQ_DETECT_SPI;
- break;
- case SDCONFIG_BUS_WIDTH_1_BIT:
- irqData.IRQDetectMode = IRQ_DETECT_1_BIT;
- break;
- case SDCONFIG_BUS_WIDTH_4_BIT:
- irqData.IRQDetectMode = IRQ_DETECT_4_BIT;
- /* check card and HCD for 4bit multi-block interrupt support */
- if ((pHcd->CardProperties.SDIOCaps & SDIO_CAPS_INT_MULTI_BLK) &&
- (pHcd->Attributes & SDHCD_ATTRIB_MULTI_BLK_IRQ)) {
- /* note: during initialization of the card, the mult-blk IRQ support
- * is enabled in card caps register */
- irqData.IRQDetectMode |= IRQ_DETECT_MULTI_BLK;
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver enabling IRQ in multi-block mode:\n"));
- }
- break;
- default:
- DBG_ASSERT(FALSE);
- break;
- }
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver enabling IRQ in HCD Mode:0x%X\n",
- irqData.IRQDetectMode));
- }
-
- status = _IssueConfig(pHcd,SDCONFIG_SDIO_INT_CTRL,
- (PVOID)&irqData, sizeof(irqData));
- if (!SDIO_SUCCESS(status)){
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver failed to enable/disable IRQ in hcd %d\n",
- status));
- }
-
- } while (FALSE);
-
- status = _ReleaseHcdLock(pHcd);
-}
-
-static BOOL CheckWriteIntEnableSuccess(PSDREQUEST pReq)
-{
- if (!SDIO_SUCCESS(pReq->Status)){
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get write INT Enable register Err:%d\n",
- pReq->Status));
- return FALSE;
- }
-
- if (SD_R5_GET_RESP_FLAGS(pReq->Response) & SD_R5_ERRORS) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: WriteIntEnableComplete CMD52 resp error: 0x%X \n",
- SD_R5_GET_RESP_FLAGS(pReq->Response)));
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void HcdIrqEnableComplete(PSDREQUEST pReq)
-{
- if (CheckWriteIntEnableSuccess(pReq)) {
- /* configure HCD */
- HcdIrqControl((PSDHCD)pReq->pCompleteContext, TRUE);
- }
- FreeRequest(pReq);
-}
-
-static void HcdIrqDisableComplete(PSDREQUEST pReq)
-{
- CheckWriteIntEnableSuccess(pReq);
- HcdIrqControl((PSDHCD)pReq->pCompleteContext, FALSE);
- FreeRequest(pReq);
-}
-
-static void WriteIntEnableComplete(PSDREQUEST pReq)
-{
- if (CheckWriteIntEnableSuccess(pReq)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Wrote INT Enable value:0x%X \n",
- (INT)pReq->pCompleteContext));
- }
- FreeRequest(pReq);
-}
-
-static void HcdAckComplete(PSDREQUEST pReq)
-{
- SDIO_STATUS status;
- DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: Hcd (0x%X) Irq Ack \n",
- (INT)pReq->pCompleteContext));
- /* re-arm the HCD */
- status = _IssueConfig((PSDHCD)pReq->pCompleteContext,SDCONFIG_SDIO_REARM_INT,NULL,0);
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: HCD Re-Arm failed : %d\n",
- status));
- }
- FreeRequest(pReq);
-}
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SDFunctionAckInterrupt - handle device interrupt acknowledgement
- Input: pDevice - the device
- Output:
- Return:
- Notes:
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS SDFunctionAckInterrupt(PSDDEVICE pDevice)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- UCHAR mask;
- PSDREQUEST pReq = NULL;
- BOOL setHcd = FALSE;
- SDIO_STATUS status2;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- pReq = AllocateRequest();
- if (NULL == pReq) {
- return SDIO_STATUS_NO_RESOURCES;
- }
-
- status = _AcquireHcdLock(pDevice->pHcd);
-
- if (!SDIO_SUCCESS(status)) {
- FreeRequest(pReq);
- return status;
- }
-
- do {
- if (!((SDDEVICE_GET_SDIO_FUNCNO(pDevice) >= SDIO_FIRST_FUNCTION_NUMBER) &&
- (SDDEVICE_GET_SDIO_FUNCNO(pDevice) <= SDIO_LAST_FUNCTION_NUMBER))){
- status = SDIO_STATUS_INVALID_PARAMETER;
- DBG_ASSERT(FALSE);
- break;
- }
- mask = 1 << SDDEVICE_GET_SDIO_FUNCNO(pDevice);
- if (pDevice->pHcd->PendingIrqAcks & mask) {
- /* clear the ack bit in question */
- pDevice->pHcd->PendingIrqAcks &= ~mask;
- if (0 == pDevice->pHcd->PendingIrqAcks) {
- pDevice->pHcd->IrqProcState = SDHCD_IDLE;
- /* no pending acks, so re-arm if irqs are stilled enabled */
- if (pDevice->pHcd->IrqsEnabled) {
- setHcd = TRUE;
- /* issue pseudo request to sync this with bus requests */
- pReq->Status = SDIO_STATUS_SUCCESS;
- pReq->pCompletion = HcdAckComplete;
- pReq->pCompleteContext = pDevice->pHcd;
- pReq->Flags = SD_PSEUDO_REQ_FLAGS;
- }
- }
- } else {
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: AckInterrupt: no IRQ pending on Function :%d, \n",
- SDDEVICE_GET_SDIO_FUNCNO(pDevice)));
- }
- } while (FALSE);
-
- status2 = ReleaseHcdLock(pDevice);
-
- if (pReq != NULL) {
- if (SDIO_SUCCESS(status) && (setHcd)) {
- /* issue request */
- IssueRequestToHCD(pDevice->pHcd,pReq);
- } else {
- FreeRequest(pReq);
- }
- }
-
- return status;
-}
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SDMaskUnmaskFunctionIRQ - mask/unmask function IRQ
- Input: pDevice - the device/function
- MaskInt - mask interrupt
- Output:
- Return: status
- Notes: Note, this function can be called from an ISR or completion context
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS SDMaskUnmaskFunctionIRQ(PSDDEVICE pDevice, BOOL MaskInt)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- UINT8 mask;
- UINT8 controlVal;
- BOOL setHcd;
- PSDREQUEST pReq = NULL;
- SDIO_STATUS status2;
-
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- setHcd = FALSE;
-
- pReq = AllocateRequest();
- if (NULL == pReq) {
- return SDIO_STATUS_NO_RESOURCES;
- }
-
- status = _AcquireHcdLock(pDevice->pHcd);
-
- if (!SDIO_SUCCESS(status)) {
- FreeRequest(pReq);
- return status;
- }
-
- do {
-
- if (pDevice->pHcd->CardProperties.Flags & CARD_RAW) {
- if (!MaskInt) {
- if (!pDevice->pHcd->IrqsEnabled) {
- pReq->pCompletion = RawHcdEnableIrqPseudoComplete;
- setHcd = TRUE;
- pDevice->pHcd->IrqsEnabled = 1 << 1;
- }
- } else {
- if (pDevice->pHcd->IrqsEnabled) {
- pReq->pCompletion = RawHcdDisableIrqPseudoComplete;
- setHcd = TRUE;
- pDevice->pHcd->IrqsEnabled = 0;
- }
- }
-
- if (setHcd) {
- /* hcd IRQ control requests must be synched with outstanding
- * bus requests so we issue a pseudo bus request */
- pReq->pCompleteContext = pDevice->pHcd;
- pReq->Flags = SD_PSEUDO_REQ_FLAGS;
- pReq->Status = SDIO_STATUS_SUCCESS;
- } else {
- /* no request to submit, just free it */
- FreeRequest(pReq);
- pReq = NULL;
- }
- /* we're done, submit the bus request if any */
- break;
- }
-
- if (!(pDevice->pHcd->CardProperties.Flags & CARD_SDIO)){
- /* nothing to do if it's not an SDIO card */
- DBG_ASSERT(FALSE);
- status = SDIO_STATUS_INVALID_PARAMETER;
- break;
- }
-
- if (!((SDDEVICE_GET_SDIO_FUNCNO(pDevice) >= SDIO_FIRST_FUNCTION_NUMBER) &&
- (SDDEVICE_GET_SDIO_FUNCNO(pDevice) <= SDIO_LAST_FUNCTION_NUMBER))){
- status = SDIO_STATUS_INVALID_PARAMETER;
- DBG_ASSERT(FALSE);
- break;
- }
-
- mask = 1 << SDDEVICE_GET_SDIO_FUNCNO(pDevice);
- if (!MaskInt) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver Unmasking Int, Mask:0x%X\n", mask));
- /* check interrupts that were enabled on entry */
- if (0 == pDevice->pHcd->IrqsEnabled) {
- /* need to turn on interrupts in HCD */
- setHcd = TRUE;
- /* use this completion routine */
- pReq->pCompletion = HcdIrqEnableComplete;
- }
- /* set the enable bit, in the shadow register */
- pDevice->pHcd->IrqsEnabled |= mask;
- /* make sure control value includes the master enable */
- controlVal = pDevice->pHcd->IrqsEnabled | SDIO_INT_MASTER_ENABLE;
- } else {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver Masking Int, Mask:0x%X\n", mask));
- /* clear the bit */
- pDevice->pHcd->IrqsEnabled &= ~mask;
- /* check and see if this clears all the bits */
- if (0 == pDevice->pHcd->IrqsEnabled){
- /* if none of the functions are enabled, clear this register */
- controlVal = 0;
- /* disable in host */
- setHcd = TRUE;
- /* use this completion routine */
- pReq->pCompletion = HcdIrqDisableComplete;
- } else {
- /* set control value making sure master enable is left on */
- controlVal = pDevice->pHcd->IrqsEnabled | SDIO_INT_MASTER_ENABLE;
- }
- }
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver INT_ENABLE_REG value:0x%X\n", controlVal));
- /* setup bus request to update the mask register */
- SDIO_SET_CMD52_WRITE_ARG(pReq->Argument,0,SDIO_INT_ENABLE_REG,controlVal);
- pReq->Command = CMD52;
- pReq->Flags = SDREQ_FLAGS_TRANS_ASYNC | SDREQ_FLAGS_RESP_SDIO_R5;
-
- if (setHcd) {
- /* make this a barrier request and set context*/
- pReq->Flags |= SDREQ_FLAGS_BARRIER;
- pReq->pCompleteContext = pDevice->pHcd;
- } else {
- /* does not require an update to the HCD */
- pReq->pCompleteContext = (PVOID)(UINT32)controlVal;
- pReq->pCompletion = WriteIntEnableComplete;
- }
-
- } while (FALSE);
-
- status2 = _ReleaseHcdLock(pDevice->pHcd);
-
- if (pReq != NULL) {
- if (SDIO_SUCCESS(status)) {
- /* issue request */
- IssueRequestToHCD(pDevice->pHcd,pReq);
- } else {
- FreeRequest(pReq);
- }
- }
-
- return status;
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- SDSPIModeEnableDisableCRC - Enable/Disable SPI Mode CRC checking
- Input: pDevice - the device/function
- Enable - Enable CRC
- Output:
- Return: status
- Notes: Note, this function can be called from an ISR or completion context
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS SDSPIModeEnableDisableCRC(PSDDEVICE pDevice,BOOL Enable)
-{
- SDCONFIG_BUS_MODE_DATA busMode;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- UINT32 cmdARG = 0;
-
- if (!SDDEVICE_IS_BUSMODE_SPI(pDevice)) {
- return SDIO_STATUS_INVALID_PARAMETER;
- }
- //??we should make these atomic using a barrier
-
- /* get the current mode and clock */
- busMode.BusModeFlags = pDevice->pHcd->CardProperties.BusMode;
- busMode.ClockRate = pDevice->pHcd->CardProperties.OperBusClock;
-
- if (Enable) {
- /* clear the no-CRC flag */
- busMode.BusModeFlags &= ~SDCONFIG_BUS_MODE_SPI_NO_CRC;
- cmdARG = SD_CMD59_CRC_ON;
- } else {
- busMode.BusModeFlags |= SDCONFIG_BUS_MODE_SPI_NO_CRC;
- cmdARG = SD_CMD59_CRC_OFF;
- }
-
- do {
- /* issue CMD59 to turn on/off CRC */
- status = _IssueSimpleBusRequest(pDevice->pHcd,
- CMD59,
- cmdARG,
- SDREQ_FLAGS_RESP_R1,
- NULL);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed issue CMD59 (arg=0x%X) Err:%d \n",
- cmdARG, status));
- break;
- }
- if (Enable) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: CRC Enabled in SPI mode \n"));
- } else {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: CRC Disabled in SPI mode \n"));
- }
- status = SetOperationalBusMode(pDevice,&busMode);
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set SPI NO CRC mode in hcd : Err:%d \n",
- status));
- break;
- }
- } while (FALSE);
-
- return status;
-}
-
-
-static UINT32 ConvertSPIStatusToSDCardStatus(UINT8 SpiR1, UINT8 SpiR2)
-{
- UINT32 cardStatus = 0;
-
- if (SpiR1 != 0) {
- /* convert the error */
- if (SpiR1 & SPI_CS_ERASE_RESET) {
- cardStatus |= SD_CS_ERASE_RESET;
- }
- if (SpiR1 & SPI_CS_ILLEGAL_CMD) {
- cardStatus |= SD_CS_ILLEGAL_CMD_ERR;
- }
- if (SpiR1 & SPI_CS_CMD_CRC_ERR) {
- cardStatus |= SD_CS_PREV_CMD_CRC_ERR;
- }
- if (SpiR1 & SPI_CS_ERASE_SEQ_ERR) {
- cardStatus |= SD_CS_ERASE_SEQ_ERR;
- }
- if (SpiR1 & SPI_CS_ADDRESS_ERR) {
- cardStatus |= SD_CS_ADDRESS_ERR;
- }
- if (SpiR1 & SPI_CS_PARAM_ERR) {
- cardStatus |= SD_CS_CMD_OUT_OF_RANGE;
- }
- }
-
- if (SpiR2 != 0) {
- /* convert the error */
- if (SpiR2 & SPI_CS_CARD_IS_LOCKED) {
- cardStatus |= SD_CS_CARD_LOCKED;
- }
- if (SpiR2 & SPI_CS_LOCK_UNLOCK_FAILED) {
- /* this bit is shared, just set both */
- cardStatus |= (SD_CS_LK_UNLK_FAILED | SD_CS_WP_ERASE_SKIP);
- }
- if (SpiR2 & SPI_CS_ERROR) {
- cardStatus |= SD_CS_GENERAL_ERR;
- }
- if (SpiR2 & SPI_CS_INTERNAL_ERROR) {
- cardStatus |= SD_CS_CARD_INTERNAL_ERR;
- }
- if (SpiR2 & SPI_CS_ECC_FAILED) {
- cardStatus |= SD_CS_ECC_FAILED;
- }
- if (SpiR2 & SPI_CS_WP_VIOLATION) {
- cardStatus |= SD_CS_WP_ERR;
- }
- if (SpiR2 & SPI_CS_ERASE_PARAM_ERR) {
- cardStatus |= SD_CS_ERASE_PARAM_ERR;
- }
- if (SpiR2 & SPI_CS_OUT_OF_RANGE) {
- cardStatus |= SD_CS_CMD_OUT_OF_RANGE;
- }
- }
-
- return cardStatus;
-}
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ConvertSPI_Response - filter the SPI response and convert it to an SD Response
- Input: pReq - request
- Output: pReq - modified response, if pRespBuffer is not NULL
- pRespBuffer - converted response (optional)
- Return:
- Notes: This function converts a SPI response into an SD response. A caller
- can supply a buffer instead.
- For SPI bus operation the HCD must send the SPI response as
- a stream of bytes, the highest byte contains the first received byte from the
- card. This function only filters simple responses (R1 primarily).
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void ConvertSPI_Response(PSDREQUEST pReq, UINT8 *pRespBuffer)
-{
-
- UINT32 cardStatus;
-
- if (pReq->Flags & SDREQ_FLAGS_RESP_SPI_CONVERTED) {
- /* already converted */
- return;
- }
- if (NULL == pRespBuffer) {
- pRespBuffer = pReq->Response;
- }
-
- switch (GET_SDREQ_RESP_TYPE(pReq->Flags)) {
- case SDREQ_FLAGS_RESP_R1:
- case SDREQ_FLAGS_RESP_R1B:
- cardStatus = ConvertSPIStatusToSDCardStatus(GET_SPI_R1_RESP_TOKEN(pReq->Response),
- 0);
- if (CMD55 == pReq->Command) {
- /* we emulate this since SPI does not have such a bit */
- cardStatus |= SD_CS_APP_CMD;
- }
- /* stuff the SD card status */
- SD_R1_SET_CMD_STATUS(pRespBuffer,cardStatus);
- /* stuff the command */
- SD_R1_SET_CMD(pRespBuffer,pReq->Command);
- pReq->Flags |= SDREQ_FLAGS_RESP_SPI_CONVERTED;
- break;
- case SDREQ_FLAGS_RESP_SDIO_R5:
- {
- UINT8 respFlags;
- UINT8 readData;
-
- readData = GET_SPI_SDIO_R5_RESPONSE_RDATA(pReq->Response);
- respFlags = GET_SPI_SDIO_R5_RESP_TOKEN(pReq->Response);
-
- pRespBuffer[SD_R5_RESP_FLAGS_OFFSET] = 0;
- if (respFlags != 0) {
- if (respFlags & SPI_R5_ILLEGAL_CMD) {
- pRespBuffer[SD_R5_RESP_FLAGS_OFFSET] |= SD_R5_ILLEGAL_CMD;
- }
- if (respFlags & SPI_R5_CMD_CRC) {
- pRespBuffer[SD_R5_RESP_FLAGS_OFFSET] |= SD_R5_RESP_CMD_ERR;
- }
- if (respFlags & SPI_R5_FUNC_ERR) {
- pRespBuffer[SD_R5_RESP_FLAGS_OFFSET] |= SD_R5_INVALID_FUNC;
- }
- if (respFlags & SPI_R5_PARAM_ERR) {
- pRespBuffer[SD_R5_RESP_FLAGS_OFFSET] |= SD_R5_ARG_RANGE_ERR;
- }
- }
- /* stuff read data */
- pRespBuffer[SD_SDIO_R5_READ_DATA_OFFSET] = readData;
- /* stuff the command */
- SD_R5_SET_CMD(pRespBuffer,pReq->Command);
- }
- pReq->Flags |= SDREQ_FLAGS_RESP_SPI_CONVERTED;
- break;
- case SDREQ_FLAGS_RESP_R2:
- /* for CMD13 and ACMD13 , SPI uses it's own R2 response format (2 bytes) */
- /* the issue of CMD13 needs to change the response flag to R2 */
- if (CMD13 == pReq->Command) {
- cardStatus = ConvertSPIStatusToSDCardStatus(
- GET_SPI_R2_RESP_TOKEN(pReq->Response),
- GET_SPI_R2_STATUS_TOKEN(pReq->Response));
- /* stuff the SD card status */
- SD_R1_SET_CMD_STATUS(pRespBuffer,cardStatus);
- /* stuff the command */
- SD_R1_SET_CMD(pRespBuffer,pReq->Command);
- pReq->Flags |= SDREQ_FLAGS_RESP_SPI_CONVERTED;
- break;
- }
- /* no other commands should be using R2 when using SPI, if they are
- * they should be bypassing the filter */
- DBG_ASSERT(FALSE);
- break;
- default:
- /* for all others:
- *
- * SDREQ_FLAGS_RESP_R6 - SPI mode does not use RCA
- * SDREQ_FLAGS_RESP_R3 - bus driver handles this internally
- * SDREQ_FLAGS_RESP_SDIO_R4 - bus driver handles this internally
- *
- */
- DBG_PRINT(SDDBG_ERROR, ("ConvertSPI_Response - invalid response type:0x%2.2X",
- GET_SDREQ_RESP_TYPE(pReq->Flags)));
- DBG_ASSERT(FALSE);
- break;
- }
-}
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Check an SD/MMC/SDIO response.
-
- @function name: SDIO_CheckResponse
- @prototype: SDIO_STATUS SDIO_CheckResponse(PSDHCD pHcd, PSDREQUEST pReq, SDHCD_RESPONSE_CHECK_MODE CheckMode)
- @category: HD_Reference
-
- @input: pHcd - the host controller definition structure.
- @input: pReq - request containing the response
- @input: CheckMode - mode
-
- @return: SDIO_STATUS
-
- @notes: Host controller drivers must call into this function to validate various command
- responses before continuing with data transfers or for decoding received SPI tokens.
- The CheckMode option determines the type of validation to perform.
- if (CheckMode == SDHCD_CHECK_DATA_TRANS_OK) :
- The host controller must check the card response to determine whether it
- is safe to perform a data transfer. This API only checks commands that
- involve data transfers and checks various status fields in the command response.
- If the card cannot accept data, this function will return a non-successful status that
- should be treated as a request failure. The host driver should complete the request with the
- returned status. Host controller should only call this function in preparation for a
- data transfer.
- if (CheckMode == SDHCD_CHECK_SPI_TOKEN) :
- This API checks the SPI token and returns a timeout status if the illegal command bit is
- set. This simulates the behavior of SD 1/4 bit operation where illegal commands result in
- a command timeout. A driver that supports SPI mode should pass every response to this
- function to determine the appropriate error status to complete the request with. If the
- API returns success, the response indicates that the card accepted the command.
-
- @example: Checking the response before starting the data transfer :
- if (SDIO_SUCCESS(status) && (pReq->Flags & SDREQ_FLAGS_DATA_TRANS)) {
- // check the response to see if we should continue with data
- status = SDIO_CheckResponse(pHcd, pReq, SDHCD_CHECK_DATA_TRANS_OK);
- if (SDIO_SUCCESS(status)) {
- .... start data transfer phase
- } else {
- ... card response indicates that the card cannot handle data
- // set completion status
- pRequest->Status = status;
- }
- }
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- _SDIO_CheckResponse - check response on behalf of the host controller
- Input: pHcd - host controller
- pReq - request containing the response
- CheckMode - mode
- Output:
- Return: status
- Notes:
-
- CheckMode == SDHCD_CHECK_DATA_TRANS_OK :
- The host controller requests a check on the response to determine whether it
- is okay to perform a data transfer. This function only filters on commands that
- involve data. Host controller should only call this function in preparation for a
- data transfer.
-
- CheckMode == SDHCD_CHECK_SPI_TOKEN :
- The bus driver checks the SPI token and returns a timeout status if the illegal command bit is
- set. This simulates the behavior of SD native operation.
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDIO_CheckResponse(PSDHCD pHcd, PSDREQUEST pReq, SDHCD_RESPONSE_CHECK_MODE CheckMode)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- if (CheckMode == SDHCD_CHECK_DATA_TRANS_OK) {
- UINT32 cardStatus;
- UINT8 *pResponse;
- UINT8 convertedResponse[MAX_CARD_RESPONSE_BYTES];
-
- if (!(pReq->Flags & SDREQ_FLAGS_DATA_TRANS) ||
- (pReq->Flags & SDREQ_FLAGS_DATA_SKIP_RESP_CHK) ||
- (GET_SDREQ_RESP_TYPE(pReq->Flags) == SDREQ_FLAGS_NO_RESP)) {
- return SDIO_STATUS_SUCCESS;
- }
- pResponse = pReq->Response;
- /* check SPI mode */
- if (IS_HCD_BUS_MODE_SPI(pHcd)) {
- if (!(pReq->Flags & SDREQ_FLAGS_RESP_SKIP_SPI_FILT)) {
- /* apply conversion */
- ConvertSPI_Response(pReq, NULL);
- } else {
- /* temporarily convert the response, without altering the original */
- ConvertSPI_Response(pReq, convertedResponse);
- /* point to the converted one */
- pResponse = convertedResponse;
- }
- }
-
- switch (GET_SDREQ_RESP_TYPE(pReq->Flags)) {
- case SDREQ_FLAGS_RESP_R1:
- case SDREQ_FLAGS_RESP_R1B:
- cardStatus = SD_R1_GET_CARD_STATUS(pResponse);
- if (!(cardStatus &
- (SD_CS_ILLEGAL_CMD_ERR | SD_CS_CARD_INTERNAL_ERR | SD_CS_GENERAL_ERR))) {
- /* okay for data */
- break;
- }
- /* figure out what it was */
- if (cardStatus & SD_CS_ILLEGAL_CMD_ERR) {
- status = SDIO_STATUS_DATA_STATE_INVALID;
- } else {
- status = SDIO_STATUS_DATA_ERROR_UNKNOWN;
- }
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Check Response Error. R1 CardStatus:0x%X \n",
- cardStatus));
- break;
- case SDREQ_FLAGS_RESP_SDIO_R5:
- cardStatus = SD_R5_GET_RESP_FLAGS(pResponse);
- if (!(cardStatus & SD_R5_CURRENT_CMD_ERRORS)){
- /* all okay */
- break;
- }
-
- status = ConvertCMD52ResponseToSDIOStatus((UINT8)cardStatus);
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Check Response Error. R5 CardStatus:0x%X \n",
- cardStatus));
- break;
- default:
- break;
- }
-
- return status;
- }
-
- {
- UINT8 spiToken;
-
- /* handle SPI token validation */
- switch (GET_SDREQ_RESP_TYPE(pReq->Flags)) {
- case SDREQ_FLAGS_RESP_R2:
- spiToken = GET_SPI_R2_RESP_TOKEN(pReq->Response);
- break;
- case SDREQ_FLAGS_RESP_SDIO_R5:
- spiToken = GET_SPI_SDIO_R5_RESP_TOKEN(pReq->Response);
- break;
- case SDREQ_FLAGS_RESP_R3:
- spiToken = GET_SPI_R3_RESP_TOKEN(pReq->Response);
- break;
- case SDREQ_FLAGS_RESP_SDIO_R4:
- spiToken = GET_SPI_SDIO_R4_RESP_TOKEN(pReq->Response);
- break;
- default:
- /* all other tokesn are SPI R1 type */
- spiToken = GET_SPI_R1_RESP_TOKEN(pReq->Response);
- break;
- }
-
- if ((GET_SDREQ_RESP_TYPE(pReq->Flags) == SDREQ_FLAGS_RESP_SDIO_R5) ||
- (GET_SDREQ_RESP_TYPE(pReq->Flags) == SDREQ_FLAGS_RESP_SDIO_R4)) {
- /* handle SDIO status tokens */
- if ((spiToken & SPI_R5_ILLEGAL_CMD) ||
- (spiToken & SPI_R5_CMD_CRC)) {
- status = SDIO_STATUS_BUS_RESP_TIMEOUT;
- }
- } else {
- /* handle all other status tokens */
- if ((spiToken & SPI_CS_ILLEGAL_CMD) ||
- (spiToken & SPI_CS_CMD_CRC_ERR)) {
- status = SDIO_STATUS_BUS_RESP_TIMEOUT;
- }
- }
- }
-
- return status;
-}
-
diff --git a/drivers/sdio/stack/busdriver/sdio_bus_os.c b/drivers/sdio/stack/busdriver/sdio_bus_os.c
deleted file mode 100644
index e99e5478bbf..00000000000
--- a/drivers/sdio/stack/busdriver/sdio_bus_os.c
+++ /dev/null
@@ -1,828 +0,0 @@
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-@file: sdio_bus_os.c
-
-@abstract: Linux implementation module
-
-#notes: includes module load and unload functions
-
-@notice: Copyright (c), 2004-2006 Atheros Communications, Inc.
-
-
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Portions of this code were developed with information supplied from the
- * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
- *
- * The following conditions apply to the release of the SD simplified specification (�Simplified
- * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
- * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
- * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
- * Specification may require a license from the SD Card Association or other third parties.
- * Disclaimers:
- * The information contained in the Simplified Specification is presented only as a standard
- * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
- * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
- * any damages, any infringements of patents or other right of the SD Card Association or any third
- * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
- * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
- * be construed as an obligation by the SD Card Association to disclose or distribute any technical
- * information, know-how or other confidential information to any third party.
- *
- *
- * The initial developers of the original code are Seung Yi and Paul Lever
- *
- * sdio@atheros.com
- *
- *
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* debug level for this module*/
-#define DBG_DECLARE 3;
-
-#include <linux/sdio/ctsystem.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/init.h>
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <linux/pnp.h>
-void pnp_remove_card_device(struct pnp_dev *dev);
-#include <linux/sdio/sdio_busdriver.h>
-#include <linux/sdio/sdio_lib.h>
-#include "_busdriver.h"
-/* new for 2.6.26-rc1 --- not sure this is a great way... */
-#include "../../../pnp/base.h"
-
-#define DESCRIPTION "SDIO Bus Driver"
-#define AUTHOR "Atheros Communications, Inc."
-
-/* debug print parameter */
-/* configuration and default parameters */
-static int RequestRetries = SDMMC_DEFAULT_CMD_RETRIES;
-module_param(RequestRetries, int, 0644);
-MODULE_PARM_DESC(RequestRetries, "number of command retries");
-static int CardReadyPollingRetry = SDMMC_DEFAULT_CARD_READY_RETRIES;
-module_param(CardReadyPollingRetry, int, 0644);
-MODULE_PARM_DESC(CardReadyPollingRetry, "number of card ready retries");
-static int PowerSettleDelay = SDMMC_POWER_SETTLE_DELAY;
-module_param(PowerSettleDelay, int, 0644);
-MODULE_PARM_DESC(PowerSettleDelay, "delay in ms for power to settle after power changes");
-static int DefaultOperClock = 52000000;
-module_param(DefaultOperClock, int, 0644);
-MODULE_PARM_DESC(DefaultOperClock, "maximum operational clock limit");
-static int DefaultBusMode = SDCONFIG_BUS_WIDTH_4_BIT;
-module_param(DefaultBusMode, int, 0644);
-MODULE_PARM_DESC(DefaultBusMode, "default bus mode: see SDCONFIG_BUS_WIDTH_xxx");
-static int RequestListSize = SDBUS_DEFAULT_REQ_LIST_SIZE;
-module_param(RequestListSize, int, 0644);
-MODULE_PARM_DESC(RequestListSize, "");
-static int SignalSemListSize = SDBUS_DEFAULT_REQ_SIG_SIZE;
-module_param(SignalSemListSize, int, 0644);
-MODULE_PARM_DESC(SignalSemListSize, "");
-static int CDPollingInterval = SDBUS_DEFAULT_CD_POLLING_INTERVAL;
-module_param(CDPollingInterval, int, 0644);
-MODULE_PARM_DESC(CDPollingInterval, "");
-static int DefaultOperBlockLen = SDMMC_DEFAULT_BYTES_PER_BLOCK;
-module_param(DefaultOperBlockLen, int, 0644);
-MODULE_PARM_DESC(DefaultOperBlockLen, "operational block length");
-static int DefaultOperBlockCount = SDMMC_DEFAULT_BLOCKS_PER_TRANS;
-module_param(DefaultOperBlockCount, int, 0644);
-MODULE_PARM_DESC(DefaultOperBlockCount, "operational block count");
-static int ConfigFlags = BD_DEFAULT_CONFIG_FLAGS;
-module_param(ConfigFlags, int, 0644);
-MODULE_PARM_DESC(ConfigFlags, "config flags");
-
-static int HcdRCount = MAX_HCD_REQ_RECURSION;
-module_param(HcdRCount, int, 0644);
-MODULE_PARM_DESC(HcdRCount, "HCD request recursion count");
-
-static void CardDetect_WorkItem(
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-void *context);
-#else
-struct work_struct *ignored);
-#endif
-static void CardDetect_TimerFunc(unsigned long Context);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-static DECLARE_WORK(CardDetectPollWork, CardDetect_WorkItem
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-, 0);
-#else
-);
-#endif
-#endif
-static int RegisterDriver(PSDFUNCTION pFunction);
-static int UnregisterDriver(PSDFUNCTION pFunction);
-
-static struct timer_list CardDetectTimer;
-
-#define SDDEVICE_FROM_OSDEVICE(pOSDevice) container_of(pOSDevice, SDDEVICE, Device)
-#define SDFUNCTION_FROM_OSDRIVER(pOSDriver) container_of(pOSDriver, SDFUNCTION, Driver)
-
-
-/*
- * SDIO_RegisterHostController - register a host controller bus driver
-*/
-SDIO_STATUS SDIO_RegisterHostController(PSDHCD pHcd) {
- /* we are the exported verison, call the internal verison */
- return _SDIO_RegisterHostController(pHcd);
-}
-
-/*
- * SDIO_UnregisterHostController - unregister a host controller bus driver
-*/
-SDIO_STATUS SDIO_UnregisterHostController(PSDHCD pHcd) {
- /* we are the exported verison, call the internal verison */
- return _SDIO_UnregisterHostController(pHcd);
-}
-
-/*
- * SDIO_RegisterFunction - register a function driver
-*/
-SDIO_STATUS SDIO_RegisterFunction(PSDFUNCTION pFunction) {
- int error;
- SDIO_STATUS status;
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - SDIO_RegisterFunction\n"));
-
- /* since we do PnP registration first, we need to check the version */
- if (!CHECK_FUNCTION_DRIVER_VERSION(pFunction)) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: Function Major Version Mismatch (hcd = %d, bus driver = %d)\n",
- GET_SDIO_STACK_VERSION_MAJOR(pFunction), CT_SDIO_STACK_VERSION_MAJOR(g_Version)));
- return SDIO_STATUS_INVALID_PARAMETER;
- }
-
- /* we are the exported verison, call the internal verison after registering with the bus
- we handle probes internally to the bus driver */
- if ((error = RegisterDriver(pFunction)) < 0) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO BusDriver - SDIO_RegisterFunction, failed to register with system bus driver: %d\n",
- error));
- status = OSErrorToSDIOError(error);
- } else {
- status = _SDIO_RegisterFunction(pFunction);
- if (!SDIO_SUCCESS(status)) {
- UnregisterDriver(pFunction);
- }
- }
-
- return status;
-}
-
-/*
- * SDIO_UnregisterFunction - unregister a function driver
-*/
-SDIO_STATUS SDIO_UnregisterFunction(PSDFUNCTION pFunction) {
- SDIO_STATUS status;
- /* we are the exported verison, call the internal verison */
- status = _SDIO_UnregisterFunction(pFunction);
- UnregisterDriver(pFunction);
- return status;
-}
-
-/*
- * SDIO_HandleHcdEvent - tell core an event occurred
-*/
-SDIO_STATUS SDIO_HandleHcdEvent(PSDHCD pHcd, HCD_EVENT Event) {
- /* we are the exported verison, call the internal verison */
- DBG_PRINT(SDIODBG_HCD_EVENTS, ("SDIO Bus Driver: SDIO_HandleHcdEvent, event type 0x%X, HCD:0x%X\n",
- Event, (UINT)pHcd));
- return _SDIO_HandleHcdEvent(pHcd, Event);
-}
-
-/* get default settings */
-SDIO_STATUS _SDIO_BusGetDefaultSettings(PBDCONTEXT pBdc)
-{
- /* these defaults are module params */
- pBdc->RequestRetries = RequestRetries;
- pBdc->CardReadyPollingRetry = CardReadyPollingRetry;
- pBdc->PowerSettleDelay = PowerSettleDelay;
- pBdc->DefaultOperClock = DefaultOperClock;
- pBdc->DefaultBusMode = DefaultBusMode;
- pBdc->RequestListSize = RequestListSize;
- pBdc->SignalSemListSize = SignalSemListSize;
- pBdc->CDPollingInterval = CDPollingInterval;
- pBdc->DefaultOperBlockLen = DefaultOperBlockLen;
- pBdc->DefaultOperBlockCount = DefaultOperBlockCount;
- pBdc->ConfigFlags = ConfigFlags;
- pBdc->MaxHcdRecursion = HcdRCount;
- return SDIO_STATUS_SUCCESS;
-}
-
-static void CardDetect_TimerFunc(unsigned long Context)
-{
- DBG_PRINT(SDIODBG_CD_TIMER, ("+ SDIO BusDriver Card Detect Timer\n"));
-
- /* timers run in an ISR context and cannot block or sleep, so we need
- * to queue a work item to call the bus driver timer notification */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- if (schedule_work(&CardDetectPollWork) <= 0) {
- DBG_PRINT(SDDBG_ERROR, ("Failed to queue Card Detect timer!\n"));
- }
-#else
- CardDetect_WorkItem(NULL);
-#endif
- DBG_PRINT(SDIODBG_CD_TIMER, ("- SDIO BusDriver Card Detect Timer\n"));
-}
-
-/*
- * Initialize any timers we are using
-*/
-SDIO_STATUS InitializeTimers(void)
-{
- init_timer(&CardDetectTimer);
- printk(KERN_INFO "init_timer(&CardDetectTimer) = %p\n", &CardDetectTimer);
- CardDetectTimer.function = CardDetect_TimerFunc;
- CardDetectTimer.data = 0;
- return SDIO_STATUS_SUCCESS;
-}
-
-/*
- * cleanup timers
-*/
-SDIO_STATUS CleanupTimers(void)
-{
- del_timer(&CardDetectTimer);
- return SDIO_STATUS_SUCCESS;
-}
-
-
-/*
- * Queue a timer, Timeout is in milliseconds
-*/
-SDIO_STATUS QueueTimer(INT TimerID, UINT32 TimeOut)
-{
- UINT32 delta;
-
- /* convert timeout to ticks */
- delta = (TimeOut * HZ)/1000;
- if (delta == 0) {
- delta = 1;
- }
- DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO BusDriver - SDIO_QueueTimer System Ticks Per Sec:%d \n",HZ));
- DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO BusDriver - SDIO_QueueTimer TimerID: %d TimeOut:%d MS, requires %d Ticks\n",
- TimerID,TimeOut,delta));
- switch (TimerID) {
- case SDIOBUS_CD_TIMER_ID:
- CardDetectTimer.expires = jiffies + delta;
- add_timer(&CardDetectTimer);
- break;
- default:
- return SDIO_STATUS_INVALID_PARAMETER;
- }
-
- return SDIO_STATUS_SUCCESS;
-}
-
-/* check a response on behalf of the host controller, to allow it to proceed with a
- * data transfer */
-SDIO_STATUS SDIO_CheckResponse(PSDHCD pHcd, PSDREQUEST pReq, SDHCD_RESPONSE_CHECK_MODE CheckMode)
-{
- return _SDIO_CheckResponse(pHcd,pReq,CheckMode);
-}
-
-/*
- * CardDetect_WorkItem - the work item for handling card detect polling interrupt
-*/
-static void CardDetect_WorkItem(
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-void *context)
-#else
-struct work_struct *ignored)
-#endif
-{
- /* call bus driver function */
- SDIO_NotifyTimerTriggered(SDIOBUS_CD_TIMER_ID);
-}
-
-/*
- * OS_IncHcdReference - increment host controller driver reference count
-*/
-SDIO_STATUS Do_OS_IncHcdReference(PSDHCD pHcd)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- do {
- if (NULL == pHcd->pModule) {
- /* hcds that are 2.3 or higher should set this */
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: HCD:%s should set module ptr!\n",
- (pHcd->pName != NULL) ? pHcd->pName : "Unknown"));
- break;
- }
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- if (!try_module_get(pHcd->pModule)) {
- status = SDIO_STATUS_ERROR;
- }
-#else
- if (!try_inc_mod_count(pHcd->pModule)) {
- status = SDIO_STATUS_ERROR;
- }
-#endif
-
- } while (FALSE);
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: HCD:%s failed to get module\n",
- (pHcd->pName != NULL) ? pHcd->pName : "Unknown"));
- }
-
- return status;
-}
-
-/*
- * OS_DecHcdReference - decrement host controller driver reference count
-*/
-SDIO_STATUS Do_OS_DecHcdReference(PSDHCD pHcd)
-{
- if (pHcd->pModule != NULL) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- module_put(pHcd->pModule);
-#else
- /* 2.4 or lower */
- __MOD_DEC_USE_COUNT(pHcd->pModule);
-#endif
- }
- return SDIO_STATUS_SUCCESS;
-}
-
-/****************************************************************************************/
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#include <linux/pnp.h>
-
-#if !defined(CONFIG_PNP)
-#error "CONFIG_PNP not defined"
-#endif
-
-static ULONG InUseDevices = 0;
-static spinlock_t InUseDevicesLock = SPIN_LOCK_UNLOCKED;
-
-static const struct pnp_device_id pnp_idtable[] = {
- {"SD_XXXX", 0}
-};
-static int sdio_get_resources(struct pnp_dev * pDev)
-{
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - sdio_get_resources: %s\n",
- pDev->dev.bus_id));
- return 0;
-}
-static int sdio_set_resources(struct pnp_dev * pDev)
-{
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - sdio_set_resources: %s\n",
- pDev->dev.bus_id));
- return 0;
-}
-
-static int sdio_disable_resources(struct pnp_dev *pDev)
-{
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - sdio_disable_resources: %s\n",
- pDev->dev.bus_id));
- if (pDev != NULL) {
- pDev->active = 0;
- }
- return 0;
-}
-void release(struct device * pDev) {
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - release: %s\n",
- pDev->bus_id));
- return;
-}
-struct pnp_protocol sdio_protocol = {
- .name = "SDIO",
- .get = sdio_get_resources,
- .set = sdio_set_resources,
- .disable = sdio_disable_resources,
- .dev.release = release,
-};
-
-/*
- * driver_probe - probe for OS based driver
-*/
-static int driver_probe(struct pnp_dev* pOSDevice, const struct pnp_device_id *pId)
-{
- PSDDEVICE pDevice = SDDEVICE_FROM_OSDEVICE(&pOSDevice);
- PSDFUNCTION pFunction = pDevice->Device->dev.driver_data;
-
- if (pFunction == NULL) {
- return -1;
- }
-
- if (strcmp(pFunction->pName, pOSDevice->dev.driver->name) == 0) {
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - driver_probe, match: %s/%s driver: %s\n",
- pOSDevice->dev.bus_id, pFunction->pName, pOSDevice->dev.driver->name));
- return 1;
- } else {
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - driver_probe, no match: %s/%s driver: %s\n",
- pOSDevice->dev.bus_id, pFunction->pName, pOSDevice->dev.driver->name));
- return -1;
- }
-/* if (pOSDevice->id != NULL) {
- if (strcmp(pOSDevice->id->id, pId->id) == 0) {
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - driver_probe, match: %s/%s\n",
- pOSDevice->dev.bus_id, pId->id));
- return 1;
- }
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - driver_probe, did not match: %s/%s/%s\n",
- pOSDevice->dev.bus_id, pId->id, pOSDevice->id->id));
- } else {
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - driver_probe, did not match: %s/%s\n",
- pOSDevice->dev.bus_id, pId->id));
- }
- return -1;
-*/
-//?? if (pDevice->Device.dev.driver_data != NULL) {
-//?? if (pDevice->Device.dev.driver_data == pFunction) {
-//?? if (pDevice->Device.data != NULL) {
-//?? if (pDevice->Device.data == pFunction) {
-//?? DBG_PRINT(SDDBG_TRACE,
-//?? ("SDIO BusDriver - driver_probe, match: %s\n",
-//?? pOSDevice->dev.bus_id));
-//?? return 1;
-//?? }
-//?? }
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - driver_probe, match: %s\n",
- pOSDevice->dev.bus_id));
- return 1;
-}
-
-static int RegisterDriver(PSDFUNCTION pFunction)
-{
- memset(&pFunction->Driver, 0, sizeof(pFunction->Driver));
- pFunction->Driver.name = pFunction->pName;
- pFunction->Driver.probe = driver_probe;
- pFunction->Driver.id_table = pnp_idtable;
- pFunction->Driver.flags = PNP_DRIVER_RES_DO_NOT_CHANGE;
-
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - SDIO_RegisterFunction, registering driver: %s\n",
- pFunction->Driver.name));
- return pnp_register_driver(&pFunction->Driver);
-}
-
-static int UnregisterDriver(PSDFUNCTION pFunction)
-{
- DBG_PRINT(SDDBG_TRACE,
- ("+SDIO BusDriver - UnregisterDriver, driver: %s\n",
- pFunction->Driver.name));
- pnp_unregister_driver(&pFunction->Driver);
- DBG_PRINT(SDDBG_TRACE,
- ("-SDIO BusDriver - UnregisterDriver\n"));
- return 0;
-}
-
-/*
- * OS_InitializeDevice - initialize device that will be registered
-*/
-SDIO_STATUS OS_InitializeDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction)
-{
- char id_name[20];
-
- /* set the id as slot number/function number */
- snprintf(id_name, sizeof(id_name) - 1, "SD_%02X%02X",
- pDevice->pHcd->SlotNumber, (UINT)SDDEVICE_GET_SDIO_FUNCNO(pDevice));
-
- pDevice->Device = pnp_alloc_dev(&sdio_protocol, pDevice->pHcd->SlotNumber + 1, id_name);
- pDevice->Device->dev.driver_data = (PVOID)pFunction;
-//?? pDevice->Device.data = (PVOID)pFunction;
-//?? pDevice->Device.dev.driver = &pFunction->Driver.driver;
-//?? pDevice->Device.driver = &pFunction->Driver;
-//?? pDevice->Device.dev.release = release;
- /* get a unique device number, must be done with locks held */
- spin_lock(&InUseDevicesLock);
- pDevice->Device->number = FirstClearBit(&InUseDevices);
- SetBit(&InUseDevices, pDevice->Device->number);
- spin_unlock(&InUseDevicesLock);
- pDevice->Device->capabilities = PNP_REMOVABLE | PNP_DISABLE;
- pDevice->Device->active = 1;
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_InitializeDevice adding id: %s\n",
- id_name));
- /* deal with DMA settings */
- if (pDevice->pHcd->pDmaDescription != NULL) {
- pDevice->Device->dev.dma_mask = &pDevice->pHcd->pDmaDescription->Mask;
- pDevice->Device->dev.coherent_dma_mask = pDevice->pHcd->pDmaDescription->Mask;
- }
-
- return SDIO_STATUS_SUCCESS;
-}
-
-/*
- * OS_AddDevice - must be pre-initialized with OS_InitializeDevice
-*/
-SDIO_STATUS OS_AddDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction)
-{
- int error;
- DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_AddDevice adding function: %s\n",
- pFunction->pName));
- error = pnp_add_device(pDevice->Device);
- if (error < 0) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO BusDriver - OS_AddDevice failed pnp_add_device: %d\n",
- error));
- }
- /* replace the buggy pnp's release */
- pDevice->Device->dev.release = release;
-
- return OSErrorToSDIOError(error);
-}
-
-/*
- * OS_RemoveDevice - unregister device with driver and bus
-*/
-void OS_RemoveDevice(PSDDEVICE pDevice)
-{
- DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_RemoveDevice \n"));
- pnp_remove_card_device(pDevice->Device);
- spin_lock(&InUseDevicesLock);
- ClearBit(&InUseDevices, pDevice->Device->number);
- spin_unlock(&InUseDevicesLock);
-
- if (pDevice->Device->id != NULL) {
- KernelFree(pDevice->Device->id);
- pDevice->Device->id = NULL;
- }
-
- KernelFree(pDevice->Device);
-}
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Add OS device to bus driver.
-
- @function name: SDIO_BusAddOSDevice
- @category: HD_Reference
-
- @output: pDma - descrip[tion of support DMA or NULL
- @output: pDriver - assigned driver object
- @output: pDevice - assigned device object
-
- @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when successful.
-
- @notes: If the HCD does not register with the driver sub-system directly (like in the PCI case),
- then it should register with the bus driver to obtain OS dependent device objects.
- All input structures should be maintained throughout the life of the driver.
-
- @example: getting device objects:
- typedef struct _SDHCD_DRIVER {
- OS_PNPDEVICE HcdDevice; / * the OS device for this HCD * /
- OS_PNPDRIVER HcdDriver; / * the OS driver for this HCD * /
- SDDMA_DESCRIPTION Dma; / * driver DMA description * /
- }SDHCD_DRIVER, *PSDHCD_DRIVER;
-
- typedef struct _SDHCD_DRIVER_CONTEXT {
- PTEXT pDescription; / * human readable device decsription * /
- SDLIST DeviceList; / * the list of current devices handled by this driver * /
- OS_SEMAPHORE DeviceListSem; / * protection for the DeviceList * /
- UINT DeviceCount; / * number of devices currently installed * /
- SDHCD_DRIVER Driver; / * OS dependent driver specific info * /
- }SDHCD_DRIVER_CONTEXT, *PSDHCD_DRIVER_CONTEXT;
-
- static SDHCD_DRIVER_CONTEXT HcdContext = {
- .pDescription = DESCRIPTION,
- .DeviceCount = 0,
- .Driver.HcdDevice.name = "sdio_xxx_hcd",
- .Driver.HcdDriver.name = "sdio_xxx_hcd",
- }
- .....
- status = SDIO_BusAddOSDevice(NULL, &HcdContext.Driver, &HcdContext.Device);
- if (SDIO_SUCCESS(status) {
- return Probe(&HcdContext.Device);
- }
- return SDIOErrorToOSError(status);
-
- @see also: SDIO_BusRemoveOSDevice
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS SDIO_BusAddOSDevice(PSDDMA_DESCRIPTION pDma, POS_PNPDRIVER pDriver, POS_PNPDEVICE *outDevice, const char* name)
-{
- int err;
- struct pnp_device_id *pFdid;
- static int slotNumber = 0; /* we just use an increasing count for the slots number */
- struct pnp_dev* pDevice;
-
- pFdid = KernelAlloc(sizeof(struct pnp_device_id)*2);
- /* set the id as slot number/function number */
- snprintf(pFdid[0].id, sizeof(pFdid[0].id), "SD_%02X08",
- slotNumber++);
- pFdid[0].driver_data = 0;
- pFdid[1].id[0] = '\0';
- pFdid[1].driver_data = 0;
-
- pDriver->id_table = pFdid;
- pDriver->flags = PNP_DRIVER_RES_DO_NOT_CHANGE;
- err = pnp_register_driver(pDriver);
- if (err < 0) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO BusDriver - SDIO_GetBusOSDevice, failed registering driver: %s, err: %d\n",
- pDriver->name, err));
- return OSErrorToSDIOError(err);
- }
-
- pDevice = pnp_alloc_dev(&sdio_protocol, slotNumber - 1, pFdid[0].id);
- if (!pDevice)
- return -EINVAL;
-
- if (pDma != NULL) {
- pDevice->dev.dma_mask = &pDma->Mask;
- pDevice->dev.coherent_dma_mask = pDma->Mask;
- }
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO BusDriver - SDIO_GetBusOSDevice, registering driver: %s DMAmask: 0x%x\n",
- pDriver->name, (UINT)*pDevice->dev.dma_mask));
-
- pDevice->protocol = &sdio_protocol;
- pDevice->capabilities = PNP_REMOVABLE | PNP_DISABLE;
- pDevice->active = 1;
-
-
- /* get a unique device number */
- spin_lock(&InUseDevicesLock);
- pDevice->number = FirstClearBit(&InUseDevices);
- SetBit(&InUseDevices, pDevice->number);
- spin_unlock(&InUseDevicesLock);
-
- err = pnp_add_device(pDevice);
- if (err < 0) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO BusDriver - SDIO_GetBusOSDevice failed pnp_device_add: %d\n",
- err));
- pnp_unregister_driver(pDriver);
- }
- /* replace the buggy pnp's release */
- pDevice->dev.release = release;
- *outDevice = pDevice;
- return OSErrorToSDIOError(err);
-}
-
-/**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Return OS device from bus driver.
-
- @function name: SDIO_BusRemoveOSDevice
- @category: HD_Reference
-
- @input: pDriver - setup PNP driver object
- @input: pDevice - setup PNP device object
-
- @return: none
-
-
- @example: returning device objects:
- SDIO_BusRemoveOSDevice(&HcdContext.Driver, &HcdContext.Device);
-
-
- @see also: SDIO_BusAddOSDevice
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void SDIO_BusRemoveOSDevice(POS_PNPDRIVER pDriver, POS_PNPDEVICE pDevice)
-{
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO BusDriver - SDIO_PutBusOSDevice, unregistering driver: %s\n",
- pDriver->name));
-
- pnp_remove_card_device(pDevice);
- if (pDevice->id != NULL) {
- KernelFree(pDevice->id);
- pDevice->id = NULL;
- }
-
- spin_lock(&InUseDevicesLock);
- ClearBit(&InUseDevices, pDevice->number);
- spin_unlock(&InUseDevicesLock);
-
- pnp_unregister_driver(pDriver);
- if (pDriver->id_table != NULL) {
- KernelFree((void *)pDriver->id_table);
- pDriver->id_table = NULL;
- }
-
-}
-
-
-/*
- * module init
-*/
-static int __init sdio_busdriver_init(void) {
- SDIO_STATUS status;
- int error;
- REL_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: loaded\n"));
- if (!SDIO_SUCCESS((status = _SDIO_BusDriverInitialize()))) {
- return SDIOErrorToOSError(status);
- }
- /* register the sdio bus */
- error = pnp_register_protocol(&sdio_protocol);
- if (error < 0) {
- REL_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: failed to register bus device, %d\n", error));
- _SDIO_BusDriverCleanup();
- return error;
- }
- return 0;
-}
-
-/*
- * module cleanup
-*/
-static void __exit sdio_busdriver_cleanup(void) {
- REL_PRINT(SDDBG_TRACE, ("SDIO unloaded\n"));
- _SDIO_BusDriverCleanup();
- pnp_unregister_protocol(&sdio_protocol);
-DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - unloaded 1\n"));
-}
-EXPORT_SYMBOL(SDIO_BusAddOSDevice);
-EXPORT_SYMBOL(SDIO_BusRemoveOSDevice);
-
-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- /* 2.4 */
-static int RegisterDriver(PSDFUNCTION pFunction)
-{
- return 0;
-}
-
-static int UnregisterDriver(PSDFUNCTION pFunction)
-{
- DBG_PRINT(SDDBG_TRACE,
- ("+-SDIO BusDriver - UnregisterDriver, driver: \n"));
- return 0;
-}
-
-/*
- * OS_InitializeDevice - initialize device that will be registered
-*/
-SDIO_STATUS OS_InitializeDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction)
-{
- return SDIO_STATUS_SUCCESS;
-}
-
-/*
- * OS_AddDevice - must be pre-initialized with OS_InitializeDevice
-*/
-SDIO_STATUS OS_AddDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction)
-{
- DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_AddDevice adding function: %s\n",
- pFunction->pName));
- return SDIO_STATUS_SUCCESS;
-
-}
-
-/*
- * OS_RemoveDevice - unregister device with driver and bus
-*/
-void OS_RemoveDevice(PSDDEVICE pDevice)
-{
- DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_RemoveDevice \n"));
-}
-
-/*
- * module init
-*/
-static int __init sdio_busdriver_init(void) {
- SDIO_STATUS status;
- REL_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: loaded\n"));
- if (!SDIO_SUCCESS((status = _SDIO_BusDriverInitialize()))) {
- return SDIOErrorToOSError(status);
- }
- return 0;
-}
-
-/*
- * module cleanup
-*/
-static void __exit sdio_busdriver_cleanup(void) {
- REL_PRINT(SDDBG_TRACE, ("SDIO unloaded\n"));
- _SDIO_BusDriverCleanup();
-}
-#else ////KERNEL_VERSION
-#error "unsupported kernel version: "UTS_RELEASE
-#endif //KERNEL_VERSION
-
-MODULE_LICENSE("GPL and additional rights");
-MODULE_DESCRIPTION(DESCRIPTION);
-MODULE_AUTHOR(AUTHOR);
-
-module_init(sdio_busdriver_init);
-module_exit(sdio_busdriver_cleanup);
-EXPORT_SYMBOL(SDIO_RegisterHostController);
-EXPORT_SYMBOL(SDIO_UnregisterHostController);
-EXPORT_SYMBOL(SDIO_HandleHcdEvent);
-EXPORT_SYMBOL(SDIO_CheckResponse);
-EXPORT_SYMBOL(SDIO_RegisterFunction);
-EXPORT_SYMBOL(SDIO_UnregisterFunction);
diff --git a/drivers/sdio/stack/busdriver/sdio_function.c b/drivers/sdio/stack/busdriver/sdio_function.c
deleted file mode 100644
index 78b8e17999a..00000000000
--- a/drivers/sdio/stack/busdriver/sdio_function.c
+++ /dev/null
@@ -1,715 +0,0 @@
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-@file: sdio_function.c
-
-@abstract: OS independent bus driver support for function drivers
-
-@notes: This file supports the interface between SDIO function drivers and the bus driver.
-
-@notice: Copyright (c), 2004-2005 Atheros Communications, Inc.
-
-
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Portions of this code were developed with information supplied from the
- * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
- *
- * The following conditions apply to the release of the SD simplified specification (�Simplified
- * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
- * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
- * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
- * Specification may require a license from the SD Card Association or other third parties.
- * Disclaimers:
- * The information contained in the Simplified Specification is presented only as a standard
- * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
- * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
- * any damages, any infringements of patents or other right of the SD Card Association or any third
- * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
- * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
- * be construed as an obligation by the SD Card Association to disclose or distribute any technical
- * information, know-how or other confidential information to any third party.
- *
- *
- * The initial developers of the original code are Seung Yi and Paul Lever
- *
- * sdio@atheros.com
- *
- *
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-#define MODULE_NAME SDBUSDRIVER
-#include <linux/sdio/ctsystem.h>
-#include <linux/sdio/sdio_busdriver.h>
-#include <linux/sdio/sdio_lib.h>
-#include "_busdriver.h"
-
-static SDIO_STATUS ProbeForDevice(PSDFUNCTION pFunction);
-
-#ifdef CT_MAN_CODE_CHECK
-static UINT16 ManCodeCheck = CT_MAN_CODE_CHECK;
-#endif
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Register a function driver with the bus driver.
-
- @function name: SDIO_RegisterFunction
- @prototype: SDIO_STATUS SDIO_RegisterFunction(PSDFUNCTION pFunction)
- @category: PD_Reference
- @input: pFunction - the function definition structure.
-
- @output: none
-
- @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when succesful.
-
- @notes: Each function driver must register with the bus driver once upon loading.
- The calling function must be prepared to receive a Probe callback before
- this function returns. This will occur when an perpheral device is already
- pluugged in that is supported by this function.
- The function driver should unregister itself when exiting.
- The bus driver checks for possible function drivers to support a device
- in reverse registration order.
-
- @example: Registering a function driver:
- //list of devices supported by this function driver
- static SD_PNP_INFO Ids[] = {
- {.SDIO_ManufacturerID = 0xaa55,
- .SDIO_ManufacturerCode = 0x5555,
- .SDIO_FunctionNo = 1},
- {} //list is null termintaed
- };
- static GENERIC_FUNCTION_CONTEXT FunctionContext = {
- .Function.pName = "sdio_generic", //name of the device
- .Function.Version = CT_SDIO_STACK_VERSION_CODE, // set stack version
- .Function.MaxDevices = 1, //maximum number of devices supported by this driver
- .Function.NumDevices = 0, //current number of devices, always zero to start
- .Function.pIds = Ids, //the list of devices supported by this device
- .Function.pProbe = Probe, //pointer to the function drivers Probe function
- // that will be called when a possibly supported device
- // is inserted.
- .Function.pRemove = Remove, //pointer to the function drivers Remove function
- / that will be called when a device is removed.
- .Function.pContext = &FunctionContext, //data value that will be passed into Probe and
- // Remove callbacks.
- };
- SDIO_STATUS status;
- status = SDIO_RegisterFunction(&FunctionContext.Function)
- if (!SDIO_SUCCESS(status)) {
- ...failed to register
- }
-
- @see also: SDIO_UnregisterFunction
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDIO_RegisterFunction(PSDFUNCTION pFunction)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
-#ifdef CT_MAN_CODE_CHECK
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO Bus Driver: _SDIO_RegisterFunction: WARNING, this version is locked to Memory cards and SDIO cards with JEDEC IDs of: 0x%X\n",
- ManCodeCheck));
-#else
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: _SDIO_RegisterFunction\n"));
-#endif
-
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: Function Driver Stack Version: %d.%d \n",
- GET_SDIO_STACK_VERSION_MAJOR(pFunction),GET_SDIO_STACK_VERSION_MINOR(pFunction)));
-
- if (!CHECK_FUNCTION_DRIVER_VERSION(pFunction)) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Bus Driver: Function Major Version Mismatch (hcd = %d, bus driver = %d)\n",
- GET_SDIO_STACK_VERSION_MAJOR(pFunction), CT_SDIO_STACK_VERSION_MAJOR(g_Version)));
- return SDIO_STATUS_INVALID_PARAMETER;
- }
-
-
- /* sanity check the driver */
- if ((pFunction == NULL) ||
- (pFunction->pProbe == NULL) ||
- (pFunction->pIds == NULL)) {
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_RegisterFunction, invalid registration data\n"));
- return SDIO_STATUS_INVALID_PARAMETER;
- }
- /* protect the function list and add the function */
- if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->FunctionListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- SignalInitialize(&pFunction->CleanupReqSig);
- SDLIST_INIT(&pFunction->DeviceList);
- SDListAdd(&pBusContext->FunctionList, &pFunction->SDList);
- if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) {
- goto cleanup; /* wait interrupted */
- }
-
- /* see if we have devices for this new function driver */
- ProbeForDevice(pFunction);
-
- return status;
-cleanup:
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_RegisterFunction, error exit 0x%X\n", status));
- return status;
-}
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Unregister a function driver with the bus driver.
-
- @function name: SDIO_UnregisterFunction
- @prototype: SDIO_STATUS SDIO_UnregisterFunction(PSDFUNCTION pFunction)
- @category: PD_Reference
-
- @input: pFunction - the function definition structure.
-
- @output: none
-
- @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when succesful.
-
- @notes: Each function driver must unregister from the bus driver when the function driver
- exits.
- A function driver must disconnect from any interrupts before calling this function.
-
- @example: Unregistering a function driver:
- SDIO_UnregisterFunction(&FunctionContext.Function);
-
- @see also: SDIO_RegisterFunction
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDIO_UnregisterFunction(PSDFUNCTION pFunction)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDDEVICE pDevice;
-
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: _SDIO_UnregisterFunction\n"));
-
- /* protect the function list and synchronize with Probe() and Remove()*/
- if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->FunctionListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- /* remove this function from the function list */
- SDListRemove(&pFunction->SDList);
- /* now remove this function as the handler for any of its devices */
- SDITERATE_OVER_LIST_ALLOW_REMOVE(&pFunction->DeviceList, pDevice, SDDEVICE,FuncListLink) {
- if (pDevice->pFunction == pFunction) {
- /* notify removal */
- NotifyDeviceRemove(pDevice);
- }
- }SDITERATE_END;
-
- SignalDelete(&pFunction->CleanupReqSig);
-
- if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: _SDIO_UnregisterFunction\n"));
- return status;
-
-cleanup:
- DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: _SDIO_UnregisterFunction, error exit 0x%X\n", status));
- return status;
-}
-
-/* documentation headers only for Probe and Remove */
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: This function is called by the Busdriver when a device is inserted that can be supported by this function driver.
-
- @function name: Probe
- @prototype: BOOL (*pProbe)(struct _SDFUNCTION *pFunction, struct _SDDEVICE *pDevice)
- @category: PD_Reference
-
- @input: pFunction - the function definition structure that was passed to Busdriver
- via the SDIO_RegisterFunction.
- @input: pDevice - the description of the newly inserted device.
-
- @output: none
-
- @return: TRUE - this function driver will suport this device
- FALSE - this function driver will not support this device
-
- @notes: The Busdriver calls the Probe function of a function driver to inform it that device is
- available for the function driver to control. The function driver should initialize the
- device and be pepared to acceopt any interrupts from the device before returning.
-
- @example: Example of typical Probe function callback:
- static BOOL Probe(PSDFUNCTION pFunction, PSDDEVICE pDevice) {
- ...get the our context info passed into the SDIO_RegisterFunction
- PSDXXX_DRIVER_CONTEXT pFunctionContext =
- (PSDXXX_DRIVER_CONTEXT)pFunction->pContext;
- SDIO_STATUS status;
- //test the identification of this device and ensure we want to support it
- // we can test based on class, or use more specific tests on SDIO_ManufacturerID, etc.
- if (pDevice->pId[0].SDIO_FunctionClass == XXX) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO XXX Function: Probe - card matched (0x%X/0x%X/0x%X)\n",
- pDevice->pId[0].SDIO_ManufacturerID,
- pDevice->pId[0].SDIO_ManufacturerCode,
- pDevice->pId[0].SDIO_FunctionNo));
- ...
-
- @see also: SDIO_RegisterFunction
- @see also: Remove
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-BOOL FilterPnpInfo(PSDDEVICE pDevice)
-{
-#ifdef CT_MAN_CODE_CHECK
- if (pDevice->pId[0].CardFlags & CARD_SDIO) {
- if (pDevice->pId[0].SDIO_ManufacturerCode != ManCodeCheck) {
- DBG_PRINT(SDDBG_ERROR,
- ("SDIO Card with JEDEC ID:0x%X , not Allowed! Driver check halted. "
- "Please Contact sales@codetelligence.com.\n",
- pDevice->pId[0].SDIO_ManufacturerCode));
- return FALSE;
- }
- }
- return TRUE;
-#else
- return TRUE;
-#endif
-}
-
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: This function is called by the Busdriver when a device controlled by this function
- function driver is removed.
-
- @function name: Remove
- @prototype: void (*pRemove)(struct _SDFUNCTION *pFunction, struct _SDDEVICE *pDevice)
- @category: PD_Reference
-
- @input: pFunction - the function definition structure that was passed to Busdriver
- via the SDIO_RegisterFunction.
- @input: pDevice - the description of the device being removed.
-
- @output: none
-
- @return: none
-
- @notes: The Busdriver calls the Remove function of a function driver to inform it that device it
- was supporting has been removed. The device has already been removed, so no further I/O
- to the device can be performed.
-
- @example: Example of typical Remove function callback:
- void Remove(PSDFUNCTION pFunction, PSDDEVICE pDevice) {
- // get the our context info passed into the SDIO_RegisterFunction
- PSDXXX_DRIVER_CONTEXT pFunctionContext =
- (PSDXXX_DRIVER_CONTEXT)pFunction->pContext;
- ...free any acquired resources.
-
- @see also: SDIO_RegisterFunction
- @see also: Probe
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/*
- * ProbeForFunction - look for a function driver to handle this card
- *
-*/
-SDIO_STATUS ProbeForFunction(PSDDEVICE pDevice, PSDHCD pHcd) {
- SDIO_STATUS status;
- PSDLIST pList;
- PSDFUNCTION pFunction;
-
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: ProbeForFunction\n"));
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction - Dump of Device PNP Data: \n"));
- DBG_PRINT(SDDBG_TRACE, (" Card Flags 0x%X \n", pDevice->pId[0].CardFlags));
- if (pDevice->pId[0].CardFlags & CARD_SDIO) {
- DBG_PRINT(SDDBG_TRACE, (" SDIO MANF: 0x%X \n", pDevice->pId[0].SDIO_ManufacturerID));
- DBG_PRINT(SDDBG_TRACE, (" SDIO MANFCODE: 0x%X \n", pDevice->pId[0].SDIO_ManufacturerCode));
- DBG_PRINT(SDDBG_TRACE, (" SDIO FuncNo: %d \n", pDevice->pId[0].SDIO_FunctionNo));
- DBG_PRINT(SDDBG_TRACE, (" SDIO FuncClass: %d \n", pDevice->pId[0].SDIO_FunctionClass));
- }
- if (pDevice->pId[0].CardFlags & (CARD_MMC | CARD_SD)) {
- DBG_PRINT(SDDBG_TRACE, (" SDMMC MANFID: 0x%X \n",pDevice->pId[0].SDMMC_ManfacturerID));
- DBG_PRINT(SDDBG_TRACE, (" SDMMC OEMID: 0x%X \n",pDevice->pId[0].SDMMC_OEMApplicationID));
- }
-
- if (!FilterPnpInfo(pDevice)) {
- status = SDIO_STATUS_SUCCESS;
- goto cleanup;
- }
-
- /* protect the function list */
- if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->FunctionListSem)))) {
- goto cleanup; /* wait interrupted */
- }
-
- /* protect against ProbeForDevice */
- if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->DeviceListSem)))) {
- /* release the function list semaphore we just took */
- SemaphorePost(&pBusContext->FunctionListSem);
- goto cleanup;
- }
-
- if (pDevice->pFunction != NULL) {
- /* device already has a function driver handling it */
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction, device already has function\n"));
- /* release function list */
- SemaphorePost(&pBusContext->DeviceListSem);
- /* release function list */
- SemaphorePost(&pBusContext->FunctionListSem);
- /* just return success */
- status = SDIO_STATUS_SUCCESS;
- goto cleanup;
- }
-
- /* release device list */
- SemaphorePost(&pBusContext->DeviceListSem);
-
- /* walk functions looking for one that can handle this device */
- SDITERATE_OVER_LIST(&pBusContext->FunctionList, pList) {
- pFunction = CONTAINING_STRUCT(pList, SDFUNCTION, SDList);
- if (pFunction->NumDevices >= pFunction->MaxDevices) {
- /* function can't support any more devices */
- continue;
- }
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction - checking: %s \n",
- pFunction->pName));
-
- /* see if this function handles this device */
- if (IsPotentialIdMatch(pDevice->pId, pFunction->pIds)) {
- if (!FilterPnpInfo(pDevice)) {
- break;
- }
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction -Got Match, probing: %s \n",
- pFunction->pName));
- /* we need to setup with the OS bus driver before the probe, so probe can
- do OS operations. */
- OS_InitializeDevice(pDevice, pFunction);
- if (!SDIO_SUCCESS(OS_AddDevice(pDevice, pFunction))) {
- break;
- }
- /* close enough match, ask the function driver if it supports us */
- if (pFunction->pProbe(pFunction, pDevice)) {
- /* she accepted the device, add to list */
- pDevice->pFunction = pFunction;
- SDListAdd(&pFunction->DeviceList, &pDevice->FuncListLink);
- pFunction->NumDevices++;
- break;
- } else {
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: %s did not claim the device \n",
- pFunction->pName));
- /* didn't take this device */
- OS_RemoveDevice(pDevice);
- }
-
- }
- }
- if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: ProbeForFunction\n"));
- return status;
-cleanup:
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: ProbeForFunction, error exit 0x%X\n", status));
- return status;
-}
-
-/*
- * ProbeForDevice - look for a device that this function driver supports
- *
-*/
-static SDIO_STATUS ProbeForDevice(PSDFUNCTION pFunction) {
- SDIO_STATUS status;
- PSDLIST pList;
- PSDDEVICE pDevice;
-
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice\n"));
- if (pFunction->NumDevices >= pFunction->MaxDevices) {
- /* function can't support any more devices */
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice, too many devices in function\n"));
- return SDIO_STATUS_SUCCESS;
- }
-
- /* protect the driver list */
- if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->DeviceListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- /* walk device list */
- SDITERATE_OVER_LIST(&pBusContext->DeviceList, pList) {
- pDevice = CONTAINING_STRUCT(pList, SDDEVICE, SDList);
- if (pDevice->pFunction != NULL) {
- /* device already has a function driver handling it */
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice, device already has function\n"));
- continue;
- }
- /* see if this function handles this device */
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice, matching ID:%d %d class:%d\n",
- pDevice->pId[0].SDIO_ManufacturerID,
- pDevice->pId[0].SDIO_FunctionNo,
- pDevice->pId[0].SDIO_FunctionClass));
- if (IsPotentialIdMatch(pDevice->pId, pFunction->pIds)) {
- if (!FilterPnpInfo(pDevice)) {
- break;
- }
- /* we need to setup with the OS bus driver before the probe, so probe can
- do OS operations. */
- OS_InitializeDevice(pDevice, pFunction);
- if (!SDIO_SUCCESS(OS_AddDevice(pDevice, pFunction))) {
- break;
- }
- /* close enough match, ask the function driver if it supports us */
- if (pFunction->pProbe(pFunction, pDevice)) {
- /* she accepted the device, add to list */
- pDevice->pFunction = pFunction;
- SDListAdd(&pFunction->DeviceList, &pDevice->FuncListLink);
- pFunction->NumDevices++;
- break;
- } else {
- DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: %s did not claim the device \n",
- pFunction->pName));
- /* didn't take this device */
- OS_RemoveDevice(pDevice);
- }
- }
- }
- if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->DeviceListSem)))) {
- goto cleanup; /* wait interrupted */
- }
-
- return status;
-cleanup:
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: ProbeForDevice, error exit 0x%X\n", status));
- return status;
-}
-
-#if 0
-static void DumpPnpEntry(PSD_PNP_INFO pInfo)
-{
- DBG_PRINT(SDDBG_TRACE, ("Function PnpInfo Dump: \n"));
- DBG_PRINT(SDDBG_TRACE, (" Card Flags 0x%X \n", pInfo->CardFlags));
- DBG_PRINT(SDDBG_TRACE, (" SDIO MANF: 0x%X \n", pInfo->SDIO_ManufacturerID));
- DBG_PRINT(SDDBG_TRACE, (" SDIO MANFCODE: 0x%X \n", pInfo->SDIO_ManufacturerCode));
- DBG_PRINT(SDDBG_TRACE, (" SDIO FuncNo: %d \n", pInfo->SDIO_FunctionNo));
- DBG_PRINT(SDDBG_TRACE, (" SDIO FuncClass: %d \n", pInfo->SDIO_FunctionClass));
- DBG_PRINT(SDDBG_TRACE, (" SDMMC MANFID: 0x%X \n", pInfo->SDMMC_ManfacturerID));
- DBG_PRINT(SDDBG_TRACE, (" SDMMC OEMID: 0x%X \n", pInfo->SDMMC_OEMApplicationID));
-}
-#endif
-/*
- * IsPotentialIdMatch - test for potential device match
- *
-*/
-BOOL IsPotentialIdMatch(PSD_PNP_INFO pIdsDev, PSD_PNP_INFO pIdsFuncList) {
- PSD_PNP_INFO pTFn;
- BOOL match = FALSE;
-
- for (pTFn = pIdsFuncList;!IS_LAST_SDPNPINFO_ENTRY(pTFn);pTFn++) {
- //DumpPnpEntry(pTFn);
- /* check specific SDIO Card manufacturer ID, Code and Function number */
- if ((pIdsDev->SDIO_ManufacturerID != 0) &&
- (pTFn->SDIO_ManufacturerID != 0) &&
- (pIdsDev->SDIO_ManufacturerID == pTFn->SDIO_ManufacturerID) &&
- (pIdsDev->SDIO_ManufacturerCode == pTFn->SDIO_ManufacturerCode) &&
- ((pIdsDev->SDIO_FunctionNo == pTFn->SDIO_FunctionNo) ||
- (pTFn->SDIO_FunctionNo == 0)) ) {
- match = TRUE;
- break;
- }
- /* check generic function class */
- if ((pIdsDev->SDIO_FunctionClass != 0) &&
- (pTFn->SDIO_FunctionClass != 0) &&
- (pIdsDev->SDIO_FunctionClass == pTFn->SDIO_FunctionClass)) {
- match = TRUE;
- break;
- }
- /* check specific SDMMC MANFID and APPLICATION ID, NOTE SANDISK
- * uses a MANFID of zero! */
- if ((pTFn->SDMMC_OEMApplicationID != 0) &&
- (pIdsDev->SDMMC_ManfacturerID == pTFn->SDMMC_ManfacturerID) &&
- (pIdsDev->SDMMC_OEMApplicationID == pTFn->SDMMC_OEMApplicationID)) {
- match = TRUE;
- break;
- }
-
- /* check generic SD Card */
- if ((pIdsDev->CardFlags & CARD_SD) &&
- (pTFn->CardFlags & CARD_SD)){
- match = TRUE;
- break;
- }
-
- /* check generic MMC Card */
- if ((pIdsDev->CardFlags & CARD_MMC) &&
- (pTFn->CardFlags & CARD_MMC)){
- match = TRUE;
- break;
- }
-
- /* check raw Card */
- if ((pIdsDev->CardFlags & CARD_RAW) &&
- (pTFn->CardFlags & CARD_RAW)){
- match = TRUE;
- break;
- }
- }
-
- return match;
-}
-
-/*
- * NotifyDeviceRemove - tell function driver on this device that the device is being removed
- *
-*/
-SDIO_STATUS NotifyDeviceRemove(PSDDEVICE pDevice) {
- SDIO_STATUS status;
- SDREQUESTQUEUE cancelQueue;
- PSDREQUEST pReq;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- InitializeRequestQueue(&cancelQueue);
-
- if ((pDevice->pFunction != NULL) &&
- (pDevice->pFunction->pRemove != NULL)){
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: removing device 0x%X\n", (INT)pDevice));
- /* fail any outstanding requests for this device */
- /* acquire lock for request queue */
- status = _AcquireHcdLock(pDevice->pHcd);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
- /* mark the function to block any more requests comming down */
- pDevice->pFunction->Flags |= SDFUNCTION_FLAG_REMOVING;
- /* walk through HCD queue and remove this function's requests */
- SDITERATE_OVER_LIST_ALLOW_REMOVE(&pDevice->pHcd->RequestQueue.Queue, pReq, SDREQUEST, SDList) {
- if (pReq->pFunction == pDevice->pFunction) {
- /* cancel this request, as this device or function is being removed */
- /* note that these request are getting completed out of order */
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - NotifyDeviceRemove: canceling req 0x%X\n", (UINT)pReq));
- pReq->Status = SDIO_STATUS_CANCELED;
- /* remove it from the HCD queue */
- SDListRemove(&pReq->SDList);
- /* add it to the cancel queue */
- QueueRequest(&cancelQueue, pReq);
- }
- }SDITERATE_END;
-
- status = _ReleaseHcdLock(pDevice->pHcd);
-
- /* now empty the cancel queue if anything is in there */
- while (TRUE) {
- pReq = DequeueRequest(&cancelQueue);
- if (NULL == pReq) {
- break;
- }
- /* complete the request */
- DoRequestCompletion(pReq, pDevice->pHcd);
- }
- /* re-acquire the lock to deal with the current request */
- status = _AcquireHcdLock(pDevice->pHcd);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
- /* now deal with the current request */
- pReq = GET_CURRENT_REQUEST(pDevice->pHcd);
- if ((pReq !=NULL) && (pReq->pFunction == pDevice->pFunction) && (pReq->pFunction != NULL)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - NotifyDeviceRemove: Outstanding Req 0x%X on HCD: 0x%X.. waiting...\n",
- (UINT)pReq, (UINT)pDevice->pHcd));
- /* the outstanding request on this device is for the function being removed */
- pReq->Flags |= SDREQ_FLAGS_CANCELED;
- /* wait for this request to get completed normally */
- status = _ReleaseHcdLock(pDevice->pHcd);
- SignalWait(&pDevice->pFunction->CleanupReqSig);
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - NotifyDeviceRemove: Outstanding HCD Req 0x%X completed \n", (UINT)pReq));
- } else {
- /* release lock */
- status = _ReleaseHcdLock(pDevice->pHcd);
- }
-
- /* synchronize with ISR SYNC Handlers */
- status = SemaphorePendInterruptable(&pBusContext->DeviceListSem);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
- /* call this devices Remove function */
- pDevice->pFunction->pRemove(pDevice->pFunction,pDevice);
- pDevice->pFunction->NumDevices--;
- /* make sure the sync handler is NULLed out */
- pDevice->pIrqFunction = NULL;
- SemaphorePost(&pBusContext->DeviceListSem);
-
- OS_RemoveDevice(pDevice);
- /* detach this device from the function list it belongs to */
- SDListRemove(&pDevice->FuncListLink);
- pDevice->pFunction->Flags &= ~SDFUNCTION_FLAG_REMOVING;
- pDevice->pFunction = NULL;
- }
- return SDIO_STATUS_SUCCESS;
-}
-
-
-/*
- * RemoveHcdFunctions - remove all functions attached to an HCD
- *
-*/
-SDIO_STATUS RemoveHcdFunctions(PSDHCD pHcd) {
- SDIO_STATUS status;
- PSDLIST pList;
- PSDFUNCTION pFunction;
- PSDDEVICE pDevice;
- DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: RemoveHcdFunctions\n"));
-
- /* walk through the functions and remove the ones associated with this HCD */
- /* protect the driver list */
- if (!SDIO_SUCCESS((status = SemaphorePend(&pBusContext->FunctionListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- /* mark that card is being removed */
- pHcd->CardProperties.CardState |= CARD_STATE_REMOVED;
- SDITERATE_OVER_LIST(&pBusContext->FunctionList, pList) {
- pFunction = CONTAINING_STRUCT(pList, SDFUNCTION, SDList);
- DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: scanning function 0x%X, %s\n", (INT)pFunction,
- (pFunction == NULL)?"NULL":pFunction->pName));
-
- /* walk the devices on this function and look for a match */
- SDITERATE_OVER_LIST_ALLOW_REMOVE(&pFunction->DeviceList, pDevice, SDDEVICE,FuncListLink) {
- if (pDevice->pHcd == pHcd) {
- /* match, remove it */
- NotifyDeviceRemove(pDevice);
- }
- SDITERATE_END;
- SDITERATE_END;
- if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: RemoveHcdFunctions\n"));
- return SDIO_STATUS_SUCCESS;
-
-cleanup:
- DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: RemoveHcdFunctions, error exit 0x%X\n", status));
- return status;
-}
-
-/*
- * RemoveAllFunctions - remove all functions attached
- *
-*/
-SDIO_STATUS RemoveAllFunctions()
-{
- SDIO_STATUS status;
- PSDLIST pList;
- PSDHCD pHcd;
-
- /* walk through the HCDs */
- /* protect the driver list */
- if (!SDIO_SUCCESS((status = SemaphorePend(&pBusContext->HcdListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- SDITERATE_OVER_LIST(&pBusContext->HcdList, pList) {
- pHcd = CONTAINING_STRUCT(pList, SDHCD, SDList);
- /* remove the functions */
- RemoveHcdFunctions(pHcd);
- }
- if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->HcdListSem)))) {
- goto cleanup; /* wait interrupted */
- }
- return SDIO_STATUS_SUCCESS;
-cleanup:
- DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: RemoveAllFunctions, error exit 0x%X\n", status));
- return status;
-}
-
diff --git a/drivers/sdio/stack/lib/Makefile b/drivers/sdio/stack/lib/Makefile
deleted file mode 100644
index 44fa03897ea..00000000000
--- a/drivers/sdio/stack/lib/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_SDIO) += sdio_lib.o
-sdio_lib-objs := sdio_lib_c.o sdio_lib_os.o
diff --git a/drivers/sdio/stack/lib/_sdio_lib.h b/drivers/sdio/stack/lib/_sdio_lib.h
deleted file mode 100644
index 28762b0f6c2..00000000000
--- a/drivers/sdio/stack/lib/_sdio_lib.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-@file: _sdio_lib.h
-
-@abstract: SDIO Lib internal include
-
-#notes:
-
-@notice: Copyright (c), 2004-2006 Atheros Communications, Inc.
-
-
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Portions of this code were developed with information supplied from the
- * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
- *
- * The following conditions apply to the release of the SD simplified specification (�Simplified
- * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
- * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
- * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
- * Specification may require a license from the SD Card Association or other third parties.
- * Disclaimers:
- * The information contained in the Simplified Specification is presented only as a standard
- * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
- * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
- * any damages, any infringements of patents or other right of the SD Card Association or any third
- * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
- * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
- * be construed as an obligation by the SD Card Association to disclose or distribute any technical
- * information, know-how or other confidential information to any third party.
- *
- *
- * The initial developers of the original code are Seung Yi and Paul Lever
- *
- * sdio@atheros.com
- *
- *
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-#ifndef ___SDIO_LIB_H___
-#define ___SDIO_LIB_H___
-
-#endif /* ___SDIO_LIB_H___*/
diff --git a/drivers/sdio/stack/lib/sdio_lib_c.c b/drivers/sdio/stack/lib/sdio_lib_c.c
deleted file mode 100644
index 4bc5a83ecf6..00000000000
--- a/drivers/sdio/stack/lib/sdio_lib_c.c
+++ /dev/null
@@ -1,908 +0,0 @@
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-@file: sdio_lib_c.c
-
-@abstract: OS independent SDIO library functions
-@category abstract: Support_Reference Support Functions.
-
-@notes: Support functions for device I/O
-
-@notice: Copyright (c), 2004-2005 Atheros Communications, Inc.
-
-
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Portions of this code were developed with information supplied from the
- * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
- *
- * The following conditions apply to the release of the SD simplified specification (�Simplified
- * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
- * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
- * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
- * Specification may require a license from the SD Card Association or other third parties.
- * Disclaimers:
- * The information contained in the Simplified Specification is presented only as a standard
- * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
- * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
- * any damages, any infringements of patents or other right of the SD Card Association or any third
- * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
- * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
- * be construed as an obligation by the SD Card Association to disclose or distribute any technical
- * information, know-how or other confidential information to any third party.
- *
- *
- * The initial developers of the original code are Seung Yi and Paul Lever
- *
- * sdio@atheros.com
- *
- *
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-#define MODULE_NAME SDLIB_
-
-#include <linux/sdio/ctsystem.h>
-#include <linux/sdio/sdio_busdriver.h>
-#include <linux/sdio/_sdio_defs.h>
-#include <linux/sdio/sdio_lib.h>
-#include "_sdio_lib.h"
-
-#define _Cmd52WriteByteCommon(pDev, Address, pValue) \
- _SDLIB_IssueCMD52((pDev),0,(Address),(pValue),1,TRUE)
-#define _Cmd52ReadByteCommon(pDev, Address, pValue) \
- _SDLIB_IssueCMD52((pDev),0,(Address),pValue,1,FALSE)
-#define _Cmd52ReadMultipleCommon(pDev, Address, pBuf,length) \
- _SDLIB_IssueCMD52((pDev),0,(Address),(pBuf),(length),FALSE)
-
-/* inline version */
-static INLINE void _iSDLIB_SetupCMD52Request(UINT8 FuncNo,
- UINT32 Address,
- BOOL Write,
- UINT8 WriteData,
- PSDREQUEST pRequest) {
- if (Write) {
- SDIO_SET_CMD52_ARG(pRequest->Argument,CMD52_WRITE,
- FuncNo,
- CMD52_NORMAL_WRITE,Address,WriteData);
- } else {
- SDIO_SET_CMD52_ARG(pRequest->Argument,CMD52_READ,FuncNo,0,Address,0x00);
- }
-
- pRequest->Flags = SDREQ_FLAGS_RESP_SDIO_R5;
- pRequest->Command = CMD52;
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Setup cmd52 requests
-
- @function name: SDLIB_SetupCMD52Request
- @prototype: void SDLIB_SetupCMD52Request(UINT8 FuncNo,
- UINT32 Address,
- BOOL Write,
- UINT8 WriteData,
- PSDREQUEST pRequest)
- @category: PD_Reference
-
- @input: FunctionNo - function number.
- @input: Address - I/O address, 17-bit register address.
- @input: Write - TRUE if a write operation, FALSE for reads.
- @input: WriteData - write data, byte to write if write operation.
-
- @output: pRequest - request is updated with cmd52 parameters
-
- @return: none
-
- @notes: This function does not perform any I/O. For register reads, the completion
- routine can use the SD_R5_GET_READ_DATA() macro to extract the register value.
- The routine should also extract the response flags using the SD_R5_GET_RESP_FLAGS()
- macro and check the flags with the SD_R5_ERRORS mask.
-
- @example: Getting the register value from the completion routine:
- flags = SD_R5_GET_RESP_FLAGS(pRequest->Response);
- if (flags & SD_R5_ERRORS) {
- ... errors
- } else {
- registerValue = SD_R5_GET_READ_DATA(pRequest->Response);
- }
-
- @see also: SDLIB_IssueCMD52
- @see also: SDDEVICE_CALL_REQUEST_FUNC
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void _SDLIB_SetupCMD52Request(UINT8 FuncNo,
- UINT32 Address,
- BOOL Write,
- UINT8 WriteData,
- PSDREQUEST pRequest)
-{
- _iSDLIB_SetupCMD52Request(FuncNo,Address,Write,WriteData,pRequest);
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Issue a CMD52 to read or write a register
-
- @function name: SDLIB_IssueCMD52
- @prototype: SDIO_STATUS SDLIB_IssueCMD52(PSDDEVICE pDevice,
- UINT8 FuncNo,
- UINT32 Address,
- PUINT8 pData,
- INT ByteCount,
- BOOL Write)
- @category: PD_Reference
- @input: pDevice - the device that is the target of the command.
- @input: FunctionNo - function number of the target.
- @input: Address - 17-bit register address.
- @input: ByteCount - number of bytes to read or write,
- @input: Write - TRUE if a write operation, FALSE for reads.
- @input: pData - data buffer for writes.
-
- @output: pData - data buffer for writes.
-
- @return: SDIO Status
-
- @notes: This function will allocate a request and issue multiple byte reads or writes
- to satisfy the ByteCount requested. This function is fully synchronous and will block
- the caller.
-
- @see also: SDLIB_SetupCMD52Request
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDLIB_IssueCMD52(PSDDEVICE pDevice,
- UINT8 FuncNo,
- UINT32 Address,
- PUINT8 pData,
- INT ByteCount,
- BOOL Write)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- PSDREQUEST pReq = NULL;
-
- pReq = SDDeviceAllocRequest(pDevice);
-
- if (NULL == pReq) {
- return SDIO_STATUS_NO_RESOURCES;
- }
-
- while (ByteCount) {
- _iSDLIB_SetupCMD52Request(FuncNo,Address,Write,*pData,pReq);
- status = SDDEVICE_CALL_REQUEST_FUNC(pDevice,pReq);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
-
- status = ConvertCMD52ResponseToSDIOStatus(SD_R5_GET_RESP_FLAGS(pReq->Response));
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Library: CMD52 resp error: 0x%X \n",
- SD_R5_GET_RESP_FLAGS(pReq->Response)));
- break;
- }
- if (!Write) {
- /* store the byte */
- *pData = SD_R5_GET_READ_DATA(pReq->Response);
- }
- pData++;
- Address++;
- ByteCount--;
- }
-
- SDDeviceFreeRequest(pDevice,pReq);
- return status;
-}
-
-
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Find a device's tuple.
-
- @function name: SDLIB_FindTuple
- @prototype: SDIO_STATUS SDLIB_FindTuple(PSDDEVICE pDevice,
- UINT8 Tuple,
- UINT32 *pTupleScanAddress,
- PUINT8 pBuffer,
- UINT8 *pLength)
-
- @category: PD_Reference
- @input: pDevice - the device that is the target of the command.
- @input: Tuple - 8-bit ID of tuple to find
- @input: pTupleScanAddress - On entry pTupleScanAddress is the adddress to start scanning
- @input: pLength - length of pBuffer
-
- @output: pBuffer - storage for tuple
- @output: pTupleScanAddress - address of the next tuple
- @output: pLength - length of tuple read
-
- @return: status
-
- @notes: It is possible to have the same tuple ID multiple times with different lengths. This function
- blocks and is fully synchronous.
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDLIB_FindTuple(PSDDEVICE pDevice,
- UINT8 Tuple,
- UINT32 *pTupleScanAddress,
- PUINT8 pBuffer,
- UINT8 *pLength)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- UINT32 scanStart = *pTupleScanAddress;
- UINT8 tupleCode;
- UINT8 tupleLink;
-
- /* sanity check */
- if (scanStart < SDIO_CIS_AREA_BEGIN) {
- return SDIO_STATUS_CIS_OUT_OF_RANGE;
- }
-
- while (TRUE) {
- /* check for end */
- if (scanStart > SDIO_CIS_AREA_END) {
- status = SDIO_STATUS_TUPLE_NOT_FOUND;
- break;
- }
- /* get the code */
- status = _Cmd52ReadByteCommon(pDevice, scanStart, &tupleCode);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- if (CISTPL_END == tupleCode) {
- /* found the end */
- status = SDIO_STATUS_TUPLE_NOT_FOUND;
- break;
- }
- /* bump past tuple code */
- scanStart++;
- /* get the tuple link value */
- status = _Cmd52ReadByteCommon(pDevice, scanStart, &tupleLink);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- /* bump past tuple link*/
- scanStart++;
- /* check tuple we just found */
- if (tupleCode == Tuple) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Library: Tuple:0x%2.2X Found at Address:0x%X, TupleLink:0x%X \n",
- Tuple, (scanStart - 2), tupleLink));
- if (tupleLink != CISTPL_LINK_END) {
- /* return the next scan address to the caller */
- *pTupleScanAddress = scanStart + tupleLink;
- } else {
- /* the tuple link is an end marker */
- *pTupleScanAddress = 0xFFFFFFFF;
- }
- /* go get the tuple */
- status = _Cmd52ReadMultipleCommon(pDevice, scanStart,pBuffer,min(*pLength,tupleLink));
- if (SDIO_SUCCESS(status)) {
- /* set the actual return length */
- *pLength = min(*pLength,tupleLink);
- }
- /* break out of loop */
- break;
- }
- /*increment past this entire tuple */
- scanStart += tupleLink;
- }
-
- return status;
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Issue an SDIO configuration command.
-
- @function name: SDLIB_IssueConfig
- @prototype: SDIO_STATUS _SDLIB_IssueConfig(PSDDEVICE pDevice,
- SDCONFIG_COMMAND Command,
- PVOID pData,
- INT Length)
-
- @category: PD_Reference
- @input: pDevice - the device that is the target of the command.
- @input: Command - command to send, see example.
- @input: pData - command's data
- @input: Length length of pData
-
- @output: pData - updated on commands that return data.
-
- @return: SDIO Status
-
- @example: Command and data pairs:
- Type Data
- SDCONFIG_GET_WP SDCONFIG_WP_VALUE
- SDCONFIG_SEND_INIT_CLOCKS none
- SDCONFIG_SDIO_INT_CTRL SDCONFIG_SDIO_INT_CTRL_DATA
- SDCONFIG_SDIO_REARM_INT none
- SDCONFIG_BUS_MODE_CTRL SDCONFIG_BUS_MODE_DATA
- SDCONFIG_POWER_CTRL SDCONFIG_POWER_CTRL_DATA
-
- @notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDLIB_IssueConfig(PSDDEVICE pDevice,
- SDCONFIG_COMMAND Command,
- PVOID pData,
- INT Length)
-{
- SDCONFIG configHdr;
- SET_SDCONFIG_CMD_INFO(&configHdr,Command,pData,Length);
- return SDDEVICE_CALL_CONFIG_FUNC(pDevice,&configHdr);
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Set function block size
-
- @function name: SDLIB_SetFunctionBlockSize
- @prototype: SDIO_STATUS SDLIB_SetFunctionBlockSize(PSDDEVICE pDevice,
- UINT16 BlockSize)
-
- @category: PD_Reference
- @input: pDevice - the device that is the target of the command.
- @input: BlockSize - block size to set in function
-
- @output: none
-
- @return: SDIO Status
-
- @notes: Issues CMD52 to set the block size. This function is fully synchronous and may
- block.
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDLIB_SetFunctionBlockSize(PSDDEVICE pDevice,
- UINT16 BlockSize)
-{
- UINT8 data[2];
-
- /* endian safe */
- data[0] = (UINT8)BlockSize;
- data[1] = (UINT8)(BlockSize >> 8);
- /* write the function blk size control register */
- return _SDLIB_IssueCMD52(pDevice,
- 0, /* function 0 register space */
- FBR_FUNC_BLK_SIZE_LOW_OFFSET(CalculateFBROffset(
- SDDEVICE_GET_SDIO_FUNCNO(pDevice))),
- data,
- 2,
- TRUE);
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Print a buffer to the debug output
-
- @function name: SDLIB_PrintBuffer
- @prototype: void SDLIB_PrintBuffer(PUCHAR pBuffer, INT Length, PTEXT pDescription)
- @category: Support_Reference
-
- @input: pBuffer - Hex buffer to be printed.
- @input: Length - length of pBuffer.
- @input: pDescription - String title to be printed above the dump.
-
- @output: none
-
- @return: none
-
- @notes: Prints the buffer by converting to ASCII and using REL_PRINT() with 16
- bytes per line.
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void _SDLIB_PrintBuffer(PUCHAR pBuffer, INT Length, PTEXT pDescription)
-{
- TEXT line[49];
- TEXT address[5];
- TEXT ascii[17];
- TEXT temp[5];
- INT i;
- UCHAR num;
- USHORT offset = 0;
-
- REL_PRINT(0,
- ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
- if (pDescription != NULL) {
- REL_PRINT(0, ("Description: %s \n\n",pDescription));
- } else {
- REL_PRINT(0, ("Description: NONE \n\n"));
- }
- REL_PRINT(0,
- ("Offset Data ASCII \n"));
- REL_PRINT(0,
- ("--------------------------------------------------------------------------\n"));
-
- while (Length) {
- line[0] = (TEXT)0;
- ascii[0] = (TEXT)0;
- address[0] = (TEXT)0;
- sprintf(address,"%4.4X",offset);
- for (i = 0; i < 16; i++) {
- if (Length != 0) {
- num = *pBuffer;
- sprintf(temp,"%2.2X ",num);
- strcat(line,temp);
- if ((num >= 0x20) && (num <= 0x7E)) {
- sprintf(temp,"%c",*pBuffer);
- } else {
- sprintf(temp,"%c",0x2e);
- }
- strcat(ascii,temp);
- pBuffer++;
- Length--;
- } else {
- /* pad partial line with spaces */
- strcat(line," ");
- strcat(ascii," ");
- }
- }
- REL_PRINT(0,("%s %s %s\n", address, line, ascii));
- offset += 16;
- }
- REL_PRINT(0,
- ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
-
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Get default operational current
-
- @function name: SDLIB_GetDefaultOpCurrent
- @prototype: SDIO_STATUS SDLIB_GetDefaultOpCurrent(PSDDEVICE pDevice, SD_SLOT_CURRENT *pOpCurrent)
- @category: PD_Reference
-
- @input: pDevice - the device that is the target of the command.
-
- @output: pOpCurrent - operational current in mA.
-
- @return: SDIO_STATUS
-
- @notes: This routine reads the function's CISTPL_FUNCE tuple for the default operational
- current. For SDIO 1.0 devices this value is read from the 8-bit TPLFE_OP_MAX_PWR
- field. For SDIO 1.1 devices, the HP MAX power field is used only if the device is
- operating in HIPWR mode. Otherwise the 8-bit TPLFE_OP_MAX_PWR field is used.
- Some systems may restrict high power/current mode and force cards to operate in a
- legacy (< 200mA) mode. This function is fully synchronous and will block the caller.
-
- @example: Getting the default operational current for this function:
- // get default operational current
- status = SDLIB_GetDefaultOpCurrent(pDevice, &slotCurrent);
- if (!SDIO_SUCCESS(status)) {
- .. failed
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDLIB_GetDefaultOpCurrent(PSDDEVICE pDevice, SD_SLOT_CURRENT *pOpCurrent)
-{
- UINT32 nextTpl;
- UINT8 tplLength;
- struct SDIO_FUNC_EXT_FUNCTION_TPL_1_1 funcTuple;
- SDIO_STATUS status;
-
- /* get the FUNCE tuple */
- nextTpl = SDDEVICE_GET_SDIO_FUNC_CISPTR(pDevice);
- tplLength = sizeof(funcTuple);
- /* go get the function Extension tuple */
- status = _SDLIB_FindTuple(pDevice,
- CISTPL_FUNCE,
- &nextTpl,
- (PUINT8)&funcTuple,
- &tplLength);
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDLIB_GetDefaultOpCurrent: Failed to get FuncE Tuple: %d \n", status));
- return status;
- }
- /* use the operational power (8-bit) value of current in mA as default*/
- *pOpCurrent = funcTuple.CommonInfo.OpMaxPwr;
- if ((tplLength >= sizeof(funcTuple)) && (SDDEVICE_IS_SDIO_REV_GTEQ_1_10(pDevice))) {
- /* we have a 1.1 tuple */
- /* check for HIPWR mode */
- if (SDDEVICE_GET_CARD_FLAGS(pDevice) & CARD_HIPWR) {
- /* use the maximum operational power (16 bit ) from the tuple */
- *pOpCurrent = CT_LE16_TO_CPU_ENDIAN(funcTuple.HiPwrMaxPwr);
- }
- }
- return SDIO_STATUS_SUCCESS;
-}
-
-
-static INLINE void FreeMessageBlock(PSDMESSAGE_QUEUE pQueue, PSDMESSAGE_BLOCK pMsg) {
- SDListInsertHead(&pQueue->FreeMessageList, &pMsg->SDList);
-}
-static INLINE void QueueMessageBlock(PSDMESSAGE_QUEUE pQueue, PSDMESSAGE_BLOCK pMsg) {
- SDListInsertTail(&pQueue->MessageList, &pMsg->SDList);
-}
-static INLINE void QueueMessageToHead(PSDMESSAGE_QUEUE pQueue, PSDMESSAGE_BLOCK pMsg) {
- SDListInsertHead(&pQueue->MessageList, &pMsg->SDList);
-}
-
-static INLINE PSDMESSAGE_BLOCK GetFreeMessageBlock(PSDMESSAGE_QUEUE pQueue) {
- PSDLIST pItem = SDListRemoveItemFromHead(&pQueue->FreeMessageList);
- if (pItem != NULL) {
- return CONTAINING_STRUCT(pItem, SDMESSAGE_BLOCK , SDList);
- }
- return NULL;
-}
-static INLINE PSDMESSAGE_BLOCK GetQueuedMessage(PSDMESSAGE_QUEUE pQueue) {
- PSDLIST pItem = SDListRemoveItemFromHead(&pQueue->MessageList);
- if (pItem != NULL) {
- return CONTAINING_STRUCT(pItem, SDMESSAGE_BLOCK , SDList);
- }
- return NULL;
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Create a message queue
-
- @function name: SDLIB_CreateMessageQueue
- @prototype: PSDMESSAGE_QUEUE SDLIB_CreateMessageQueue(INT MaxMessages, INT MaxMessageLength)
- @category: Support_Reference
-
- @input: MaxMessages - Maximum number of messages this queue supports
- @input: MaxMessageLength - Maximum size of each message
-
- @return: Message queue object, NULL on failure
-
- @notes: This function creates a simple first-in-first-out message queue. The caller must determine
- the maximum number of messages the queue supports and the size of each message. This
- function will pre-allocate memory for each message. A producer of data posts a message
- using SDLIB_PostMessage with a user defined data structure. A consumer of this data
- can retrieve the message (in FIFO order) using SDLIB_GetMessage. A message queue does not
- provide a signaling mechanism for notifying a consumer of data. Notifying a consumer is
- user defined.
-
- @see also: SDLIB_DeleteMessageQueue, SDLIB_GetMessage, SDLIB_PostMessage.
-
- @example: Creating a message queue:
- typedef struct _MyMessage {
- UINT8 Code;
- PVOID pDataBuffer;
- } MyMessage;
- // create message queue, 16 messages max.
- pMsgQueue = SDLIB_CreateMessageQueue(16,sizeof(MyMessage));
- if (NULL == pMsgQueue) {
- .. failed
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-PSDMESSAGE_QUEUE _CreateMessageQueue(INT MaxMessages, INT MaxMessageLength)
-{
- PSDMESSAGE_QUEUE pQueue = NULL;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- INT ii;
- PSDMESSAGE_BLOCK pMsg;
-
- do {
- pQueue = (PSDMESSAGE_QUEUE)KernelAlloc(sizeof(SDMESSAGE_QUEUE));
-
- if (NULL == pQueue) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
- SDLIST_INIT(&pQueue->MessageList);
- SDLIST_INIT(&pQueue->FreeMessageList);
- pQueue->MaxMessageLength = MaxMessageLength;
- status = CriticalSectionInit(&pQueue->MessageCritSection);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- /* allocate message blocks */
- for (ii = 0; ii < MaxMessages; ii++) {
- pMsg = (PSDMESSAGE_BLOCK)KernelAlloc(sizeof(SDMESSAGE_BLOCK) + MaxMessageLength -1);
- if (NULL == pMsg) {
- break;
- }
- FreeMessageBlock(pQueue, pMsg);
- }
-
- if (0 == ii) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
-
- } while (FALSE);
-
- if (!SDIO_SUCCESS(status)) {
- if (pQueue != NULL) {
- _DeleteMessageQueue(pQueue);
- pQueue = NULL;
- }
- }
- return pQueue;
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Delete a message queue
-
- @function name: SDLIB_DeleteMessageQueue
- @prototype: void SDLIB_DeleteMessageQueue(PSDMESSAGE_QUEUE pQueue)
- @category: Support_Reference
-
- @input: pQueue - message queue to delete
-
- @notes: This function flushes the message queue and frees all memory allocated for
- messages.
-
- @see also: SDLIB_CreateMessageQueue
-
- @example: Deleting a message queue:
- if (pMsgQueue != NULL) {
- SDLIB_DeleteMessageQueue(pMsgQueue);
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void _DeleteMessageQueue(PSDMESSAGE_QUEUE pQueue)
-{
- PSDMESSAGE_BLOCK pMsg;
- SDIO_STATUS status;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- status = CriticalSectionAcquireSyncIrq(&pQueue->MessageCritSection);
-
- /* cleanup free list */
- while (1) {
- pMsg = GetFreeMessageBlock(pQueue);
- if (pMsg != NULL) {
- KernelFree(pMsg);
- } else {
- break;
- }
- }
- /* cleanup any in the queue */
- while (1) {
- pMsg = GetQueuedMessage(pQueue);
- if (pMsg != NULL) {
- KernelFree(pMsg);
- } else {
- break;
- }
- }
-
- status = CriticalSectionReleaseSyncIrq(&pQueue->MessageCritSection);
- CriticalSectionDelete(&pQueue->MessageCritSection);
- KernelFree(pQueue);
-
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Post a message queue
-
- @function name: SDLIB_PostMessage
- @prototype: SDIO_STATUS SDLIB_PostMessage(PSDMESSAGE_QUEUE pQueue, PVOID pMessage, INT MessageLength)
- @category: Support_Reference
-
- @input: pQueue - message queue to post to
- @input: pMessage - message to post
- @input: MessageLength - length of message (for validation)
-
- @return: SDIO_STATUS
-
- @notes: The message queue uses an internal list of user defined message structures. When
- posting a message the message is copied into an allocated structure and queued. The memory
- pointed to by pMessage does not need to be allocated and can reside on the stack.
- The length of the message to post can be smaller that the maximum message size. This allows
- for variable length messages up to the maximum message size. This
- function returns SDIO_STATUS_NO_RESOURCES, if the message queue is full. This
- function returns SDIO_STATUS_BUFFER_TOO_SMALL, if the message size exceeds the maximum
- size of a message. Posting and getting messsages from a message queue is safe in any
- driver context.
-
- @see also: SDLIB_CreateMessageQueue , SDLIB_GetMessage
-
- @example: Posting a message
- MyMessage message;
- // set up message
- message.code = MESSAGE_DATA_READY;
- message.pData = pInstance->pDataBuffers[currentIndex];
- // post message
- status = SDLIB_PostMessage(pInstance->pReadQueue,&message,sizeof(message));
- if (!SDIO_SUCCESS(status)) {
- // failed
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _PostMessage(PSDMESSAGE_QUEUE pQueue, PVOID pMessage, INT MessageLength)
-{
- SDIO_STATUS status2;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDMESSAGE_BLOCK pMsg;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- if (MessageLength > pQueue->MaxMessageLength) {
- return SDIO_STATUS_BUFFER_TOO_SMALL;
- }
-
- status = CriticalSectionAcquireSyncIrq(&pQueue->MessageCritSection);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
-
- do {
- /* get a message block */
- pMsg = GetFreeMessageBlock(pQueue);
- if (NULL == pMsg) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
- /* copy the message */
- memcpy(pMsg->MessageStart,pMessage,MessageLength);
- /* set the length of the message */
- pMsg->MessageLength = MessageLength;
- /* queue the message to the list */
- QueueMessageBlock(pQueue,pMsg);
- } while (FALSE);
-
- status2 = CriticalSectionReleaseSyncIrq(&pQueue->MessageCritSection);
- return status;
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Get a message from a message queue
-
- @function name: SDLIB_GetMessage
- @prototype: SDIO_STATUS SDLIB_GetMessage(PSDMESSAGE_QUEUE pQueue, PVOID pData, INT *pBufferLength)
- @category: Support_Reference
-
- @input: pQueue - message queue to retreive a message from
- @input: pBufferLength - on entry, the length of the data buffer
- @output: pData - buffer to hold the message
- @output: pBufferLength - on return, contains the number of bytes copied
-
- @return: SDIO_STATUS
-
- @notes: The message queue uses an internal list of user defined message structures. The message is
- dequeued (FIFO order) and copied to the callers buffer. The internal allocation for the message
- is returned back to the message queue. This function returns SDIO_STATUS_NO_MORE_MESSAGES
- if the message queue is empty. If the length of the buffer is smaller than the length of
- the message at the head of the queue,this function returns SDIO_STATUS_BUFFER_TOO_SMALL and
- returns the required length in pBufferLength.
-
- @see also: SDLIB_CreateMessageQueue , SDLIB_PostMessage
-
- @example: Getting a message
- MyMessage message;
- INT length;
- // set length
- length = sizeof(message);
- // post message
- status = SDLIB_GetMessage(pInstance->pReadQueue,&message,&length);
- if (!SDIO_SUCCESS(status)) {
- // failed
- }
-
- @example: Checking queue for a message and getting the size of the message
- INT length;
- // use zero length to get the size of the message
- length = 0;
- status = SDLIB_GetMessage(pInstance->pReadQueue,NULL,&length);
- if (status == SDIO_STATUS_NO_MORE_MESSAGES) {
- // no messages in queue
- } else if (status == SDIO_STATUS_BUFFER_TOO_SMALL) {
- // message exists in queue and length of message is returned
- messageSizeInQueue = length;
- } else {
- // some other failure
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _GetMessage(PSDMESSAGE_QUEUE pQueue, PVOID pData, INT *pBufferLength)
-{
- SDIO_STATUS status2;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDMESSAGE_BLOCK pMsg;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- status = CriticalSectionAcquireSyncIrq(&pQueue->MessageCritSection);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
-
- do {
- pMsg = GetQueuedMessage(pQueue);
- if (NULL == pMsg) {
- status = SDIO_STATUS_NO_MORE_MESSAGES;
- break;
- }
- if (*pBufferLength < pMsg->MessageLength) {
- /* caller buffer is too small */
- *pBufferLength = pMsg->MessageLength;
- /* stick it back to the front */
- QueueMessageToHead(pQueue, pMsg);
- status = SDIO_STATUS_BUFFER_TOO_SMALL;
- break;
- }
- /* copy the message to the callers buffer */
- memcpy(pData,pMsg->MessageStart,pMsg->MessageLength);
- /* return actual length */
- *pBufferLength = pMsg->MessageLength;
- /* return this message block back to the free list */
- FreeMessageBlock(pQueue, pMsg);
-
- } while (FALSE);
-
- status2 = CriticalSectionReleaseSyncIrq(&pQueue->MessageCritSection);
-
- return status;
-}
-
-/* the following documents the OS helper APIs */
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Create an OS-specific helper task/thread
-
- @function name: SDLIB_OSCreateHelper
- @prototype: SDIO_STATUS SDLIB_OSCreateHelper(POSKERNEL_HELPER pHelper,
- PHELPER_FUNCTION pFunction,
- PVOID pContext)
- @category: Support_Reference
-
- @input: pHelper - caller allocated helper object
- @input: pFunction - helper function
- @input: pContext - helper context
-
- @return: SDIO_STATUS
-
- @notes: This function creates a helper task/thread that runs in a new execution context. The newly
- created task/thread invokes the helper function. The thread/task exits when the helper
- function returns. The helper function has the prototype of:
- THREAD_RETURN HelperFunction(POSKERNEL_HELPER pHelper)
- The helper function usually implements a while loop and suspends execution using
- SD_WAIT_FOR_WAKEUP(). On exit the helper function can return an OS-specific THREAD_RETURN
- code (usually zero). The helper function executes in a fully schedule-able context and
- can block on semaphores and sleep.
-
- @see also: SDLIB_OSDeleteHelper , SD_WAIT_FOR_WAKEUP
-
- @example: A thread helper function:
- THREAD_RETURN HelperFunction(POSKERNEL_HELPER pHelper)
- {
- SDIO_STATUS status;
- PMYCONTEXT pContext = (PMYCONTEXT)SD_GET_OS_HELPER_CONTEXT(pHelper);
- // wait for wake up
- while(1) {
- status = SD_WAIT_FOR_WAKEUP(pHelper);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- if (SD_IS_HELPER_SHUTTING_DOWN(pHelper)) {
- //... shutting down
- break;
- }
- // handle wakeup...
- }
- return 0;
- }
-
- @example: Creating a helper:
- status = SDLIB_OSCreateHelper(&pInstance->OSHelper,HelperFunction,pInstance);
- if (!SDIO_SUCCESS(status)) {
- // failed
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Delete an OS helper task/thread
-
- @function name: SDLIB_OSDeleteHelper
- @prototype: void SDLIB_OSDeleteHelper(POSKERNEL_HELPER pHelper)
- @category: Support_Reference
-
- @input: pHelper - caller allocated helper object
-
- @notes: This function wakes the helper and waits(blocks) until the helper exits. The caller can
- only pass an OS helper structure that was initialized sucessfully by
- SDLIB_OSCreateHelper. The caller must be in a schedulable context.
-
- @see also: SDLIB_OSCreateHelper
-
- @example: Deleting a helper:
- if (pInstance->HelperCreated) {
- // clean up the helper if we successfully created it
- SDLIB_OSDeleteHelper(&pInstance->OSHelper);
- }
-
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-
diff --git a/drivers/sdio/stack/lib/sdio_lib_os.c b/drivers/sdio/stack/lib/sdio_lib_os.c
deleted file mode 100644
index 55363d04ffd..00000000000
--- a/drivers/sdio/stack/lib/sdio_lib_os.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-@file: sdio_function_os.c
-
-@abstract: Linux implementation module for SDIO library
-
-#notes: includes module load and unload functions
-
-@notice: Copyright (c), 2004 Atheros Communications, Inc.
-
-
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Portions of this code were developed with information supplied from the
- * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
- *
- * The following conditions apply to the release of the SD simplified specification (�Simplified
- * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
- * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
- * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
- * Specification may require a license from the SD Card Association or other third parties.
- * Disclaimers:
- * The information contained in the Simplified Specification is presented only as a standard
- * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
- * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
- * any damages, any infringements of patents or other right of the SD Card Association or any third
- * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
- * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
- * be construed as an obligation by the SD Card Association to disclose or distribute any technical
- * information, know-how or other confidential information to any third party.
- *
- *
- * The initial developers of the original code are Seung Yi and Paul Lever
- *
- * sdio@atheros.com
- *
- *
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/* debug level for this module*/
-#define DBG_DECLARE 4;
-#include <linux/sdio/ctsystem.h>
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kthread.h>
-
-#include <linux/sdio/sdio_busdriver.h>
-#include <linux/sdio/sdio_lib.h>
-#include "_sdio_lib.h"
-
-#define DESCRIPTION "SDIO Kernel Library"
-#define AUTHOR "Atheros Communications, Inc."
-
-/* proxies */
-SDIO_STATUS SDLIB_IssueCMD52(PSDDEVICE pDevice,
- UINT8 FuncNo,
- UINT32 Address,
- PUINT8 pData,
- INT ByteCount,
- BOOL Write)
-{
- return _SDLIB_IssueCMD52(pDevice,FuncNo,Address,pData,ByteCount,Write);
-}
-
-SDIO_STATUS SDLIB_FindTuple(PSDDEVICE pDevice,
- UINT8 Tuple,
- UINT32 *pTupleScanAddress,
- PUINT8 pBuffer,
- UINT8 *pLength)
-{
- return _SDLIB_FindTuple(pDevice,Tuple,pTupleScanAddress,pBuffer,pLength);
-}
-
-SDIO_STATUS SDLIB_IssueConfig(PSDDEVICE pDevice,
- SDCONFIG_COMMAND Command,
- PVOID pData,
- INT Length)
-{
- return _SDLIB_IssueConfig(pDevice,Command,pData,Length);
-}
-
-void SDLIB_PrintBuffer(PUCHAR pBuffer,INT Length,PTEXT pDescription)
-{
- _SDLIB_PrintBuffer(pBuffer,Length,pDescription);
-}
-
-SDIO_STATUS SDLIB_SetFunctionBlockSize(PSDDEVICE pDevice,
- UINT16 BlockSize)
-{
- return _SDLIB_SetFunctionBlockSize(pDevice,BlockSize);
-}
-
-void SDLIB_SetupCMD52Request(UINT8 FuncNo,
- UINT32 Address,
- BOOL Write,
- UINT8 WriteData,
- PSDREQUEST pRequest)
-{
- _SDLIB_SetupCMD52Request(FuncNo,Address,Write,WriteData,pRequest);
-}
-
-SDIO_STATUS SDLIB_GetDefaultOpCurrent(PSDDEVICE pDevice, SD_SLOT_CURRENT *pOpCurrent)
-{
- return _SDLIB_GetDefaultOpCurrent(pDevice,pOpCurrent);
-}
-
-/* helper function launcher */
-INT HelperLaunch(PVOID pContext)
-{
- INT exit;
- /* call function */
- exit = ((POSKERNEL_HELPER)pContext)->pHelperFunc((POSKERNEL_HELPER)pContext);
- complete_and_exit(&((POSKERNEL_HELPER)pContext)->Completion, exit);
- return exit;
-}
-
-/*
- * OSCreateHelper - create a worker kernel thread
-*/
-SDIO_STATUS SDLIB_OSCreateHelper(POSKERNEL_HELPER pHelper,
- PHELPER_FUNCTION pFunction,
- PVOID pContext)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- memset(pHelper,0,sizeof(OSKERNEL_HELPER));
-
- do {
- pHelper->pContext = pContext;
- pHelper->pHelperFunc = pFunction;
- status = SignalInitialize(&pHelper->WakeSignal);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- init_completion(&pHelper->Completion);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- pHelper->pTask = kthread_create(HelperLaunch,
- (PVOID)pHelper,
- "SDIO Helper");
- if (NULL == pHelper->pTask) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
- wake_up_process(pHelper->pTask);
-#else
- /* 2.4 */
- pHelper->pTask = kernel_thread(HelperLaunch,
- (PVOID)pHelper,
- (CLONE_FS | CLONE_FILES | SIGCHLD));
- if (pHelper->pTask < 0) {
- DBG_PRINT(SDDBG_TRACE,
- ("SDIO BusDriver - OSCreateHelper, failed to create thread\n"));
- }
-#endif
-
- } while (FALSE);
-
- if (!SDIO_SUCCESS(status)) {
- SDLIB_OSDeleteHelper(pHelper);
- }
- return status;
-}
-
-/*
- * OSDeleteHelper - delete thread created with OSCreateHelper
-*/
-void SDLIB_OSDeleteHelper(POSKERNEL_HELPER pHelper)
-{
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- if (pHelper->pTask != NULL) {
-#else
- /* 2.4 */
- if (pHelper->pTask >= 0) {
-#endif
- pHelper->ShutDown = TRUE;
- SignalSet(&pHelper->WakeSignal);
- /* wait for thread to exit */
- wait_for_completion(&pHelper->Completion);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- pHelper->pTask = NULL;
-#else
- /* 2.4 */
- pHelper->pTask = 0;
-#endif
- }
-
- SignalDelete(&pHelper->WakeSignal);
-}
-
-/*
- * module init
-*/
-static int __init sdio_lib_init(void) {
- REL_PRINT(SDDBG_TRACE, ("SDIO Library load\n"));
- return 0;
-}
-
-/*
- * module cleanup
-*/
-static void __exit sdio_lib_cleanup(void) {
- REL_PRINT(SDDBG_TRACE, ("SDIO Library unload\n"));
-}
-
-PSDMESSAGE_QUEUE SDLIB_CreateMessageQueue(INT MaxMessages, INT MaxMessageLength)
-{
- return _CreateMessageQueue(MaxMessages,MaxMessageLength);
-
-}
-void SDLIB_DeleteMessageQueue(PSDMESSAGE_QUEUE pQueue)
-{
- _DeleteMessageQueue(pQueue);
-}
-
-SDIO_STATUS SDLIB_PostMessage(PSDMESSAGE_QUEUE pQueue, PVOID pMessage, INT MessageLength)
-{
- return _PostMessage(pQueue,pMessage,MessageLength);
-}
-
-SDIO_STATUS SDLIB_GetMessage(PSDMESSAGE_QUEUE pQueue, PVOID pData, INT *pBufferLength)
-{
- return _GetMessage(pQueue,pData,pBufferLength);
-}
-
-MODULE_LICENSE("GPL and additional rights");
-MODULE_DESCRIPTION(DESCRIPTION);
-MODULE_AUTHOR(AUTHOR);
-module_init(sdio_lib_init);
-module_exit(sdio_lib_cleanup);
-EXPORT_SYMBOL(SDLIB_IssueCMD52);
-EXPORT_SYMBOL(SDLIB_FindTuple);
-EXPORT_SYMBOL(SDLIB_IssueConfig);
-EXPORT_SYMBOL(SDLIB_PrintBuffer);
-EXPORT_SYMBOL(SDLIB_SetFunctionBlockSize);
-EXPORT_SYMBOL(SDLIB_SetupCMD52Request);
-EXPORT_SYMBOL(SDLIB_GetDefaultOpCurrent);
-EXPORT_SYMBOL(SDLIB_OSCreateHelper);
-EXPORT_SYMBOL(SDLIB_OSDeleteHelper);
-EXPORT_SYMBOL(SDLIB_CreateMessageQueue);
-EXPORT_SYMBOL(SDLIB_DeleteMessageQueue);
-EXPORT_SYMBOL(SDLIB_PostMessage);
-EXPORT_SYMBOL(SDLIB_GetMessage);
diff --git a/drivers/sdio/stack/platform/Makefile b/drivers/sdio/stack/platform/Makefile
deleted file mode 100644
index 14b36126035..00000000000
--- a/drivers/sdio/stack/platform/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_SDIO) += sdio_platform.o
-sdio_platform-objs := sdioplatformdriver.o \ No newline at end of file
diff --git a/drivers/sdio/stack/platform/sdioplatformdriver.c b/drivers/sdio/stack/platform/sdioplatformdriver.c
deleted file mode 100644
index d5520fc2908..00000000000
--- a/drivers/sdio/stack/platform/sdioplatformdriver.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-@file: sdioplatformdriver.c
-
-@abstract: Linux implementation module for SDIO pltaform driver
-
-#notes:
-
-@notice: Copyright (c), 2006 Atheros Communications, Inc.
-
-@license: This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation.
-
-
-
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Portions of this code were developed with information supplied from the
- * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
- *
- * The following conditions apply to the release of the SD simplified specification (�Simplified
- * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
- * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
- * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
- * Specification may require a license from the SD Card Association or other third parties.
- * Disclaimers:
- * The information contained in the Simplified Specification is presented only as a standard
- * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
- * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
- * any damages, any infringements of patents or other right of the SD Card Association or any third
- * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
- * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
- * be construed as an obligation by the SD Card Association to disclose or distribute any technical
- * information, know-how or other confidential information to any third party.
- *
- *
- * The initial developers of the original code are Seung Yi and Paul Lever
- *
- * sdio@atheros.com
- *
- *
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-#define DESCRIPTION "SDIO Platform Driver"
-#define AUTHOR "Atheros Communications, Inc."
-
-//??for .h
-
-struct sdioplatform_peripheral {
- struct list_head node;
- struct sdioplatform_controller *controller;
- struct device dev;
-};
-struct sdioplatform_driver {
- struct device_driver drv;
- int (*probe)(struct sdioplatform_peripheral *);
- void (*remove)(struct sdioplatform_peripheral *);
- int (*suspend)(struct sdioplatform_peripheral *, pm_message_t);
- int (*resume)(struct sdioplatform_peripheral *);
-};
-
-
-struct sdioplatform_controller {
- struct device *dev;
-};
-struct sdioplatform_controller_driver {
- struct device_driver drv;
- int (*probe)(struct sdioplatform_controller *);
- void (*remove)(struct sdioplatform_controller *);
- int (*suspend)(struct sdioplatform_controller *, pm_message_t);
- int (*resume)(struct sdioplatform_controller *);
-};
-
-
-
-#define device_to_sdioplatform_peripheral(d) container_of(d, struct sdioplatform_peripheral, dev)
-#define driver_to_sdioplatform_driver(d) container_of(d, struct sdioplatform_driver, drv)
-
-#define device_to_sdioplatform_controller(d) container_of(d, struct sdioplatform_controller, dev)
-#define driver_to_sdioplatform_controller_driver(d) container_of(d, struct sdioplatform_controller_driver, drv)
-
-#define SDIOPLATFORM_ATTR(name, fmt, args...) \
-static ssize_t sdio_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev); \
- return sprintf(buf, fmt, args); \
-}
-
-SDIOPLATFORM_ATTR(bus_id, "%s\n", bus_id);
-#define SDIOPLATFORM_ATTR_RO(name) __ATTR(name, S_IRUGO, sdioplatform_##name##_show, NULL)
-
-static struct device_attribute sdioplatform_dev_attrs[] = {
- SDIOPLATFORM_ATTR_RO(bus_id),
- __ATTR_NULL
-};
-
-static struct bus_type sdioplatform_bus_type = {
- .name = "sdioplatform",
- .dev_attrs = sdioplatform_dev_attrs,
- .match = sdioplatform_bus_match,
- .hotplug = NULL,
- .suspend = sdioplatform_bus_suspend,
- .resume = sdioplatform_bus_resume,
-};
-
-
-/* controller functions */
-static int sdioplatform_controllerdrv_probe(struct device *dev)
-{
- struct sdioplatform_controller_driver *drv = driver_to_sdioplatform_controller_driver(dev->driver);
- struct sdioplatform_controller *controller = device_to_sdioplatform_controller(dev);
-
- return drv->probe(controller);
-}
-
-static int sdioplatform_controllerdrv_remove(struct device *dev)
-{
- struct sdioplatform_controller_driver *drv = driver_to_sdioplatform_controller_driver(dev->driver);
- struct sdioplatform_controller *controller = device_to_sdioplatform_controller(dev);
-
- return drv->remove(controller);
-}
-
-/*
- * sdioplatform_register_controller_driver - register a controller driver
- */
-int sdioplatform_register_controller_driver(struct sdioplatform_controller_driver *drv)
-{
- drv->drv.bus = &sdioplatform_bus_type;
- drv->drv.probe = sdioplatform_controllerdrv_probe;
- drv->drv.remove = sdioplatform_controllerdrv_remove;
- return driver_register(&drv->drv);
-}
-
-/*
- * sdioplatform_unregister_controller_driver - unregister a controller driver
- */
-void sdioplatform_unregister_controller_driver(struct sdioplatform_driver *drv)
-{
- driver_unregister(&drv->drv);
-}
-
-/*
- * sdioplatform_add_controller - register a controller device
- */
-int sdioplatform_add_controller(char *name, struct sdioplatform_controller *dev)
-{
- if (!dev) {
- return -EINVAL;
- }
- strncpy(dev->dev.bus_id, BUS_ID_SIZE, name);
- return device_register(&dev->dev);
-}
-
-/*
- * sdioplatform_remove_controller - unregister a controller device
- */
-int sdioplatform_remove_controller(char *name, struct sdioplatform_controller *dev)
-{
- if (!dev) {
- return -EINVAL;
- }
- return device_unregister(&dev->dev);
-}
-
-/* peripheral functions */
-static int sdioplatform_drv_probe(struct device *dev)
-{
- struct sdioplatform_driver *drv = driver_to_sdioplatform_driver(dev->driver);
- struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev);
-
- return drv->probe(peripheral);
-}
-
-static int sdioplatform_controllerdrv_remove(struct device *dev)
-{
- struct sdioplatform_controller_driver *drv = driver_to_sdioplatform_controller_driver(dev->driver);
- struct sdioplatform_controller *controller = device_to_sdioplatform_controller(dev);
-
- return drv->remove(controller);
-}
-
-/*
- * sdioplatform_register_driver - register a driver
- */
-int sdioplatform_register_driver(struct sdioplatform_driver *drv)
-{
- drv->drv.bus = &sdioplatform_bus_type;
- drv->drv.probe = sdioplatform_drv_probe;
- drv->drv.remove = sdioplatform_drv_remove;
- return driver_register(&drv->drv);
-}
-
-/*
- * sdioplatform_unregister_driver - unregister a driver
- */
-void sdioplatform_unregister_driver(struct sdioplatform_driver *drv)
-{
- driver_unregister(&drv->drv);
-}
-
-/*
- * sdioplatform_add_peripheral - register a peripheral device
- */
-int sdioplatform_add_peripheral(char *name, struct sdioplatform_peripheral *dev)
-{
- if (!dev) {
- return -EINVAL;
- }
- strncpy(dev->dev.bus_id, BUS_ID_SIZE, name);
- return device_register(&dev->dev);
-}
-
-/*
- * sdioplatform_remove_peripheral - unregister a peripheral device
- */
-int sdioplatform_remove_peripheral(char *name, struct sdioplatform_peripheral *dev)
-{
- if (!dev) {
- return -EINVAL;
- }
- return device_unregister(&dev->dev);
-}
-
-
-
-
-
-static int sdioplatform_bus_match(struct device *dev, struct device_driver *drv)
-{
- /* probes handle the matching */
- return 1;
-}
-
-static int sdioplatform_bus_suspend(struct device *dev, pm_message_t state)
-{
- struct sdioplatform_driver *drv = driver_to_sdioplatform_driver(dev->driver);
- struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev);
- int ret = 0;
-
- if (peripheral->driver && drv->suspend) {
- ret = drv->suspend(peripheral, state);
- }
- return ret;
-}
-
-static int sdioplatform_bus_resume(struct device *dev)
-{
- struct sdioplatform_driver *drv = driver_to_sdioplatform_driver(dev->driver);
- struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev);
- int ret = 0;
-
- if (peripheral->driver && drv->resume) {
- ret = drv->resume(card);
- }
- return ret;
-}
-
-/*
- * module init
-*/
-static int __init sdio_platformdriver_init(void) {
- int ret = bus_register(&sdioplatform_bus_type);
- return ret;
-}
-
-/*
- * module cleanup
-*/
-static void __exit sdio_platformdriver_cleanup(void) {
- REL_PRINT(SDDBG_TRACE, ("SDIO unloaded\n"));
- _SDIO_BusDriverCleanup();
-}
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(DESCRIPTION);
-MODULE_AUTHOR(AUTHOR);
-
-module_init(sdio_platformdriver_init);
-module_exit(sdio_platformdriver_cleanup);
-EXPORT_SYMBOL(sdioplatform_register_controller_driver);
-EXPORT_SYMBOL(sdioplatform_unregister_controller_driver);
-EXPORT_SYMBOL(sdioplatform_add_controller);
-EXPORT_SYMBOL(sdioplatform_remove_controller);
-EXPORT_SYMBOL(sdioplatform_register_driver);
-EXPORT_SYMBOL(sdioplatform_unregister_driver);
-EXPORT_SYMBOL(sdioplatform_add_peripheral);
-EXPORT_SYMBOL(sdioplatform_remove_peripheral);
-
-
-