1baf8532aSAlex Dubov /* 2baf8532aSAlex Dubov * Sony MemoryStick support 3baf8532aSAlex Dubov * 4baf8532aSAlex Dubov * Copyright (C) 2007 Alex Dubov <oakad@yahoo.com> 5baf8532aSAlex Dubov * 6baf8532aSAlex Dubov * This program is free software; you can redistribute it and/or modify 7baf8532aSAlex Dubov * it under the terms of the GNU General Public License version 2 as 8baf8532aSAlex Dubov * published by the Free Software Foundation. 9baf8532aSAlex Dubov * 10baf8532aSAlex Dubov * Special thanks to Carlos Corbacho for providing various MemoryStick cards 11baf8532aSAlex Dubov * that made this driver possible. 12baf8532aSAlex Dubov * 13baf8532aSAlex Dubov */ 14baf8532aSAlex Dubov 15baf8532aSAlex Dubov #include <linux/memstick.h> 16baf8532aSAlex Dubov #include <linux/idr.h> 17baf8532aSAlex Dubov #include <linux/fs.h> 18baf8532aSAlex Dubov #include <linux/delay.h> 19*5a0e3ad6STejun Heo #include <linux/slab.h> 20baf8532aSAlex Dubov 21baf8532aSAlex Dubov #define DRIVER_NAME "memstick" 22baf8532aSAlex Dubov 23baf8532aSAlex Dubov static unsigned int cmd_retries = 3; 24baf8532aSAlex Dubov module_param(cmd_retries, uint, 0644); 25baf8532aSAlex Dubov 26baf8532aSAlex Dubov static struct workqueue_struct *workqueue; 27baf8532aSAlex Dubov static DEFINE_IDR(memstick_host_idr); 28baf8532aSAlex Dubov static DEFINE_SPINLOCK(memstick_host_lock); 29baf8532aSAlex Dubov 30baf8532aSAlex Dubov static int memstick_dev_match(struct memstick_dev *card, 31baf8532aSAlex Dubov struct memstick_device_id *id) 32baf8532aSAlex Dubov { 33baf8532aSAlex Dubov if (id->match_flags & MEMSTICK_MATCH_ALL) { 34baf8532aSAlex Dubov if ((id->type == card->id.type) 35baf8532aSAlex Dubov && (id->category == card->id.category) 36baf8532aSAlex Dubov && (id->class == card->id.class)) 37baf8532aSAlex Dubov return 1; 38baf8532aSAlex Dubov } 39baf8532aSAlex Dubov 40baf8532aSAlex Dubov return 0; 41baf8532aSAlex Dubov } 42baf8532aSAlex Dubov 43baf8532aSAlex Dubov static int memstick_bus_match(struct device *dev, struct device_driver *drv) 44baf8532aSAlex Dubov { 45baf8532aSAlex Dubov struct memstick_dev *card = container_of(dev, struct memstick_dev, 46baf8532aSAlex Dubov dev); 47baf8532aSAlex Dubov struct memstick_driver *ms_drv = container_of(drv, 48baf8532aSAlex Dubov struct memstick_driver, 49baf8532aSAlex Dubov driver); 50baf8532aSAlex Dubov struct memstick_device_id *ids = ms_drv->id_table; 51baf8532aSAlex Dubov 52baf8532aSAlex Dubov if (ids) { 53baf8532aSAlex Dubov while (ids->match_flags) { 54baf8532aSAlex Dubov if (memstick_dev_match(card, ids)) 55baf8532aSAlex Dubov return 1; 56baf8532aSAlex Dubov ++ids; 57baf8532aSAlex Dubov } 58baf8532aSAlex Dubov } 59baf8532aSAlex Dubov return 0; 60baf8532aSAlex Dubov } 61baf8532aSAlex Dubov 62baf8532aSAlex Dubov static int memstick_uevent(struct device *dev, struct kobj_uevent_env *env) 63baf8532aSAlex Dubov { 64baf8532aSAlex Dubov struct memstick_dev *card = container_of(dev, struct memstick_dev, 65baf8532aSAlex Dubov dev); 66baf8532aSAlex Dubov 67baf8532aSAlex Dubov if (add_uevent_var(env, "MEMSTICK_TYPE=%02X", card->id.type)) 68baf8532aSAlex Dubov return -ENOMEM; 69baf8532aSAlex Dubov 70baf8532aSAlex Dubov if (add_uevent_var(env, "MEMSTICK_CATEGORY=%02X", card->id.category)) 71baf8532aSAlex Dubov return -ENOMEM; 72baf8532aSAlex Dubov 73baf8532aSAlex Dubov if (add_uevent_var(env, "MEMSTICK_CLASS=%02X", card->id.class)) 74baf8532aSAlex Dubov return -ENOMEM; 75baf8532aSAlex Dubov 76baf8532aSAlex Dubov return 0; 77baf8532aSAlex Dubov } 78baf8532aSAlex Dubov 79baf8532aSAlex Dubov static int memstick_device_probe(struct device *dev) 80baf8532aSAlex Dubov { 81baf8532aSAlex Dubov struct memstick_dev *card = container_of(dev, struct memstick_dev, 82baf8532aSAlex Dubov dev); 83baf8532aSAlex Dubov struct memstick_driver *drv = container_of(dev->driver, 84baf8532aSAlex Dubov struct memstick_driver, 85baf8532aSAlex Dubov driver); 86baf8532aSAlex Dubov int rc = -ENODEV; 87baf8532aSAlex Dubov 88baf8532aSAlex Dubov if (dev->driver && drv->probe) { 89baf8532aSAlex Dubov rc = drv->probe(card); 90baf8532aSAlex Dubov if (!rc) 91baf8532aSAlex Dubov get_device(dev); 92baf8532aSAlex Dubov } 93baf8532aSAlex Dubov return rc; 94baf8532aSAlex Dubov } 95baf8532aSAlex Dubov 96baf8532aSAlex Dubov static int memstick_device_remove(struct device *dev) 97baf8532aSAlex Dubov { 98baf8532aSAlex Dubov struct memstick_dev *card = container_of(dev, struct memstick_dev, 99baf8532aSAlex Dubov dev); 100baf8532aSAlex Dubov struct memstick_driver *drv = container_of(dev->driver, 101baf8532aSAlex Dubov struct memstick_driver, 102baf8532aSAlex Dubov driver); 103baf8532aSAlex Dubov 104baf8532aSAlex Dubov if (dev->driver && drv->remove) { 105baf8532aSAlex Dubov drv->remove(card); 106baf8532aSAlex Dubov card->dev.driver = NULL; 107baf8532aSAlex Dubov } 108baf8532aSAlex Dubov 109baf8532aSAlex Dubov put_device(dev); 110baf8532aSAlex Dubov return 0; 111baf8532aSAlex Dubov } 112baf8532aSAlex Dubov 113baf8532aSAlex Dubov #ifdef CONFIG_PM 114baf8532aSAlex Dubov 115baf8532aSAlex Dubov static int memstick_device_suspend(struct device *dev, pm_message_t state) 116baf8532aSAlex Dubov { 117baf8532aSAlex Dubov struct memstick_dev *card = container_of(dev, struct memstick_dev, 118baf8532aSAlex Dubov dev); 119baf8532aSAlex Dubov struct memstick_driver *drv = container_of(dev->driver, 120baf8532aSAlex Dubov struct memstick_driver, 121baf8532aSAlex Dubov driver); 122baf8532aSAlex Dubov 123baf8532aSAlex Dubov if (dev->driver && drv->suspend) 124baf8532aSAlex Dubov return drv->suspend(card, state); 125baf8532aSAlex Dubov return 0; 126baf8532aSAlex Dubov } 127baf8532aSAlex Dubov 128baf8532aSAlex Dubov static int memstick_device_resume(struct device *dev) 129baf8532aSAlex Dubov { 130baf8532aSAlex Dubov struct memstick_dev *card = container_of(dev, struct memstick_dev, 131baf8532aSAlex Dubov dev); 132baf8532aSAlex Dubov struct memstick_driver *drv = container_of(dev->driver, 133baf8532aSAlex Dubov struct memstick_driver, 134baf8532aSAlex Dubov driver); 135baf8532aSAlex Dubov 136baf8532aSAlex Dubov if (dev->driver && drv->resume) 137baf8532aSAlex Dubov return drv->resume(card); 138baf8532aSAlex Dubov return 0; 139baf8532aSAlex Dubov } 140baf8532aSAlex Dubov 141baf8532aSAlex Dubov #else 142baf8532aSAlex Dubov 143baf8532aSAlex Dubov #define memstick_device_suspend NULL 144baf8532aSAlex Dubov #define memstick_device_resume NULL 145baf8532aSAlex Dubov 146baf8532aSAlex Dubov #endif /* CONFIG_PM */ 147baf8532aSAlex Dubov 148baf8532aSAlex Dubov #define MEMSTICK_ATTR(name, format) \ 149baf8532aSAlex Dubov static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \ 150baf8532aSAlex Dubov char *buf) \ 151baf8532aSAlex Dubov { \ 152baf8532aSAlex Dubov struct memstick_dev *card = container_of(dev, struct memstick_dev, \ 153baf8532aSAlex Dubov dev); \ 154baf8532aSAlex Dubov return sprintf(buf, format, card->id.name); \ 155baf8532aSAlex Dubov } 156baf8532aSAlex Dubov 157baf8532aSAlex Dubov MEMSTICK_ATTR(type, "%02X"); 158baf8532aSAlex Dubov MEMSTICK_ATTR(category, "%02X"); 159baf8532aSAlex Dubov MEMSTICK_ATTR(class, "%02X"); 160baf8532aSAlex Dubov 161baf8532aSAlex Dubov #define MEMSTICK_ATTR_RO(name) __ATTR(name, S_IRUGO, name##_show, NULL) 162baf8532aSAlex Dubov 163baf8532aSAlex Dubov static struct device_attribute memstick_dev_attrs[] = { 164baf8532aSAlex Dubov MEMSTICK_ATTR_RO(type), 165baf8532aSAlex Dubov MEMSTICK_ATTR_RO(category), 166baf8532aSAlex Dubov MEMSTICK_ATTR_RO(class), 167baf8532aSAlex Dubov __ATTR_NULL 168baf8532aSAlex Dubov }; 169baf8532aSAlex Dubov 170baf8532aSAlex Dubov static struct bus_type memstick_bus_type = { 171baf8532aSAlex Dubov .name = "memstick", 172baf8532aSAlex Dubov .dev_attrs = memstick_dev_attrs, 173baf8532aSAlex Dubov .match = memstick_bus_match, 174baf8532aSAlex Dubov .uevent = memstick_uevent, 175baf8532aSAlex Dubov .probe = memstick_device_probe, 176baf8532aSAlex Dubov .remove = memstick_device_remove, 177baf8532aSAlex Dubov .suspend = memstick_device_suspend, 178baf8532aSAlex Dubov .resume = memstick_device_resume 179baf8532aSAlex Dubov }; 180baf8532aSAlex Dubov 181c4c66cf1SGreg Kroah-Hartman static void memstick_free(struct device *dev) 182baf8532aSAlex Dubov { 183c4c66cf1SGreg Kroah-Hartman struct memstick_host *host = container_of(dev, struct memstick_host, 184c4c66cf1SGreg Kroah-Hartman dev); 185baf8532aSAlex Dubov kfree(host); 186baf8532aSAlex Dubov } 187baf8532aSAlex Dubov 188baf8532aSAlex Dubov static struct class memstick_host_class = { 189baf8532aSAlex Dubov .name = "memstick_host", 190c4c66cf1SGreg Kroah-Hartman .dev_release = memstick_free 191baf8532aSAlex Dubov }; 192baf8532aSAlex Dubov 193baf8532aSAlex Dubov static void memstick_free_card(struct device *dev) 194baf8532aSAlex Dubov { 195baf8532aSAlex Dubov struct memstick_dev *card = container_of(dev, struct memstick_dev, 196baf8532aSAlex Dubov dev); 197baf8532aSAlex Dubov kfree(card); 198baf8532aSAlex Dubov } 199baf8532aSAlex Dubov 200baf8532aSAlex Dubov static int memstick_dummy_check(struct memstick_dev *card) 201baf8532aSAlex Dubov { 202baf8532aSAlex Dubov return 0; 203baf8532aSAlex Dubov } 204baf8532aSAlex Dubov 205baf8532aSAlex Dubov /** 206baf8532aSAlex Dubov * memstick_detect_change - schedule media detection on memstick host 207baf8532aSAlex Dubov * @host - host to use 208baf8532aSAlex Dubov */ 209baf8532aSAlex Dubov void memstick_detect_change(struct memstick_host *host) 210baf8532aSAlex Dubov { 211baf8532aSAlex Dubov queue_work(workqueue, &host->media_checker); 212baf8532aSAlex Dubov } 213baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_detect_change); 214baf8532aSAlex Dubov 215baf8532aSAlex Dubov /** 216baf8532aSAlex Dubov * memstick_next_req - called by host driver to obtain next request to process 217baf8532aSAlex Dubov * @host - host to use 218baf8532aSAlex Dubov * @mrq - pointer to stick the request to 219baf8532aSAlex Dubov * 220baf8532aSAlex Dubov * Host calls this function from idle state (*mrq == NULL) or after finishing 221baf8532aSAlex Dubov * previous request (*mrq should point to it). If previous request was 222baf8532aSAlex Dubov * unsuccessful, it is retried for predetermined number of times. Return value 223baf8532aSAlex Dubov * of 0 means that new request was assigned to the host. 224baf8532aSAlex Dubov */ 225baf8532aSAlex Dubov int memstick_next_req(struct memstick_host *host, struct memstick_request **mrq) 226baf8532aSAlex Dubov { 227baf8532aSAlex Dubov int rc = -ENXIO; 228baf8532aSAlex Dubov 229baf8532aSAlex Dubov if ((*mrq) && (*mrq)->error && host->retries) { 230baf8532aSAlex Dubov (*mrq)->error = rc; 231baf8532aSAlex Dubov host->retries--; 232baf8532aSAlex Dubov return 0; 233baf8532aSAlex Dubov } 234baf8532aSAlex Dubov 235baf8532aSAlex Dubov if (host->card && host->card->next_request) 236baf8532aSAlex Dubov rc = host->card->next_request(host->card, mrq); 237baf8532aSAlex Dubov 238baf8532aSAlex Dubov if (!rc) 23929196dc6SAlex Dubov host->retries = cmd_retries > 1 ? cmd_retries - 1 : 1; 240baf8532aSAlex Dubov else 241baf8532aSAlex Dubov *mrq = NULL; 242baf8532aSAlex Dubov 243baf8532aSAlex Dubov return rc; 244baf8532aSAlex Dubov } 245baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_next_req); 246baf8532aSAlex Dubov 247baf8532aSAlex Dubov /** 248baf8532aSAlex Dubov * memstick_new_req - notify the host that some requests are pending 249baf8532aSAlex Dubov * @host - host to use 250baf8532aSAlex Dubov */ 251baf8532aSAlex Dubov void memstick_new_req(struct memstick_host *host) 252baf8532aSAlex Dubov { 253f1d82698SAlex Dubov if (host->card) { 254baf8532aSAlex Dubov host->retries = cmd_retries; 255f1d82698SAlex Dubov INIT_COMPLETION(host->card->mrq_complete); 256baf8532aSAlex Dubov host->request(host); 257baf8532aSAlex Dubov } 258f1d82698SAlex Dubov } 259baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_new_req); 260baf8532aSAlex Dubov 261baf8532aSAlex Dubov /** 262baf8532aSAlex Dubov * memstick_init_req_sg - set request fields needed for bulk data transfer 263baf8532aSAlex Dubov * @mrq - request to use 264baf8532aSAlex Dubov * @tpc - memstick Transport Protocol Command 265baf8532aSAlex Dubov * @sg - TPC argument 266baf8532aSAlex Dubov */ 267baf8532aSAlex Dubov void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc, 2688e82f8c3SAlex Dubov const struct scatterlist *sg) 269baf8532aSAlex Dubov { 270baf8532aSAlex Dubov mrq->tpc = tpc; 271baf8532aSAlex Dubov if (tpc & 8) 272baf8532aSAlex Dubov mrq->data_dir = WRITE; 273baf8532aSAlex Dubov else 274baf8532aSAlex Dubov mrq->data_dir = READ; 275baf8532aSAlex Dubov 276baf8532aSAlex Dubov mrq->sg = *sg; 277e1f19995SAlex Dubov mrq->long_data = 1; 278baf8532aSAlex Dubov 279baf8532aSAlex Dubov if (tpc == MS_TPC_SET_CMD || tpc == MS_TPC_EX_SET_CMD) 280baf8532aSAlex Dubov mrq->need_card_int = 1; 281baf8532aSAlex Dubov else 282baf8532aSAlex Dubov mrq->need_card_int = 0; 283baf8532aSAlex Dubov } 284baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_init_req_sg); 285baf8532aSAlex Dubov 286baf8532aSAlex Dubov /** 287baf8532aSAlex Dubov * memstick_init_req - set request fields needed for short data transfer 288baf8532aSAlex Dubov * @mrq - request to use 289baf8532aSAlex Dubov * @tpc - memstick Transport Protocol Command 290baf8532aSAlex Dubov * @buf - TPC argument buffer 291baf8532aSAlex Dubov * @length - TPC argument size 292baf8532aSAlex Dubov * 293baf8532aSAlex Dubov * The intended use of this function (transfer of data items several bytes 294baf8532aSAlex Dubov * in size) allows us to just copy the value between request structure and 295baf8532aSAlex Dubov * user supplied buffer. 296baf8532aSAlex Dubov */ 297baf8532aSAlex Dubov void memstick_init_req(struct memstick_request *mrq, unsigned char tpc, 2988e82f8c3SAlex Dubov const void *buf, size_t length) 299baf8532aSAlex Dubov { 300baf8532aSAlex Dubov mrq->tpc = tpc; 301baf8532aSAlex Dubov if (tpc & 8) 302baf8532aSAlex Dubov mrq->data_dir = WRITE; 303baf8532aSAlex Dubov else 304baf8532aSAlex Dubov mrq->data_dir = READ; 305baf8532aSAlex Dubov 306baf8532aSAlex Dubov mrq->data_len = length > sizeof(mrq->data) ? sizeof(mrq->data) : length; 307baf8532aSAlex Dubov if (mrq->data_dir == WRITE) 308baf8532aSAlex Dubov memcpy(mrq->data, buf, mrq->data_len); 309baf8532aSAlex Dubov 310e1f19995SAlex Dubov mrq->long_data = 0; 311baf8532aSAlex Dubov 312baf8532aSAlex Dubov if (tpc == MS_TPC_SET_CMD || tpc == MS_TPC_EX_SET_CMD) 313baf8532aSAlex Dubov mrq->need_card_int = 1; 314baf8532aSAlex Dubov else 315baf8532aSAlex Dubov mrq->need_card_int = 0; 316baf8532aSAlex Dubov } 317baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_init_req); 318baf8532aSAlex Dubov 319baf8532aSAlex Dubov /* 320baf8532aSAlex Dubov * Functions prefixed with "h_" are protocol callbacks. They can be called from 321baf8532aSAlex Dubov * interrupt context. Return value of 0 means that request processing is still 322baf8532aSAlex Dubov * ongoing, while special error value of -EAGAIN means that current request is 323baf8532aSAlex Dubov * finished (and request processor should come back some time later). 324baf8532aSAlex Dubov */ 325baf8532aSAlex Dubov 326baf8532aSAlex Dubov static int h_memstick_read_dev_id(struct memstick_dev *card, 327baf8532aSAlex Dubov struct memstick_request **mrq) 328baf8532aSAlex Dubov { 329baf8532aSAlex Dubov struct ms_id_register id_reg; 330baf8532aSAlex Dubov 331baf8532aSAlex Dubov if (!(*mrq)) { 332baf8532aSAlex Dubov memstick_init_req(&card->current_mrq, MS_TPC_READ_REG, NULL, 333baf8532aSAlex Dubov sizeof(struct ms_id_register)); 334baf8532aSAlex Dubov *mrq = &card->current_mrq; 335baf8532aSAlex Dubov return 0; 336baf8532aSAlex Dubov } else { 337baf8532aSAlex Dubov if (!(*mrq)->error) { 338baf8532aSAlex Dubov memcpy(&id_reg, (*mrq)->data, sizeof(id_reg)); 339baf8532aSAlex Dubov card->id.match_flags = MEMSTICK_MATCH_ALL; 340baf8532aSAlex Dubov card->id.type = id_reg.type; 341baf8532aSAlex Dubov card->id.category = id_reg.category; 342baf8532aSAlex Dubov card->id.class = id_reg.class; 343b873c2f3SJiri Slaby dev_dbg(&card->dev, "if_mode = %02x\n", id_reg.if_mode); 344baf8532aSAlex Dubov } 345baf8532aSAlex Dubov complete(&card->mrq_complete); 346baf8532aSAlex Dubov return -EAGAIN; 347baf8532aSAlex Dubov } 348baf8532aSAlex Dubov } 349baf8532aSAlex Dubov 350baf8532aSAlex Dubov static int h_memstick_set_rw_addr(struct memstick_dev *card, 351baf8532aSAlex Dubov struct memstick_request **mrq) 352baf8532aSAlex Dubov { 353baf8532aSAlex Dubov if (!(*mrq)) { 354baf8532aSAlex Dubov memstick_init_req(&card->current_mrq, MS_TPC_SET_RW_REG_ADRS, 355baf8532aSAlex Dubov (char *)&card->reg_addr, 356baf8532aSAlex Dubov sizeof(card->reg_addr)); 357baf8532aSAlex Dubov *mrq = &card->current_mrq; 358baf8532aSAlex Dubov return 0; 359baf8532aSAlex Dubov } else { 360baf8532aSAlex Dubov complete(&card->mrq_complete); 361baf8532aSAlex Dubov return -EAGAIN; 362baf8532aSAlex Dubov } 363baf8532aSAlex Dubov } 364baf8532aSAlex Dubov 365baf8532aSAlex Dubov /** 366baf8532aSAlex Dubov * memstick_set_rw_addr - issue SET_RW_REG_ADDR request and wait for it to 367baf8532aSAlex Dubov * complete 368baf8532aSAlex Dubov * @card - media device to use 369baf8532aSAlex Dubov */ 370baf8532aSAlex Dubov int memstick_set_rw_addr(struct memstick_dev *card) 371baf8532aSAlex Dubov { 372baf8532aSAlex Dubov card->next_request = h_memstick_set_rw_addr; 373baf8532aSAlex Dubov memstick_new_req(card->host); 374baf8532aSAlex Dubov wait_for_completion(&card->mrq_complete); 375baf8532aSAlex Dubov 376baf8532aSAlex Dubov return card->current_mrq.error; 377baf8532aSAlex Dubov } 378baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_set_rw_addr); 379baf8532aSAlex Dubov 380baf8532aSAlex Dubov static struct memstick_dev *memstick_alloc_card(struct memstick_host *host) 381baf8532aSAlex Dubov { 382baf8532aSAlex Dubov struct memstick_dev *card = kzalloc(sizeof(struct memstick_dev), 383baf8532aSAlex Dubov GFP_KERNEL); 384baf8532aSAlex Dubov struct memstick_dev *old_card = host->card; 385baf8532aSAlex Dubov struct ms_id_register id_reg; 386baf8532aSAlex Dubov 387baf8532aSAlex Dubov if (card) { 388baf8532aSAlex Dubov card->host = host; 3890252c3b4SKay Sievers dev_set_name(&card->dev, "%s", dev_name(&host->dev)); 390c4c66cf1SGreg Kroah-Hartman card->dev.parent = &host->dev; 391baf8532aSAlex Dubov card->dev.bus = &memstick_bus_type; 392baf8532aSAlex Dubov card->dev.release = memstick_free_card; 393baf8532aSAlex Dubov card->check = memstick_dummy_check; 394baf8532aSAlex Dubov 395baf8532aSAlex Dubov card->reg_addr.r_offset = offsetof(struct ms_register, id); 396baf8532aSAlex Dubov card->reg_addr.r_length = sizeof(id_reg); 397baf8532aSAlex Dubov card->reg_addr.w_offset = offsetof(struct ms_register, id); 398baf8532aSAlex Dubov card->reg_addr.w_length = sizeof(id_reg); 399baf8532aSAlex Dubov 400baf8532aSAlex Dubov init_completion(&card->mrq_complete); 401baf8532aSAlex Dubov 402baf8532aSAlex Dubov host->card = card; 403baf8532aSAlex Dubov if (memstick_set_rw_addr(card)) 404baf8532aSAlex Dubov goto err_out; 405baf8532aSAlex Dubov 406baf8532aSAlex Dubov card->next_request = h_memstick_read_dev_id; 407baf8532aSAlex Dubov memstick_new_req(host); 408baf8532aSAlex Dubov wait_for_completion(&card->mrq_complete); 409baf8532aSAlex Dubov 410baf8532aSAlex Dubov if (card->current_mrq.error) 411baf8532aSAlex Dubov goto err_out; 412baf8532aSAlex Dubov } 413baf8532aSAlex Dubov host->card = old_card; 414baf8532aSAlex Dubov return card; 415baf8532aSAlex Dubov err_out: 416baf8532aSAlex Dubov host->card = old_card; 417baf8532aSAlex Dubov kfree(card); 418baf8532aSAlex Dubov return NULL; 419baf8532aSAlex Dubov } 420baf8532aSAlex Dubov 421b7789998SAlex Dubov static int memstick_power_on(struct memstick_host *host) 422baf8532aSAlex Dubov { 423b7789998SAlex Dubov int rc = host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); 424b7789998SAlex Dubov 425b7789998SAlex Dubov if (!rc) 426b7789998SAlex Dubov rc = host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL); 427b7789998SAlex Dubov 428b7789998SAlex Dubov return rc; 429baf8532aSAlex Dubov } 430baf8532aSAlex Dubov 431baf8532aSAlex Dubov static void memstick_check(struct work_struct *work) 432baf8532aSAlex Dubov { 433baf8532aSAlex Dubov struct memstick_host *host = container_of(work, struct memstick_host, 434baf8532aSAlex Dubov media_checker); 435baf8532aSAlex Dubov struct memstick_dev *card; 436baf8532aSAlex Dubov 437c4c66cf1SGreg Kroah-Hartman dev_dbg(&host->dev, "memstick_check started\n"); 438baf8532aSAlex Dubov mutex_lock(&host->lock); 43917017d8dSAlex Dubov if (!host->card) { 44017017d8dSAlex Dubov if (memstick_power_on(host)) 44117017d8dSAlex Dubov goto out_power_off; 4428e82f8c3SAlex Dubov } else if (host->card->stop) 44317017d8dSAlex Dubov host->card->stop(host->card); 444baf8532aSAlex Dubov 445baf8532aSAlex Dubov card = memstick_alloc_card(host); 446baf8532aSAlex Dubov 447baf8532aSAlex Dubov if (!card) { 448baf8532aSAlex Dubov if (host->card) { 449baf8532aSAlex Dubov device_unregister(&host->card->dev); 450baf8532aSAlex Dubov host->card = NULL; 451baf8532aSAlex Dubov } 452baf8532aSAlex Dubov } else { 453c4c66cf1SGreg Kroah-Hartman dev_dbg(&host->dev, "new card %02x, %02x, %02x\n", 454baf8532aSAlex Dubov card->id.type, card->id.category, card->id.class); 455baf8532aSAlex Dubov if (host->card) { 456baf8532aSAlex Dubov if (memstick_set_rw_addr(host->card) 457baf8532aSAlex Dubov || !memstick_dev_match(host->card, &card->id) 458baf8532aSAlex Dubov || !(host->card->check(host->card))) { 459baf8532aSAlex Dubov device_unregister(&host->card->dev); 460baf8532aSAlex Dubov host->card = NULL; 4618e82f8c3SAlex Dubov } else if (host->card->start) 46217017d8dSAlex Dubov host->card->start(host->card); 463baf8532aSAlex Dubov } 464baf8532aSAlex Dubov 465baf8532aSAlex Dubov if (!host->card) { 466baf8532aSAlex Dubov host->card = card; 467baf8532aSAlex Dubov if (device_register(&card->dev)) { 468baf8532aSAlex Dubov kfree(host->card); 469baf8532aSAlex Dubov host->card = NULL; 470baf8532aSAlex Dubov } 471baf8532aSAlex Dubov } else 472baf8532aSAlex Dubov kfree(card); 473baf8532aSAlex Dubov } 474baf8532aSAlex Dubov 47517017d8dSAlex Dubov out_power_off: 476baf8532aSAlex Dubov if (!host->card) 477baf8532aSAlex Dubov host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); 478baf8532aSAlex Dubov 479baf8532aSAlex Dubov mutex_unlock(&host->lock); 480c4c66cf1SGreg Kroah-Hartman dev_dbg(&host->dev, "memstick_check finished\n"); 481baf8532aSAlex Dubov } 482baf8532aSAlex Dubov 483baf8532aSAlex Dubov /** 484baf8532aSAlex Dubov * memstick_alloc_host - allocate a memstick_host structure 485baf8532aSAlex Dubov * @extra: size of the user private data to allocate 486baf8532aSAlex Dubov * @dev: parent device of the host 487baf8532aSAlex Dubov */ 488baf8532aSAlex Dubov struct memstick_host *memstick_alloc_host(unsigned int extra, 489baf8532aSAlex Dubov struct device *dev) 490baf8532aSAlex Dubov { 491baf8532aSAlex Dubov struct memstick_host *host; 492baf8532aSAlex Dubov 493baf8532aSAlex Dubov host = kzalloc(sizeof(struct memstick_host) + extra, GFP_KERNEL); 494baf8532aSAlex Dubov if (host) { 495baf8532aSAlex Dubov mutex_init(&host->lock); 496baf8532aSAlex Dubov INIT_WORK(&host->media_checker, memstick_check); 497c4c66cf1SGreg Kroah-Hartman host->dev.class = &memstick_host_class; 498c4c66cf1SGreg Kroah-Hartman host->dev.parent = dev; 499c4c66cf1SGreg Kroah-Hartman device_initialize(&host->dev); 500baf8532aSAlex Dubov } 501baf8532aSAlex Dubov return host; 502baf8532aSAlex Dubov } 503baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_alloc_host); 504baf8532aSAlex Dubov 505baf8532aSAlex Dubov /** 506baf8532aSAlex Dubov * memstick_add_host - start request processing on memstick host 507baf8532aSAlex Dubov * @host - host to use 508baf8532aSAlex Dubov */ 509baf8532aSAlex Dubov int memstick_add_host(struct memstick_host *host) 510baf8532aSAlex Dubov { 511baf8532aSAlex Dubov int rc; 512baf8532aSAlex Dubov 513baf8532aSAlex Dubov if (!idr_pre_get(&memstick_host_idr, GFP_KERNEL)) 514baf8532aSAlex Dubov return -ENOMEM; 515baf8532aSAlex Dubov 516baf8532aSAlex Dubov spin_lock(&memstick_host_lock); 517baf8532aSAlex Dubov rc = idr_get_new(&memstick_host_idr, host, &host->id); 518baf8532aSAlex Dubov spin_unlock(&memstick_host_lock); 519baf8532aSAlex Dubov if (rc) 520baf8532aSAlex Dubov return rc; 521baf8532aSAlex Dubov 5220252c3b4SKay Sievers dev_set_name(&host->dev, "memstick%u", host->id); 523baf8532aSAlex Dubov 524c4c66cf1SGreg Kroah-Hartman rc = device_add(&host->dev); 525baf8532aSAlex Dubov if (rc) { 526baf8532aSAlex Dubov spin_lock(&memstick_host_lock); 527baf8532aSAlex Dubov idr_remove(&memstick_host_idr, host->id); 528baf8532aSAlex Dubov spin_unlock(&memstick_host_lock); 529baf8532aSAlex Dubov return rc; 530baf8532aSAlex Dubov } 531baf8532aSAlex Dubov 532baf8532aSAlex Dubov host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); 533baf8532aSAlex Dubov memstick_detect_change(host); 534baf8532aSAlex Dubov return 0; 535baf8532aSAlex Dubov } 536baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_add_host); 537baf8532aSAlex Dubov 538baf8532aSAlex Dubov /** 539baf8532aSAlex Dubov * memstick_remove_host - stop request processing on memstick host 540baf8532aSAlex Dubov * @host - host to use 541baf8532aSAlex Dubov */ 542baf8532aSAlex Dubov void memstick_remove_host(struct memstick_host *host) 543baf8532aSAlex Dubov { 544baf8532aSAlex Dubov flush_workqueue(workqueue); 545baf8532aSAlex Dubov mutex_lock(&host->lock); 546baf8532aSAlex Dubov if (host->card) 547baf8532aSAlex Dubov device_unregister(&host->card->dev); 548baf8532aSAlex Dubov host->card = NULL; 549baf8532aSAlex Dubov host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); 550baf8532aSAlex Dubov mutex_unlock(&host->lock); 551baf8532aSAlex Dubov 552baf8532aSAlex Dubov spin_lock(&memstick_host_lock); 553baf8532aSAlex Dubov idr_remove(&memstick_host_idr, host->id); 554baf8532aSAlex Dubov spin_unlock(&memstick_host_lock); 555c4c66cf1SGreg Kroah-Hartman device_del(&host->dev); 556baf8532aSAlex Dubov } 557baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_remove_host); 558baf8532aSAlex Dubov 559baf8532aSAlex Dubov /** 560baf8532aSAlex Dubov * memstick_free_host - free memstick host 561baf8532aSAlex Dubov * @host - host to use 562baf8532aSAlex Dubov */ 563baf8532aSAlex Dubov void memstick_free_host(struct memstick_host *host) 564baf8532aSAlex Dubov { 565baf8532aSAlex Dubov mutex_destroy(&host->lock); 566c4c66cf1SGreg Kroah-Hartman put_device(&host->dev); 567baf8532aSAlex Dubov } 568baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_free_host); 569baf8532aSAlex Dubov 570d114ad54SAlex Dubov /** 571d114ad54SAlex Dubov * memstick_suspend_host - notify bus driver of host suspension 572d114ad54SAlex Dubov * @host - host to use 573d114ad54SAlex Dubov */ 574d114ad54SAlex Dubov void memstick_suspend_host(struct memstick_host *host) 575d114ad54SAlex Dubov { 576d114ad54SAlex Dubov mutex_lock(&host->lock); 577d114ad54SAlex Dubov host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); 578d114ad54SAlex Dubov mutex_unlock(&host->lock); 579d114ad54SAlex Dubov } 580d114ad54SAlex Dubov EXPORT_SYMBOL(memstick_suspend_host); 581d114ad54SAlex Dubov 582d114ad54SAlex Dubov /** 583d114ad54SAlex Dubov * memstick_resume_host - notify bus driver of host resumption 584d114ad54SAlex Dubov * @host - host to use 585d114ad54SAlex Dubov */ 586d114ad54SAlex Dubov void memstick_resume_host(struct memstick_host *host) 587d114ad54SAlex Dubov { 588b7789998SAlex Dubov int rc = 0; 589b7789998SAlex Dubov 590d114ad54SAlex Dubov mutex_lock(&host->lock); 591ead70773SAlex Dubov if (host->card) 592b7789998SAlex Dubov rc = memstick_power_on(host); 593d114ad54SAlex Dubov mutex_unlock(&host->lock); 594b7789998SAlex Dubov 595b7789998SAlex Dubov if (!rc) 596d114ad54SAlex Dubov memstick_detect_change(host); 597d114ad54SAlex Dubov } 598d114ad54SAlex Dubov EXPORT_SYMBOL(memstick_resume_host); 599d114ad54SAlex Dubov 600baf8532aSAlex Dubov int memstick_register_driver(struct memstick_driver *drv) 601baf8532aSAlex Dubov { 602baf8532aSAlex Dubov drv->driver.bus = &memstick_bus_type; 603baf8532aSAlex Dubov 604baf8532aSAlex Dubov return driver_register(&drv->driver); 605baf8532aSAlex Dubov } 606baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_register_driver); 607baf8532aSAlex Dubov 608baf8532aSAlex Dubov void memstick_unregister_driver(struct memstick_driver *drv) 609baf8532aSAlex Dubov { 610baf8532aSAlex Dubov driver_unregister(&drv->driver); 611baf8532aSAlex Dubov } 612baf8532aSAlex Dubov EXPORT_SYMBOL(memstick_unregister_driver); 613baf8532aSAlex Dubov 614baf8532aSAlex Dubov 615baf8532aSAlex Dubov static int __init memstick_init(void) 616baf8532aSAlex Dubov { 617baf8532aSAlex Dubov int rc; 618baf8532aSAlex Dubov 619baf8532aSAlex Dubov workqueue = create_freezeable_workqueue("kmemstick"); 620baf8532aSAlex Dubov if (!workqueue) 621baf8532aSAlex Dubov return -ENOMEM; 622baf8532aSAlex Dubov 623baf8532aSAlex Dubov rc = bus_register(&memstick_bus_type); 624baf8532aSAlex Dubov if (!rc) 625baf8532aSAlex Dubov rc = class_register(&memstick_host_class); 626baf8532aSAlex Dubov 627baf8532aSAlex Dubov if (!rc) 628baf8532aSAlex Dubov return 0; 629baf8532aSAlex Dubov 630baf8532aSAlex Dubov bus_unregister(&memstick_bus_type); 631baf8532aSAlex Dubov destroy_workqueue(workqueue); 632baf8532aSAlex Dubov 633baf8532aSAlex Dubov return rc; 634baf8532aSAlex Dubov } 635baf8532aSAlex Dubov 636baf8532aSAlex Dubov static void __exit memstick_exit(void) 637baf8532aSAlex Dubov { 638baf8532aSAlex Dubov class_unregister(&memstick_host_class); 639baf8532aSAlex Dubov bus_unregister(&memstick_bus_type); 640baf8532aSAlex Dubov destroy_workqueue(workqueue); 641baf8532aSAlex Dubov idr_destroy(&memstick_host_idr); 642baf8532aSAlex Dubov } 643baf8532aSAlex Dubov 644baf8532aSAlex Dubov module_init(memstick_init); 645baf8532aSAlex Dubov module_exit(memstick_exit); 646baf8532aSAlex Dubov 647baf8532aSAlex Dubov MODULE_AUTHOR("Alex Dubov"); 648baf8532aSAlex Dubov MODULE_LICENSE("GPL"); 649baf8532aSAlex Dubov MODULE_DESCRIPTION("Sony MemoryStick core driver"); 650