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