X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fmedia%2Fdvb%2Fsiano%2Fsmscoreapi.c;h=c5f45fed69dc41290a2300a5a90dfea701f87cdb;hb=f2d7499be1b1fe1cd8a5e6a01c1f44173894a241;hp=e55138e6627ab51baf2281023f5146655047188b;hpb=18658117ff844e8117f6b363cb7fa8c5f8ad2cb8;p=linux-2.6 diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index e55138e662..c5f45fed69 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -27,41 +27,38 @@ #include #include #include -#include +#include #include #include "smscoreapi.h" +#include "sms-cards.h" -typedef struct _smscore_device_notifyee -{ +int sms_debug; +module_param_named(debug, sms_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); + +struct smscore_device_notifyee_t { struct list_head entry; hotplug_t hotplug; -} smscore_device_notifyee_t; +}; -typedef struct _smscore_client -{ +struct smscore_idlist_t { struct list_head entry; - smscore_device_t *coredev; + int id; + int data_type; +}; +struct smscore_client_t { + struct list_head entry; + struct smscore_device_t *coredev; void *context; - - int data_type; - + struct list_head idlist; onresponse_t onresponse_handler; onremove_t onremove_handler; -} *psmscore_client_t; - -typedef struct _smscore_subclient -{ - struct list_head entry; - smscore_client_t *client; - - int id; -} smscore_subclient_t; +}; -typedef struct _smscore_device -{ +struct smscore_device_t { struct list_head entry; struct list_head clients; @@ -92,81 +89,119 @@ typedef struct _smscore_device struct completion version_ex_done, data_download_done, trigger_done; struct completion init_device_done, reload_start_done, resume_done; -} *psmscore_device_t; -typedef struct _smscore_registry_entry + int board_id; +}; + +void smscore_set_board_id(struct smscore_device_t *core, int id) +{ + core->board_id = id; +} + +int smscore_get_board_id(struct smscore_device_t *core) { + return core->board_id; +} + +struct smscore_registry_entry_t { struct list_head entry; char devpath[32]; int mode; -} smscore_registry_entry_t; + enum sms_device_type_st type; +}; + +static struct list_head g_smscore_notifyees; +static struct list_head g_smscore_devices; +static struct mutex g_smscore_deviceslock; -struct list_head g_smscore_notifyees; -struct list_head g_smscore_devices; -kmutex_t g_smscore_deviceslock; +static struct list_head g_smscore_registry; +static struct mutex g_smscore_registrylock; -struct list_head g_smscore_registry; -kmutex_t g_smscore_registrylock; +static int default_mode = 4; -static int default_mode = 1; module_param(default_mode, int, 0644); MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); -int smscore_registry_getmode(char* devpath) +static struct smscore_registry_entry_t *smscore_find_registry(char *devpath) { - smscore_registry_entry_t *entry; + struct smscore_registry_entry_t *entry; struct list_head *next; kmutex_lock(&g_smscore_registrylock); - - for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) - { - entry = (smscore_registry_entry_t *) next; - - if (!strcmp(entry->devpath, devpath)) - { + for (next = g_smscore_registry.next; + next != &g_smscore_registry; + next = next->next) { + entry = (struct smscore_registry_entry_t *) next; + if (!strcmp(entry->devpath, devpath)) { kmutex_unlock(&g_smscore_registrylock); - return entry->mode; + return entry; } } - - entry = (smscore_registry_entry_t *) kmalloc(sizeof(smscore_registry_entry_t), GFP_KERNEL); - if (entry) - { + entry = (struct smscore_registry_entry_t *) + kmalloc(sizeof(struct smscore_registry_entry_t), + GFP_KERNEL); + if (entry) { entry->mode = default_mode; strcpy(entry->devpath, devpath); - list_add(&entry->entry, &g_smscore_registry); - } - + } else + sms_err("failed to create smscore_registry."); kmutex_unlock(&g_smscore_registrylock); + return entry; +} + +int smscore_registry_getmode(char *devpath) +{ + struct smscore_registry_entry_t *entry; + + entry = smscore_find_registry(devpath); + if (entry) + return entry->mode; + else + sms_err("No registry found."); return default_mode; } -void smscore_registry_setmode(char* devpath, int mode) +static enum sms_device_type_st smscore_registry_gettype(char *devpath) { - smscore_registry_entry_t *entry; - struct list_head *next; + struct smscore_registry_entry_t *entry; - kmutex_lock(&g_smscore_registrylock); + entry = smscore_find_registry(devpath); + if (entry) + return entry->type; + else + sms_err("No registry found."); - for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) - { - entry = (smscore_registry_entry_t *) next; + return -1; +} - if (!strcmp(entry->devpath, devpath)) - { - entry->mode = mode; - break; - } - } +void smscore_registry_setmode(char *devpath, int mode) +{ + struct smscore_registry_entry_t *entry; - kmutex_unlock(&g_smscore_registrylock); + entry = smscore_find_registry(devpath); + if (entry) + entry->mode = mode; + else + sms_err("No registry found."); } +static void smscore_registry_settype(char *devpath, + enum sms_device_type_st type) +{ + struct smscore_registry_entry_t *entry; -void list_add_locked(struct list_head *new, struct list_head *head, spinlock_t* lock) + entry = smscore_find_registry(devpath); + if (entry) + entry->type = type; + else + sms_err("No registry found."); +} + + +static void list_add_locked(struct list_head *new, struct list_head *head, + spinlock_t *lock) { unsigned long flags; @@ -187,32 +222,31 @@ void list_add_locked(struct list_head *new, struct list_head *head, spinlock_t* */ int smscore_register_hotplug(hotplug_t hotplug) { - smscore_device_notifyee_t *notifyee; + struct smscore_device_notifyee_t *notifyee; struct list_head *next, *first; int rc = 0; kmutex_lock(&g_smscore_deviceslock); - notifyee = kmalloc(sizeof(smscore_device_notifyee_t), GFP_KERNEL); - if (notifyee) - { - // now notify callback about existing devices + notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t), + GFP_KERNEL); + if (notifyee) { + /* now notify callback about existing devices */ first = &g_smscore_devices; - for (next = first->next; next != first && !rc; next = next->next) - { - smscore_device_t *coredev = (smscore_device_t *) next; + for (next = first->next; + next != first && !rc; + next = next->next) { + struct smscore_device_t *coredev = + (struct smscore_device_t *) next; rc = hotplug(coredev, coredev->device, 1); } - if (rc >= 0) - { + if (rc >= 0) { notifyee->hotplug = hotplug; list_add(¬ifyee->entry, &g_smscore_notifyees); - } - else + } else kfree(notifyee); - } - else + } else rc = -ENOMEM; kmutex_unlock(&g_smscore_deviceslock); @@ -234,13 +268,12 @@ void smscore_unregister_hotplug(hotplug_t hotplug) first = &g_smscore_notifyees; - for (next = first->next; next != first;) - { - smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) next; + for (next = first->next; next != first;) { + struct smscore_device_notifyee_t *notifyee = + (struct smscore_device_notifyee_t *) next; next = next->next; - if (notifyee->hotplug == hotplug) - { + if (notifyee->hotplug == hotplug) { list_del(¬ifyee->entry); kfree(notifyee); } @@ -249,30 +282,30 @@ void smscore_unregister_hotplug(hotplug_t hotplug) kmutex_unlock(&g_smscore_deviceslock); } -void smscore_notify_clients(smscore_device_t *coredev) +static void smscore_notify_clients(struct smscore_device_t *coredev) { - smscore_client_t* client; + struct smscore_client_t *client; - // the client must call smscore_unregister_client from remove handler - while (!list_empty(&coredev->clients)) - { - client = (smscore_client_t *) coredev->clients.next; + /* the client must call smscore_unregister_client from remove handler */ + while (!list_empty(&coredev->clients)) { + client = (struct smscore_client_t *) coredev->clients.next; client->onremove_handler(client->context); } } -int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, int arrival) +static int smscore_notify_callbacks(struct smscore_device_t *coredev, + struct device *device, int arrival) { struct list_head *next, *first; int rc = 0; - // note: must be called under g_deviceslock + /* note: must be called under g_deviceslock */ first = &g_smscore_notifyees; - for (next = first->next; next != first; next = next->next) - { - rc = ((smscore_device_notifyee_t *) next)->hotplug(coredev, device, arrival); + for (next = first->next; next != first; next = next->next) { + rc = ((struct smscore_device_notifyee_t *) next)-> + hotplug(coredev, device, arrival); if (rc < 0) break; } @@ -280,56 +313,58 @@ int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, i return rc; } -smscore_buffer_t *smscore_createbuffer(u8* buffer, void* common_buffer, dma_addr_t common_buffer_phys) +static struct +smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, + dma_addr_t common_buffer_phys) { - smscore_buffer_t *cb = kmalloc(sizeof(smscore_buffer_t), GFP_KERNEL); - if (!cb) - { - printk(KERN_INFO "%s kmalloc(...) failed\n", __func__); + struct smscore_buffer_t *cb = + kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL); + if (!cb) { + sms_info("kmalloc(...) failed"); return NULL; } cb->p = buffer; - cb->offset_in_common = buffer - (u8*) common_buffer; + cb->offset_in_common = buffer - (u8 *) common_buffer; cb->phys = common_buffer_phys + cb->offset_in_common; return cb; } /** - * creates coredev object for a device, prepares buffers, creates buffer mappings, notifies - * registered hotplugs about new device. + * creates coredev object for a device, prepares buffers, + * creates buffer mappings, notifies registered hotplugs about new device. * - * @param params device pointer to struct with device specific parameters and handlers + * @param params device pointer to struct with device specific parameters + * and handlers * @param coredev pointer to a value that receives created coredev object * * @return 0 on success, <0 on error. */ -int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev) +int smscore_register_device(struct smsdevice_params_t *params, + struct smscore_device_t **coredev) { - smscore_device_t* dev; + struct smscore_device_t *dev; u8 *buffer; - dev = kzalloc(sizeof(smscore_device_t), GFP_KERNEL); - if (!dev) - { - printk(KERN_INFO "%s kzalloc(...) failed\n", __func__); + dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL); + if (!dev) { + sms_info("kzalloc(...) failed"); return -ENOMEM; } - // init list entry so it could be safe in smscore_unregister_device + /* init list entry so it could be safe in smscore_unregister_device */ INIT_LIST_HEAD(&dev->entry); - // init queues + /* init queues */ INIT_LIST_HEAD(&dev->clients); - INIT_LIST_HEAD(&dev->subclients); INIT_LIST_HEAD(&dev->buffers); - // init locks + /* init locks */ spin_lock_init(&dev->clientslock); spin_lock_init(&dev->bufferslock); - // init completion events + /* init completion events */ init_completion(&dev->version_ex_done); init_completion(&dev->data_download_done); init_completion(&dev->trigger_done); @@ -337,21 +372,24 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored init_completion(&dev->reload_start_done); init_completion(&dev->resume_done); - // alloc common buffer + /* alloc common buffer */ dev->common_buffer_size = params->buffer_size * params->num_buffers; - dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, &dev->common_buffer_phys, GFP_KERNEL | GFP_DMA); - if (!dev->common_buffer) - { + dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, + &dev->common_buffer_phys, + GFP_KERNEL | GFP_DMA); + if (!dev->common_buffer) { smscore_unregister_device(dev); return -ENOMEM; } - // prepare dma buffers - for (buffer = dev->common_buffer; dev->num_buffers < params->num_buffers; dev->num_buffers ++, buffer += params->buffer_size) - { - smscore_buffer_t *cb = smscore_createbuffer(buffer, dev->common_buffer, dev->common_buffer_phys); - if (!cb) - { + /* prepare dma buffers */ + for (buffer = dev->common_buffer; + dev->num_buffers < params->num_buffers; + dev->num_buffers++, buffer += params->buffer_size) { + struct smscore_buffer_t *cb = + smscore_createbuffer(buffer, dev->common_buffer, + dev->common_buffer_phys); + if (!cb) { smscore_unregister_device(dev); return -ENOMEM; } @@ -359,7 +397,7 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored smscore_putbuffer(dev, cb); } - printk(KERN_INFO "%s allocated %d buffers\n", __func__, dev->num_buffers); + sms_info("allocated %d buffers", dev->num_buffers); dev->mode = DEVICE_MODE_NONE; dev->context = params->context; @@ -373,14 +411,16 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored dev->device_flags = params->flags; strcpy(dev->devpath, params->devpath); - // add device to devices list + smscore_registry_settype(dev->devpath, params->device_type); + + /* add device to devices list */ kmutex_lock(&g_smscore_deviceslock); list_add(&dev->entry, &g_smscore_devices); kmutex_unlock(&g_smscore_deviceslock); *coredev = dev; - printk(KERN_INFO "%s device %p created\n", __func__, dev); + sms_info("device %p created", dev); return 0; } @@ -388,118 +428,148 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored /** * sets initial device mode and notifies client hotplugs that device is ready * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * * @return 0 on success, <0 on error. */ -int smscore_start_device(smscore_device_t *coredev) +int smscore_start_device(struct smscore_device_t *coredev) { - int rc = smscore_set_device_mode(coredev, smscore_registry_getmode(coredev->devpath)); - if (rc < 0) + int rc = smscore_set_device_mode( + coredev, smscore_registry_getmode(coredev->devpath)); + if (rc < 0) { + sms_info("set device mode faile , rc %d", rc); return rc; + } kmutex_lock(&g_smscore_deviceslock); rc = smscore_notify_callbacks(coredev, coredev->device, 1); - printk(KERN_INFO "%s device %p started, rc %d\n", __func__, coredev, rc); + sms_info("device %p started, rc %d", coredev, rc); kmutex_unlock(&g_smscore_deviceslock); return rc; } -int smscore_sendrequest_and_wait(smscore_device_t *coredev, void* buffer, size_t size, struct completion *completion) +static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, + void *buffer, size_t size, + struct completion *completion) { int rc = coredev->sendrequest_handler(coredev->context, buffer, size); - if (rc < 0) + if (rc < 0) { + sms_info("sendrequest returned error %d", rc); return rc; + } - return wait_for_completion_timeout(completion, msecs_to_jiffies(1000)) ? 0 : -ETIME; + return wait_for_completion_timeout(completion, + msecs_to_jiffies(10000)) ? + 0 : -ETIME; } -int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_t size) +static int smscore_load_firmware_family2(struct smscore_device_t *coredev, + void *buffer, size_t size) { - SmsFirmware_ST* firmware = (SmsFirmware_ST*) buffer; - SmsMsgHdr_ST *msg; - UINT32 mem_address = firmware->StartAddress; - u8* payload = firmware->Payload; + struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; + struct SmsMsgHdr_ST *msg; + u32 mem_address = firmware->StartAddress; + u8 *payload = firmware->Payload; int rc = 0; - if (coredev->preload_handler) - { + sms_info("loading FW to addr 0x%x size %d", + mem_address, firmware->Length); + if (coredev->preload_handler) { rc = coredev->preload_handler(coredev->context); if (rc < 0) return rc; } - // PAGE_SIZE buffer shall be enough and dma aligned - msg = (SmsMsgHdr_ST *) kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); + /* PAGE_SIZE buffer shall be enough and dma aligned */ + msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); if (!msg) return -ENOMEM; - if (coredev->mode != DEVICE_MODE_NONE) - { - SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, sizeof(SmsMsgHdr_ST)); - rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->reload_start_done); - mem_address = *(UINT32*) &payload[20]; + if (coredev->mode != DEVICE_MODE_NONE) { + sms_debug("sending reload command."); + SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, + sizeof(struct SmsMsgHdr_ST)); + rc = smscore_sendrequest_and_wait(coredev, msg, + msg->msgLength, + &coredev->reload_start_done); + mem_address = *(u32 *) &payload[20]; } - while (size && rc >= 0) - { - SmsDataDownload_ST *DataMsg = (SmsDataDownload_ST *) msg; + while (size && rc >= 0) { + struct SmsDataDownload_ST *DataMsg = + (struct SmsDataDownload_ST *) msg; int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); - SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, (UINT16)(sizeof(SmsMsgHdr_ST) + sizeof(UINT32) + payload_size)); + SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, + (u16)(sizeof(struct SmsMsgHdr_ST) + + sizeof(u32) + payload_size)); DataMsg->MemAddr = mem_address; memcpy(DataMsg->Payload, payload, payload_size); - if (coredev->device_flags & SMS_ROM_NO_RESPONSE && coredev->mode == DEVICE_MODE_NONE) - rc = coredev->sendrequest_handler(coredev->context, DataMsg, DataMsg->xMsgHeader.msgLength); + if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) && + (coredev->mode == DEVICE_MODE_NONE)) + rc = coredev->sendrequest_handler( + coredev->context, DataMsg, + DataMsg->xMsgHeader.msgLength); else - rc = smscore_sendrequest_and_wait(coredev, DataMsg, DataMsg->xMsgHeader.msgLength, &coredev->data_download_done); + rc = smscore_sendrequest_and_wait( + coredev, DataMsg, + DataMsg->xMsgHeader.msgLength, + &coredev->data_download_done); payload += payload_size; size -= payload_size; mem_address += payload_size; } - if (rc >= 0) - { - if (coredev->mode == DEVICE_MODE_NONE) - { - SmsMsgData_ST* TriggerMsg = (SmsMsgData_ST*) msg; - - SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sizeof(SmsMsgHdr_ST) + sizeof(UINT32) * 5); - - TriggerMsg->msgData[0] = firmware->StartAddress; // Entry point - TriggerMsg->msgData[1] = 5; // Priority - TriggerMsg->msgData[2] = 0x200; // Stack size - TriggerMsg->msgData[3] = 0; // Parameter - TriggerMsg->msgData[4] = 4; // Task ID - - if (coredev->device_flags & SMS_ROM_NO_RESPONSE) - { - rc = coredev->sendrequest_handler(coredev->context, TriggerMsg, TriggerMsg->xMsgHeader.msgLength); + if (rc >= 0) { + if (coredev->mode == DEVICE_MODE_NONE) { + struct SmsMsgData_ST *TriggerMsg = + (struct SmsMsgData_ST *) msg; + + SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, + sizeof(struct SmsMsgHdr_ST) + + sizeof(u32) * 5); + + TriggerMsg->msgData[0] = firmware->StartAddress; + /* Entry point */ + TriggerMsg->msgData[1] = 5; /* Priority */ + TriggerMsg->msgData[2] = 0x200; /* Stack size */ + TriggerMsg->msgData[3] = 0; /* Parameter */ + TriggerMsg->msgData[4] = 4; /* Task ID */ + + if (coredev->device_flags & SMS_ROM_NO_RESPONSE) { + rc = coredev->sendrequest_handler( + coredev->context, TriggerMsg, + TriggerMsg->xMsgHeader.msgLength); msleep(100); - } - else - rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done); - } - else - { - SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, sizeof(SmsMsgHdr_ST)); - - rc = coredev->sendrequest_handler(coredev->context, msg, msg->msgLength); + } else + rc = smscore_sendrequest_and_wait( + coredev, TriggerMsg, + TriggerMsg->xMsgHeader.msgLength, + &coredev->trigger_done); + } else { + SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, + sizeof(struct SmsMsgHdr_ST)); + + rc = coredev->sendrequest_handler(coredev->context, + msg, msg->msgLength); } + msleep(500); } - printk("%s %d \n", __func__, rc); + sms_debug("rc=%d, postload=%p ", rc, + coredev->postload_handler); kfree(msg); - return (rc >= 0 && coredev->postload_handler) ? + return ((rc >= 0) && coredev->postload_handler) ? coredev->postload_handler(coredev->context) : rc; } @@ -507,43 +577,46 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_ /** * loads specified firmware into a buffer and calls device loadfirmware_handler * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * @param filename null-terminated string specifies firmware file name * @param loadfirmware_handler device handler that loads firmware * * @return 0 on success, <0 on error. */ -int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler) +static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, + char *filename, + loadfirmware_t loadfirmware_handler) { int rc = -ENOENT; - const struct firmware *fw; - u8* fw_buffer; + u8 *fw_buffer; - if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2)) + if (loadfirmware_handler == NULL && !(coredev->device_flags & + SMS_DEVICE_FAMILY2)) return -EINVAL; rc = request_firmware(&fw, filename, coredev->device); - if (rc < 0) - { - printk(KERN_INFO "%s failed to open \"%s\"\n", __func__, filename); + if (rc < 0) { + sms_info("failed to open \"%s\"", filename); return rc; } - - fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); - if (fw_buffer) - { + sms_info("read FW %s, size=%zd", filename, fw->size); + fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), + GFP_KERNEL | GFP_DMA); + if (fw_buffer) { memcpy(fw_buffer, fw->data, fw->size); rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? - smscore_load_firmware_family2(coredev, fw_buffer, fw->size) : - loadfirmware_handler(coredev->context, fw_buffer, fw->size); + smscore_load_firmware_family2(coredev, + fw_buffer, + fw->size) : + loadfirmware_handler(coredev->context, + fw_buffer, fw->size); kfree(fw_buffer); - } - else - { - printk(KERN_INFO "%s failed to allocate firmware buffer\n", __func__); + } else { + sms_info("failed to allocate firmware buffer"); rc = -ENOMEM; } @@ -553,78 +626,89 @@ int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmwar } /** - * notifies all clients registered with the device, notifies hotplugs, frees all buffers and coredev object + * notifies all clients registered with the device, notifies hotplugs, + * frees all buffers and coredev object * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * * @return 0 on success, <0 on error. */ -void smscore_unregister_device(smscore_device_t *coredev) +void smscore_unregister_device(struct smscore_device_t *coredev) { - smscore_buffer_t *cb; + struct smscore_buffer_t *cb; int num_buffers = 0; + int retry = 0; kmutex_lock(&g_smscore_deviceslock); smscore_notify_clients(coredev); smscore_notify_callbacks(coredev, NULL, 0); - // at this point all buffers should be back - // onresponse must no longer be called + /* at this point all buffers should be back + * onresponse must no longer be called */ - while (1) - { - while ((cb = smscore_getbuffer(coredev))) - { + while (1) { + while ((cb = smscore_getbuffer(coredev))) { kfree(cb); - num_buffers ++; + num_buffers++; } - if (num_buffers == coredev->num_buffers) break; + if (++retry > 10) { + sms_info("exiting although " + "not all buffers released."); + break; + } - printk(KERN_INFO "%s waiting for %d buffer(s)\n", __func__, coredev->num_buffers - num_buffers); + sms_info("waiting for %d buffer(s)", + coredev->num_buffers - num_buffers); msleep(100); } - printk(KERN_INFO "%s freed %d buffers\n", __func__, num_buffers); + sms_info("freed %d buffers", num_buffers); if (coredev->common_buffer) - dma_free_coherent(NULL, coredev->common_buffer_size, coredev->common_buffer, coredev->common_buffer_phys); + dma_free_coherent(NULL, coredev->common_buffer_size, + coredev->common_buffer, + coredev->common_buffer_phys); list_del(&coredev->entry); kfree(coredev); kmutex_unlock(&g_smscore_deviceslock); - printk(KERN_INFO "%s device %p destroyed\n", __func__, coredev); + sms_info("device %p destroyed", coredev); } -int smscore_detect_mode(smscore_device_t *coredev) +static int smscore_detect_mode(struct smscore_device_t *coredev) { - void *buffer = kmalloc(sizeof(SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); - SmsMsgHdr_ST *msg = (SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer); + void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, + GFP_KERNEL | GFP_DMA); + struct SmsMsgHdr_ST *msg = + (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer); int rc; if (!buffer) return -ENOMEM; - SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, sizeof(SmsMsgHdr_ST)); + SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, + sizeof(struct SmsMsgHdr_ST)); - rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); - if (rc == -ETIME) - { - printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", __func__); + rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, + &coredev->version_ex_done); + if (rc == -ETIME) { + sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try"); - if (wait_for_completion_timeout(&coredev->resume_done, msecs_to_jiffies(5000))) - { - rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); + if (wait_for_completion_timeout(&coredev->resume_done, + msecs_to_jiffies(5000))) { + rc = smscore_sendrequest_and_wait( + coredev, msg, msg->msgLength, + &coredev->version_ex_done); if (rc < 0) - { - printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n", __func__, rc); - } - } - else + sms_err("MSG_SMS_GET_VERSION_EX_REQ failed " + "second try, rc %d", rc); + } else rc = -ETIME; } @@ -633,160 +717,199 @@ int smscore_detect_mode(smscore_device_t *coredev) return rc; } -char *smscore_fw_lkup[] = -{ - "dvb_nova_12mhz.inp", - "dvb_nova_12mhz.inp", - "tdmb_nova.inp", - "none", - "dvb_nova_12mhz.inp", - "isdbt_nova_12mhz.inp", - "isdbt_nova_12mhz.inp", - "cmmb_nova_12mhz.inp", - "none", +static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { + /*Stellar NOVA A0 Nova B0 VEGA*/ + /*DVBT*/ + {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*DVBH*/ + {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*TDMB*/ + {"none", "tdmb_nova_12mhz.inp", "none", "none"}, + /*DABIP*/ + {"none", "none", "none", "none"}, + /*BDA*/ + {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*ISDBT*/ + {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"}, + /*ISDBTBDA*/ + {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, + /*CMMB*/ + {"none", "none", "none", "cmmb_vega_12mhz.inp"} }; +static inline char *sms_get_fw_name(struct smscore_device_t *coredev, + int mode, enum sms_device_type_st type) +{ + char **fw = sms_get_board(smscore_get_board_id(coredev))->fw; + return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type]; +} + /** * calls device handler to change mode of operation * NOTE: stellar/usb may disconnect when changing mode * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * @param mode requested mode of operation * * @return 0 on success, <0 on error. */ -int smscore_set_device_mode(smscore_device_t *coredev, int mode) +int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) { void *buffer; int rc = 0; + enum sms_device_type_st type; - if (coredev->device_flags & SMS_DEVICE_FAMILY2) - { - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) - { - printk(KERN_INFO "%s invalid mode specified %d\n", __func__, mode); + sms_debug("set device mode to %d", mode); + if (coredev->device_flags & SMS_DEVICE_FAMILY2) { + if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) { + sms_err("invalid mode specified %d", mode); return -EINVAL; } - if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) - { + smscore_registry_setmode(coredev->devpath, mode); + + if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) { rc = smscore_detect_mode(coredev); - if (rc < 0) + if (rc < 0) { + sms_err("mode detect failed %d", rc); return rc; + } } - if (coredev->mode == mode) - { - printk(KERN_INFO "%s device mode %d already set\n", __func__, mode); + if (coredev->mode == mode) { + sms_info("device mode %d already set", mode); return 0; } - if (!(coredev->modes_supported & (1 << mode))) - { - rc = smscore_load_firmware(coredev, smscore_fw_lkup[mode], NULL); - if (rc < 0) - return rc; - } - else - { - printk(KERN_INFO "%s mode %d supported by running firmware\n", __func__, mode); - } - - buffer = kmalloc(sizeof(SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); - if (buffer) - { - SmsMsgData_ST *msg = (SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); - - SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(SmsMsgData_ST)); + if (!(coredev->modes_supported & (1 << mode))) { + char *fw_filename; + + type = smscore_registry_gettype(coredev->devpath); + fw_filename = sms_get_fw_name(coredev, mode, type); + + rc = smscore_load_firmware_from_file(coredev, + fw_filename, NULL); + if (rc < 0) { + sms_warn("error %d loading firmware: %s, " + "trying again with default firmware", + rc, fw_filename); + + /* try again with the default firmware */ + fw_filename = smscore_fw_lkup[mode][type]; + rc = smscore_load_firmware_from_file(coredev, + fw_filename, NULL); + + if (rc < 0) { + sms_warn("error %d loading " + "firmware: %s", rc, + fw_filename); + return rc; + } + } + sms_log("firmware download success: %s", fw_filename); + } else + sms_info("mode %d supported by running " + "firmware", mode); + + buffer = kmalloc(sizeof(struct SmsMsgData_ST) + + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); + if (buffer) { + struct SmsMsgData_ST *msg = + (struct SmsMsgData_ST *) + SMS_ALIGN_ADDRESS(buffer); + + SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, + sizeof(struct SmsMsgData_ST)); msg->msgData[0] = mode; - rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done); + rc = smscore_sendrequest_and_wait( + coredev, msg, msg->xMsgHeader.msgLength, + &coredev->init_device_done); kfree(buffer); - } - else + } else { + sms_err("Could not allocate buffer for " + "init device message."); rc = -ENOMEM; - } - else - { + } + } else { + if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { + sms_err("invalid mode specified %d", mode); + return -EINVAL; + } + + smscore_registry_setmode(coredev->devpath, mode); + if (coredev->detectmode_handler) - coredev->detectmode_handler(coredev->context, &coredev->mode); + coredev->detectmode_handler(coredev->context, + &coredev->mode); if (coredev->mode != mode && coredev->setmode_handler) rc = coredev->setmode_handler(coredev->context, mode); } - smscore_registry_setmode(coredev->devpath, mode); - - if (rc >= 0) - { + if (rc >= 0) { coredev->mode = mode; coredev->device_flags &= ~SMS_DEVICE_NOT_READY; } + if (rc != 0) + sms_err("return error code %d.", rc); return rc; } /** * calls device handler to get current mode of operation * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * * @return current mode */ -int smscore_get_device_mode(smscore_device_t *coredev) +int smscore_get_device_mode(struct smscore_device_t *coredev) { return coredev->mode; } -smscore_client_t* smscore_getclient_by_type(smscore_device_t *coredev, int data_type) +/** + * find client by response id & type within the clients list. + * return client handle or NULL. + * + * @param coredev pointer to a coredev object returned by + * smscore_register_device + * @param data_type client data type (SMS_DONT_CARE for all types) + * @param id client id (SMS_DONT_CARE for all id) + * + */ +static struct +smscore_client_t *smscore_find_client(struct smscore_device_t *coredev, + int data_type, int id) { - smscore_client_t *client = NULL; + struct smscore_client_t *client = NULL; struct list_head *next, *first; unsigned long flags; + struct list_head *firstid, *nextid; - if (!data_type) - return NULL; spin_lock_irqsave(&coredev->clientslock, flags); - first = &coredev->clients; - - for (next = first->next; next != first; next = next->next) - { - if (((smscore_client_t*) next)->data_type == data_type) - { - client = (smscore_client_t*) next; - break; - } - } - - spin_unlock_irqrestore(&coredev->clientslock, flags); - - return client; -} - -smscore_client_t* smscore_getclient_by_id(smscore_device_t *coredev, int id) -{ - smscore_client_t *client = NULL; - struct list_head *next, *first; - unsigned long flags; - - spin_lock_irqsave(&coredev->clientslock, flags); - - first = &coredev->subclients; - - for (next = first->next; next != first; next = next->next) - { - if (((smscore_subclient_t*) next)->id == id) - { - client = ((smscore_subclient_t*) next)->client; - break; + for (next = first->next; + (next != first) && !client; + next = next->next) { + firstid = &((struct smscore_client_t *)next)->idlist; + for (nextid = firstid->next; + nextid != firstid; + nextid = nextid->next) { + if ((((struct smscore_idlist_t *)nextid)->id == id) && + (((struct smscore_idlist_t *)nextid)->data_type == data_type || + (((struct smscore_idlist_t *)nextid)->data_type == 0))) { + client = (struct smscore_client_t *) next; + break; + } } } - spin_unlock_irqrestore(&coredev->clientslock, flags); - return client; } @@ -794,86 +917,84 @@ smscore_client_t* smscore_getclient_by_id(smscore_device_t *coredev, int id) * find client by response id/type, call clients onresponse handler * return buffer to pool on error * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * @param cb pointer to response buffer descriptor * */ -void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) +void smscore_onresponse(struct smscore_device_t *coredev, + struct smscore_buffer_t *cb) { - SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8*) cb->p + cb->offset); - smscore_client_t * client = smscore_getclient_by_type(coredev, phdr->msgType); + struct SmsMsgHdr_ST *phdr = + (struct SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset); + struct smscore_client_t *client = + smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); int rc = -EBUSY; - static unsigned long last_sample_time = 0; - static int data_total = 0; + static unsigned long last_sample_time; /* = 0; */ + static int data_total; /* = 0; */ unsigned long time_now = jiffies_to_msecs(jiffies); if (!last_sample_time) last_sample_time = time_now; - if (time_now - last_sample_time > 10000) - { - printk("\n%s data rate %d bytes/secs\n", __func__, (int)((data_total * 1000) / (time_now - last_sample_time))); + if (time_now - last_sample_time > 10000) { + sms_debug("\ndata rate %d bytes/secs", + (int)((data_total * 1000) / + (time_now - last_sample_time))); last_sample_time = time_now; data_total = 0; } data_total += cb->size; - - if (!client) - client = smscore_getclient_by_id(coredev, phdr->msgDstId); - + /* If no client registered for type & id, + * check for control client where type is not registered */ if (client) rc = client->onresponse_handler(client->context, cb); - if (rc < 0) - { - switch (phdr->msgType) + if (rc < 0) { + switch (phdr->msgType) { + case MSG_SMS_GET_VERSION_EX_RES: { - case MSG_SMS_GET_VERSION_EX_RES: - { - SmsVersionRes_ST *ver = (SmsVersionRes_ST*) phdr; - printk("%s: MSG_SMS_GET_VERSION_EX_RES id %d prots 0x%x ver %d.%d\n", __func__, ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor); - - coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId; - coredev->modes_supported = ver->SupportedProtocols; - - complete(&coredev->version_ex_done); - break; - } - - case MSG_SMS_INIT_DEVICE_RES: - printk("%s: MSG_SMS_INIT_DEVICE_RES\n", __func__); - complete(&coredev->init_device_done); - break; - - case MSG_SW_RELOAD_START_RES: - printk("%s: MSG_SW_RELOAD_START_RES\n", __func__); - complete(&coredev->reload_start_done); - break; - - case MSG_SMS_DATA_DOWNLOAD_RES: - complete(&coredev->data_download_done); - break; - - case MSG_SW_RELOAD_EXEC_RES: - printk("%s: MSG_SW_RELOAD_EXEC_RES\n", __func__); - break; - - case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: - printk("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", __func__); - complete(&coredev->trigger_done); - break; - - case MSG_SMS_SLEEP_RESUME_COMP_IND: - complete(&coredev->resume_done); - break; - - default: - printk(KERN_INFO "%s no client (%p) or error (%d), type:%d dstid:%d\n", __func__, client, rc, phdr->msgType, phdr->msgDstId); + struct SmsVersionRes_ST *ver = + (struct SmsVersionRes_ST *) phdr; + sms_debug("MSG_SMS_GET_VERSION_EX_RES " + "id %d prots 0x%x ver %d.%d", + ver->FirmwareId, ver->SupportedProtocols, + ver->RomVersionMajor, ver->RomVersionMinor); + + coredev->mode = ver->FirmwareId == 255 ? + DEVICE_MODE_NONE : ver->FirmwareId; + coredev->modes_supported = ver->SupportedProtocols; + + complete(&coredev->version_ex_done); + break; + } + case MSG_SMS_INIT_DEVICE_RES: + sms_debug("MSG_SMS_INIT_DEVICE_RES"); + complete(&coredev->init_device_done); + break; + case MSG_SW_RELOAD_START_RES: + sms_debug("MSG_SW_RELOAD_START_RES"); + complete(&coredev->reload_start_done); + break; + case MSG_SMS_DATA_DOWNLOAD_RES: + complete(&coredev->data_download_done); + break; + case MSG_SW_RELOAD_EXEC_RES: + sms_debug("MSG_SW_RELOAD_EXEC_RES"); + break; + case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: + sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES"); + complete(&coredev->trigger_done); + break; + case MSG_SMS_SLEEP_RESUME_COMP_IND: + complete(&coredev->resume_done); + break; + default: + break; } - smscore_putbuffer(coredev, cb); } } @@ -881,20 +1002,20 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) /** * return pointer to next free buffer descriptor from core pool * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * * @return pointer to descriptor on success, NULL on error. */ -smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev) +struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) { - smscore_buffer_t *cb = NULL; + struct smscore_buffer_t *cb = NULL; unsigned long flags; spin_lock_irqsave(&coredev->bufferslock, flags); - if (!list_empty(&coredev->buffers)) - { - cb = (smscore_buffer_t *) coredev->buffers.next; + if (!list_empty(&coredev->buffers)) { + cb = (struct smscore_buffer_t *) coredev->buffers.next; list_del(&cb->entry); } @@ -906,39 +1027,45 @@ smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev) /** * return buffer descriptor to a pool * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * @param cb pointer buffer descriptor * */ -void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb) +void smscore_putbuffer(struct smscore_device_t *coredev, + struct smscore_buffer_t *cb) { list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); } -int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, int id) +static int smscore_validate_client(struct smscore_device_t *coredev, + struct smscore_client_t *client, + int data_type, int id) { - smscore_client_t *existing_client; - smscore_subclient_t *subclient; + struct smscore_idlist_t *listentry; + struct smscore_client_t *registered_client; - if (!id) - return 0; - - existing_client = smscore_getclient_by_id(coredev, id); - if (existing_client == client) + if (!client) { + sms_err("bad parameter."); + return -EFAULT; + } + registered_client = smscore_find_client(coredev, data_type, id); + if (registered_client == client) return 0; - if (existing_client) - return -EBUSY; - - subclient = kzalloc(sizeof(smscore_subclient_t), GFP_KERNEL); - if (!subclient) + if (registered_client) { + sms_err("The msg ID already registered to another client."); + return -EEXIST; + } + listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL); + if (!listentry) { + sms_err("Can't allocate memory for client id."); return -ENOMEM; - - subclient->client = client; - subclient->id = id; - - list_add_locked(&subclient->entry, &coredev->subclients, &coredev->clientslock); - + } + listentry->id = id; + listentry->data_type = data_type; + list_add_locked(&listentry->entry, &client->idlist, + &coredev->clientslock); return 0; } @@ -948,45 +1075,44 @@ int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, * @param coredev pointer to a coredev object from clients hotplug * @param initial_id all messages with this id would be sent to this client * @param data_type all messages of this type would be sent to this client - * @param onresponse_handler client handler that is called to process incoming messages + * @param onresponse_handler client handler that is called to + * process incoming messages * @param onremove_handler client handler that is called when device is removed * @param context client-specific context * @param client pointer to a value that receives created smsclient object * * @return 0 on success, <0 on error. */ -int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *params, smscore_client_t **client) +int smscore_register_client(struct smscore_device_t *coredev, + struct smsclient_params_t *params, + struct smscore_client_t **client) { - smscore_client_t* newclient; - int rc; - - // check that no other channel with same data type exists - if (params->data_type && smscore_getclient_by_type(coredev, params->data_type)) + struct smscore_client_t *newclient; + /* check that no other channel with same parameters exists */ + if (smscore_find_client(coredev, params->data_type, + params->initial_id)) { + sms_err("Client already exist."); return -EEXIST; + } - newclient = kzalloc(sizeof(smscore_client_t), GFP_KERNEL); - if (!newclient) + newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL); + if (!newclient) { + sms_err("Failed to allocate memory for client."); return -ENOMEM; - - // check that no other channel with same id exists - rc = smscore_validate_client(coredev, newclient, params->initial_id); - if (rc < 0) - { - kfree(newclient); - return rc; } + INIT_LIST_HEAD(&newclient->idlist); newclient->coredev = coredev; - newclient->data_type = params->data_type; newclient->onresponse_handler = params->onresponse_handler; newclient->onremove_handler = params->onremove_handler; newclient->context = params->context; - - list_add_locked(&newclient->entry, &coredev->clients, &coredev->clientslock); - + list_add_locked(&newclient->entry, &coredev->clients, + &coredev->clientslock); + smscore_validate_client(coredev, newclient, params->data_type, + params->initial_id); *client = newclient; - - printk(KERN_INFO "%s %p %d %d\n", __func__, params->context, params->data_type, params->initial_id); + sms_debug("%p %d %d", params->context, params->data_type, + params->initial_id); return 0; } @@ -994,32 +1120,26 @@ int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *param /** * frees smsclient object and all subclients associated with it * - * @param client pointer to smsclient object returned by smscore_register_client + * @param client pointer to smsclient object returned by + * smscore_register_client * */ -void smscore_unregister_client(smscore_client_t *client) +void smscore_unregister_client(struct smscore_client_t *client) { - smscore_device_t *coredev = client->coredev; - struct list_head *next, *first; + struct smscore_device_t *coredev = client->coredev; unsigned long flags; spin_lock_irqsave(&coredev->clientslock, flags); - first = &coredev->subclients; - - for (next = first->next; next != first;) - { - smscore_subclient_t *subclient = (smscore_subclient_t *) next; - next = next->next; - if (subclient->client == client) - { - list_del(&subclient->entry); - kfree(subclient); - } + while (!list_empty(&client->idlist)) { + struct smscore_idlist_t *identry = + (struct smscore_idlist_t *) client->idlist.next; + list_del(&identry->entry); + kfree(identry); } - printk(KERN_INFO "%s %p %d\n", __func__, client->context, client->data_type); + sms_info("%p", client->context); list_del(&client->entry); kfree(client); @@ -1031,71 +1151,43 @@ void smscore_unregister_client(smscore_client_t *client) * verifies that source id is not taken by another client, * calls device handler to send requests to the device * - * @param client pointer to smsclient object returned by smscore_register_client + * @param client pointer to smsclient object returned by + * smscore_register_client * @param buffer pointer to a request buffer * @param size size (in bytes) of request buffer * * @return 0 on success, <0 on error. */ -int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size) +int smsclient_sendrequest(struct smscore_client_t *client, + void *buffer, size_t size) { - smscore_device_t* coredev = client->coredev; - SmsMsgHdr_ST* phdr = (SmsMsgHdr_ST*) buffer; - - // check that no other channel with same id exists - int rc = smscore_validate_client(client->coredev, client, phdr->msgSrcId); - if (rc < 0) - return rc; - - return coredev->sendrequest_handler(coredev->context, buffer, size); -} - -/** - * return the size of large (common) buffer - * - * @param coredev pointer to a coredev object from clients hotplug - * - * @return size (in bytes) of the buffer - */ -int smscore_get_common_buffer_size(smscore_device_t *coredev) -{ - return coredev->common_buffer_size; -} - -/** - * maps common buffer (if supported by platform) - * - * @param coredev pointer to a coredev object from clients hotplug - * @param vma pointer to vma struct from mmap handler - * - * @return 0 on success, <0 on error. - */ -int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * vma) -{ - unsigned long end = vma->vm_end, start = vma->vm_start, size = PAGE_ALIGN(coredev->common_buffer_size); + struct smscore_device_t *coredev; + struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer; + int rc; - if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || (vma->vm_flags & VM_WRITE)) - { - printk(KERN_INFO "%s invalid vm flags\n", __func__); + if (client == NULL) { + sms_err("Got NULL client"); return -EINVAL; } - if ((end - start) != size) - { - printk(KERN_INFO "%s invalid size %d expected %d\n", __func__, (int)(end - start), (int) size); + coredev = client->coredev; + + /* check that no other channel with same id exists */ + if (coredev == NULL) { + sms_err("Got NULL coredev"); return -EINVAL; } - if (remap_pfn_range(vma, start, coredev->common_buffer_phys >> PAGE_SHIFT, size, pgprot_noncached(vma->vm_page_prot))) - { - printk(KERN_INFO "%s remap_page_range failed\n", __func__); - return -EAGAIN; - } + rc = smscore_validate_client(client->coredev, client, 0, + phdr->msgSrcId); + if (rc < 0) + return rc; - return 0; + return coredev->sendrequest_handler(coredev->context, buffer, size); } -int smscore_module_init(void) + +static int __init smscore_module_init(void) { int rc = 0; @@ -1112,18 +1204,19 @@ int smscore_module_init(void) /* DVB Register */ rc = smsdvb_register(); - printk(KERN_INFO "%s, rc %d\n", __func__, rc); + sms_debug("rc %d", rc); return rc; } -void smscore_module_exit(void) +static void __exit smscore_module_exit(void) { kmutex_lock(&g_smscore_deviceslock); - while (!list_empty(&g_smscore_notifyees)) - { - smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) g_smscore_notifyees.next; + while (!list_empty(&g_smscore_notifyees)) { + struct smscore_device_notifyee_t *notifyee = + (struct smscore_device_notifyee_t *) + g_smscore_notifyees.next; list_del(¬ifyee->entry); kfree(notifyee); @@ -1131,9 +1224,10 @@ void smscore_module_exit(void) kmutex_unlock(&g_smscore_deviceslock); kmutex_lock(&g_smscore_registrylock); - while (!list_empty(&g_smscore_registry)) - { - smscore_registry_entry_t *entry = (smscore_registry_entry_t *) g_smscore_registry.next; + while (!list_empty(&g_smscore_registry)) { + struct smscore_registry_entry_t *entry = + (struct smscore_registry_entry_t *) + g_smscore_registry.next; list_del(&entry->entry); kfree(entry); @@ -1146,13 +1240,12 @@ void smscore_module_exit(void) /* Unregister USB */ smsusb_unregister(); - printk(KERN_INFO "%s\n", __func__); + sms_debug(""); } module_init(smscore_module_init); module_exit(smscore_module_exit); -MODULE_DESCRIPTION("smscore"); -MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); +MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); +MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)"); MODULE_LICENSE("GPL"); -