static int rpavscsi_reset_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata) { int rc = 0; struct vio_dev *vdev = to_vio_dev(hostdata->dev); do { if (rc) msleep(100); rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); memset(queue->msgs, 0x00, PAGE_SIZE); queue->cur = 0; set_adapter_info(hostdata); rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, queue->msg_token, PAGE_SIZE); if (rc == 2) { dev_warn(hostdata->dev, "Partner adapter not ready\n"); } else if (rc != 0) { dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc); } return rc; }
/** * reset_crq_queue: - resets a crq after a failure * @queue: crq_queue to initialize and register * @hostdata: ibmvscsi_host_data of host * */ int ibmvscsi_reset_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata) { int rc; struct vio_dev *vdev = to_vio_dev(hostdata->dev); /* Close the CRQ */ do { rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); /* Clean out the queue */ memset(queue->msgs, 0x00, PAGE_SIZE); queue->cur = 0; set_adapter_info(hostdata); /* And re-open it again */ rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, queue->msg_token, PAGE_SIZE); if (rc == 2) { /* Adapter is good, but other end is not ready */ printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n"); } else if (rc != 0) { printk(KERN_WARNING "ibmvscsi: couldn't register crq--rc 0x%x\n", rc); } return rc; }
static int ibmveth_close(struct net_device *netdev) { struct ibmveth_adapter *adapter = netdev_priv(netdev); long lpar_rc; ibmveth_debug_printk("close starting\n"); napi_disable(&adapter->napi); if (!adapter->pool_config) netif_stop_queue(netdev); free_irq(netdev->irq, netdev); do { lpar_rc = h_free_logical_lan(adapter->vdev->unit_address); } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY)); if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_free_logical_lan failed with %lx, continuing with close\n", lpar_rc); } adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8); ibmveth_cleanup(adapter); ibmveth_debug_printk("close complete\n"); return 0; }
static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter, union ibmveth_buf_desc rxq_desc, u64 mac_address) { int rc, try_again = 1; /* * After a kexec the adapter will still be open, so our attempt to * open it will fail. So if we get a failure we free the adapter and * try again, but only once. */ retry: rc = h_register_logical_lan(adapter->vdev->unit_address, adapter->buffer_list_dma, rxq_desc.desc, adapter->filter_list_dma, mac_address); if (rc != H_SUCCESS && try_again) { do { rc = h_free_logical_lan(adapter->vdev->unit_address); } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY)); try_again = 0; goto retry; } return rc; }
/** * tpm_ibmvtpm_resume - Resume from suspend * @dev: device struct * * Return value: * 0 */ static int tpm_ibmvtpm_resume(struct device *dev) { struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(dev); int rc = 0; do { if (rc) msleep(100); rc = plpar_hcall_norets(H_ENABLE_CRQ, ibmvtpm->vdev->unit_address); } while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc)); if (rc) { dev_err(dev, "Error enabling ibmvtpm rc=%d\n", rc); return rc; } rc = vio_enable_interrupts(ibmvtpm->vdev); if (rc) { dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc); return rc; } rc = ibmvtpm_crq_send_init(ibmvtpm); if (rc) dev_err(dev, "Error send_init rc=%d\n", rc); return rc; }
static long ehea_plpar_hcall_norets(unsigned long opcode, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long arg7) { long ret; int i, sleep_msecs; for (i = 0; i < 5; i++) { ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7); if (H_IS_LONG_BUSY(ret)) { sleep_msecs = get_longbusy_msecs(ret); msleep_interruptible(sleep_msecs); continue; } if (ret < H_SUCCESS) pr_err("opcode=%lx ret=%lx" " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" " arg5=%lx arg6=%lx arg7=%lx\n", opcode, ret, arg1, arg2, arg3, arg4, arg5, arg6, arg7); return ret; } return H_BUSY; }
static int ibmveth_close(struct net_device *netdev) { struct ibmveth_adapter *adapter = netdev_priv(netdev); long lpar_rc; netdev_dbg(netdev, "close starting\n"); napi_disable(&adapter->napi); if (!adapter->pool_config) netif_stop_queue(netdev); h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); do { lpar_rc = h_free_logical_lan(adapter->vdev->unit_address); } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY)); if (lpar_rc != H_SUCCESS) { netdev_err(netdev, "h_free_logical_lan failed with %lx, " "continuing with close\n", lpar_rc); } free_irq(netdev->irq, netdev); ibmveth_update_rx_no_buffer(adapter); ibmveth_cleanup(adapter); netdev_dbg(netdev, "close complete\n"); return 0; }
/** * tpm_ibmvtpm_remove - ibm vtpm remove entry point * @vdev: vio device struct * * Return value: * 0 */ static int tpm_ibmvtpm_remove(struct vio_dev *vdev) { struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev); int rc = 0; free_irq(vdev->irq, ibmvtpm); do { if (rc) msleep(100); rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); dma_unmap_single(ibmvtpm->dev, ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE, DMA_BIDIRECTIONAL); free_page((unsigned long)ibmvtpm->crq_queue.crq_addr); if (ibmvtpm->rtce_buf) { dma_unmap_single(ibmvtpm->dev, ibmvtpm->rtce_dma_handle, ibmvtpm->rtce_size, DMA_BIDIRECTIONAL); kfree(ibmvtpm->rtce_buf); } tpm_remove_hardware(ibmvtpm->dev); kfree(ibmvtpm); return 0; }
static long ehca_plpar_hcall9(unsigned long opcode, unsigned long *outs, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long arg7, unsigned long arg8, unsigned long arg9) { long ret; int i, sleep_msecs; unsigned long flags = 0; if (unlikely(ehca_debug_level >= 2)) ehca_gen_dbg("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT, opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); for (i = 0; i < 5; i++) { if (ehca_lock_hcalls) spin_lock_irqsave(&hcall_lock, flags); ret = plpar_hcall9(opcode, outs, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); if (ehca_lock_hcalls) spin_unlock_irqrestore(&hcall_lock, flags); if (H_IS_LONG_BUSY(ret)) { sleep_msecs = get_longbusy_msecs(ret); msleep_interruptible(sleep_msecs); continue; } if (ret < H_SUCCESS) { ehca_gen_err("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT, opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); ehca_gen_err("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT, ret, outs[0], outs[1], outs[2], outs[3], outs[4], outs[5], outs[6], outs[7], outs[8]); } else if (unlikely(ehca_debug_level >= 2)) ehca_gen_dbg("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT, ret, outs[0], outs[1], outs[2], outs[3], outs[4], outs[5], outs[6], outs[7], outs[8]); return ret; } return H_BUSY; }
static long ehca_plpar_hcall9(unsigned long opcode, unsigned long *outs, /* array of 9 outputs */ unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long arg7, unsigned long arg8, unsigned long arg9) { long ret; int i, sleep_msecs; ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx " "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx", opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); for (i = 0; i < 5; i++) { ret = plpar_hcall9(opcode, outs, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); if (H_IS_LONG_BUSY(ret)) { sleep_msecs = get_longbusy_msecs(ret); msleep_interruptible(sleep_msecs); continue; } if (ret < H_SUCCESS) ehca_gen_err("opcode=%lx ret=%lx" " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" " arg9=%lx" " out1=%lx out2=%lx out3=%lx out4=%lx" " out5=%lx out6=%lx out7=%lx out8=%lx" " out9=%lx", opcode, ret, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, outs[0], outs[1], outs[2], outs[3], outs[4], outs[5], outs[6], outs[7], outs[8]); ehca_gen_dbg("opcode=%lx ret=%lx out1=%lx out2=%lx out3=%lx " "out4=%lx out5=%lx out6=%lx out7=%lx out8=%lx " "out9=%lx", opcode, ret, outs[0], outs[1], outs[2], outs[3], outs[4], outs[5], outs[6], outs[7], outs[8]); return ret; } return H_BUSY; }
static long ehea_plpar_hcall9(unsigned long opcode, unsigned long *outs, /* array of 9 outputs */ unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long arg7, unsigned long arg8, unsigned long arg9) { long ret; int i, sleep_msecs; u8 cb_cat; for (i = 0; i < 5; i++) { ret = plpar_hcall9(opcode, outs, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); if (H_IS_LONG_BUSY(ret)) { sleep_msecs = get_longbusy_msecs(ret); msleep_interruptible(sleep_msecs); continue; } cb_cat = EHEA_BMASK_GET(H_MEHEAPORT_CAT, arg2); if ((ret < H_SUCCESS) && !(((ret == H_AUTHORITY) && (opcode == H_MODIFY_HEA_PORT)) && (((cb_cat == H_PORT_CB4) && ((arg3 == H_PORT_CB4_JUMBO) || (arg3 == H_PORT_CB4_SPEED))) || ((cb_cat == H_PORT_CB7) && (arg3 == H_PORT_CB7_DUCQPN))))) pr_err("opcode=%lx ret=%lx" " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" " arg9=%lx" " out1=%lx out2=%lx out3=%lx out4=%lx" " out5=%lx out6=%lx out7=%lx out8=%lx" " out9=%lx\n", opcode, ret, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, outs[0], outs[1], outs[2], outs[3], outs[4], outs[5], outs[6], outs[7], outs[8]); return ret; } return H_BUSY; }
/** * reenable_crq_queue: - reenables a crq after * @queue: crq_queue to initialize and register * @hostdata: ibmvscsi_host_data of host * */ int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata) { int rc; struct vio_dev *vdev = to_vio_dev(hostdata->dev); /* Re-enable the CRQ */ do { rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address); } while ((rc == H_IN_PROGRESS) || (rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); if (rc) printk(KERN_ERR "ibmvscsi: Error %d enabling adapter\n", rc); return rc; }
/** * release_crq_queue: - Deallocates data and unregisters CRQ * @queue: crq_queue to initialize and register * @host_data: ibmvscsi_host_data of host * * Frees irq, deallocates a page for messages, unmaps dma, and unregisters * the crq with the hypervisor. */ void ibmvscsi_release_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata, int max_requests) { long rc; struct vio_dev *vdev = to_vio_dev(hostdata->dev); free_irq(vdev->irq, (void *)hostdata); tasklet_kill(&hostdata->srp_task); do { rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); dma_unmap_single(hostdata->dev, queue->msg_token, queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); free_page((unsigned long)queue->msgs); }
static long ehca_plpar_hcall_norets(unsigned long opcode, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long arg7) { long ret; int i, sleep_msecs; unsigned long flags = 0; if (unlikely(ehca_debug_level >= 2)) ehca_gen_dbg("opcode=%lx " HCALL7_REGS_FORMAT, opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7); for (i = 0; i < 5; i++) { if (ehca_lock_hcalls) spin_lock_irqsave(&hcall_lock, flags); ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7); if (ehca_lock_hcalls) spin_unlock_irqrestore(&hcall_lock, flags); if (H_IS_LONG_BUSY(ret)) { sleep_msecs = get_longbusy_msecs(ret); msleep_interruptible(sleep_msecs); continue; } if (ret < H_SUCCESS) ehca_gen_err("opcode=%lx ret=%li " HCALL7_REGS_FORMAT, opcode, ret, arg1, arg2, arg3, arg4, arg5, arg6, arg7); else if (unlikely(ehca_debug_level >= 2)) ehca_gen_dbg("opcode=%lx ret=%li", opcode, ret); return ret; } return H_BUSY; }
/** * ibmvtpm_reset_crq - Reset CRQ * @ibmvtpm: ibm vtpm struct * * Return value: * 0 - Success * Non-zero - Failure */ static int ibmvtpm_reset_crq(struct ibmvtpm_dev *ibmvtpm) { int rc = 0; do { if (rc) msleep(100); rc = plpar_hcall_norets(H_FREE_CRQ, ibmvtpm->vdev->unit_address); } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); memset(ibmvtpm->crq_queue.crq_addr, 0, CRQ_RES_BUF_SIZE); ibmvtpm->crq_queue.index = 0; return plpar_hcall_norets(H_REG_CRQ, ibmvtpm->vdev->unit_address, ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE); }
static int rpavscsi_reenable_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata) { int rc = 0; struct vio_dev *vdev = to_vio_dev(hostdata->dev); do { if (rc) msleep(100); rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address); } while ((rc == H_IN_PROGRESS) || (rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); if (rc) dev_err(hostdata->dev, "Error %d enabling adapter\n", rc); return rc; }
static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter, union ibmveth_buf_desc rxq_desc, u64 mac_address) { int rc, try_again = 1; retry: rc = h_register_logical_lan(adapter->vdev->unit_address, adapter->buffer_list_dma, rxq_desc.desc, adapter->filter_list_dma, mac_address); if (rc != H_SUCCESS && try_again) { do { rc = h_free_logical_lan(adapter->vdev->unit_address); } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY)); try_again = 0; goto retry; } return rc; }
static int rpavscsi_init_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata, int max_requests) { int rc; int retrc; struct vio_dev *vdev = to_vio_dev(hostdata->dev); queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL); if (!queue->msgs) goto malloc_failed; queue->size = PAGE_SIZE / sizeof(*queue->msgs); queue->msg_token = dma_map_single(hostdata->dev, queue->msgs, queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); if (dma_mapping_error(hostdata->dev, queue->msg_token)) goto map_failed; gather_partition_info(); set_adapter_info(hostdata); retrc = rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, queue->msg_token, PAGE_SIZE); if (rc == H_RESOURCE) rc = rpavscsi_reset_crq_queue(queue, hostdata); if (rc == 2) { dev_warn(hostdata->dev, "Partner adapter not ready\n"); retrc = 0; } else if (rc != 0) { dev_warn(hostdata->dev, "Error %d opening adapter\n", rc); goto reg_crq_failed; } queue->cur = 0; spin_lock_init(&queue->lock); tasklet_init(&hostdata->srp_task, (void *)rpavscsi_task, (unsigned long)hostdata); if (request_irq(vdev->irq, rpavscsi_handle_event, 0, "ibmvscsi", (void *)hostdata) != 0) { dev_err(hostdata->dev, "couldn't register irq 0x%x\n", vdev->irq); goto req_irq_failed; } rc = vio_enable_interrupts(vdev); if (rc != 0) { dev_err(hostdata->dev, "Error %d enabling interrupts!!!\n", rc); goto req_irq_failed; } return retrc; req_irq_failed: tasklet_kill(&hostdata->srp_task); rc = 0; do { if (rc) msleep(100); rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); reg_crq_failed: dma_unmap_single(hostdata->dev, queue->msg_token, queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); map_failed: free_page((unsigned long)queue->msgs); malloc_failed: return -1; }
static int ibmveth_open(struct net_device *netdev) { struct ibmveth_adapter *adapter = netdev_priv(netdev); u64 mac_address = 0; int rxq_entries = 1; unsigned long lpar_rc; int rc; union ibmveth_buf_desc rxq_desc; int i; struct device *dev; ibmveth_debug_printk("open starting\n"); napi_enable(&adapter->napi); for(i = 0; i<IbmVethNumBufferPools; i++) rxq_entries += adapter->rx_buff_pool[i].size; adapter->buffer_list_addr = (void*) get_zeroed_page(GFP_KERNEL); adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL); if(!adapter->buffer_list_addr || !adapter->filter_list_addr) { ibmveth_error_printk("unable to allocate filter or buffer list pages\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENOMEM; } adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * rxq_entries; adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, GFP_KERNEL); if(!adapter->rx_queue.queue_addr) { ibmveth_error_printk("unable to allocate rx queue pages\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENOMEM; } dev = &adapter->vdev->dev; adapter->buffer_list_dma = dma_map_single(dev, adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); adapter->filter_list_dma = dma_map_single(dev, adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); adapter->rx_queue.queue_dma = dma_map_single(dev, adapter->rx_queue.queue_addr, adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || (dma_mapping_error(dev, adapter->filter_list_dma)) || (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { ibmveth_error_printk("unable to map filter or buffer list pages\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENOMEM; } adapter->rx_queue.index = 0; adapter->rx_queue.num_slots = rxq_entries; adapter->rx_queue.toggle = 1; memcpy(&mac_address, netdev->dev_addr, netdev->addr_len); mac_address = mac_address >> 16; rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | adapter->rx_queue.queue_len; rxq_desc.fields.address = adapter->rx_queue.queue_dma; ibmveth_debug_printk("buffer list @ 0x%p\n", adapter->buffer_list_addr); ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr); ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr); h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address); if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); ibmveth_error_printk("buffer TCE:0x%llx filter TCE:0x%llx rxq desc:0x%llx MAC:0x%llx\n", adapter->buffer_list_dma, adapter->filter_list_dma, rxq_desc.desc, mac_address); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENONET; } for(i = 0; i<IbmVethNumBufferPools; i++) { if(!adapter->rx_buff_pool[i].active) continue; if (ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[i])) { ibmveth_error_printk("unable to alloc pool\n"); adapter->rx_buff_pool[i].active = 0; ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENOMEM ; } } ibmveth_debug_printk("registering irq 0x%x\n", netdev->irq); if((rc = request_irq(netdev->irq, &ibmveth_interrupt, 0, netdev->name, netdev)) != 0) { ibmveth_error_printk("unable to request irq 0x%x, rc %d\n", netdev->irq, rc); do { rc = h_free_logical_lan(adapter->vdev->unit_address); } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY)); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return rc; } adapter->bounce_buffer = kmalloc(netdev->mtu + IBMVETH_BUFF_OH, GFP_KERNEL); if (!adapter->bounce_buffer) { ibmveth_error_printk("unable to allocate bounce buffer\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENOMEM; } adapter->bounce_buffer_dma = dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer, netdev->mtu + IBMVETH_BUFF_OH, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) { ibmveth_error_printk("unable to map bounce buffer\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); return -ENOMEM; } ibmveth_debug_printk("initial replenish cycle\n"); ibmveth_interrupt(netdev->irq, netdev); netif_start_queue(netdev); ibmveth_debug_printk("open complete\n"); return 0; }
/** * initialize_crq_queue: - Initializes and registers CRQ with hypervisor * @queue: crq_queue to initialize and register * @hostdata: ibmvscsi_host_data of host * * Allocates a page for messages, maps it for dma, and registers * the crq with the hypervisor. * Returns zero on success. */ int ibmvscsi_init_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata, int max_requests) { int rc; int retrc; struct vio_dev *vdev = to_vio_dev(hostdata->dev); queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL); if (!queue->msgs) goto malloc_failed; queue->size = PAGE_SIZE / sizeof(*queue->msgs); queue->msg_token = dma_map_single(hostdata->dev, queue->msgs, queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); if (dma_mapping_error(queue->msg_token)) goto map_failed; gather_partition_info(); set_adapter_info(hostdata); retrc = rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, queue->msg_token, PAGE_SIZE); if (rc == H_RESOURCE) /* maybe kexecing and resource is busy. try a reset */ rc = ibmvscsi_reset_crq_queue(queue, hostdata); if (rc == 2) { /* Adapter is good, but other end is not ready */ printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n"); retrc = 0; } else if (rc != 0) { printk(KERN_WARNING "ibmvscsi: Error %d opening adapter\n", rc); goto reg_crq_failed; } if (request_irq(vdev->irq, ibmvscsi_handle_event, 0, "ibmvscsi", (void *)hostdata) != 0) { printk(KERN_ERR "ibmvscsi: couldn't register irq 0x%x\n", vdev->irq); goto req_irq_failed; } rc = vio_enable_interrupts(vdev); if (rc != 0) { printk(KERN_ERR "ibmvscsi: Error %d enabling interrupts!!!\n", rc); goto req_irq_failed; } queue->cur = 0; spin_lock_init(&queue->lock); tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, (unsigned long)hostdata); return retrc; req_irq_failed: do { rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); reg_crq_failed: dma_unmap_single(hostdata->dev, queue->msg_token, queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); map_failed: free_page((unsigned long)queue->msgs); malloc_failed: return -1; }
/** * tpm_ibmvtpm_probe - ibm vtpm initialize entry point * @vio_dev: vio device struct * @id: vio device id struct * * Return value: * 0 - Success * Non-zero - Failure */ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, const struct vio_device_id *id) { struct ibmvtpm_dev *ibmvtpm; struct device *dev = &vio_dev->dev; struct ibmvtpm_crq_queue *crq_q; struct tpm_chip *chip; int rc = -ENOMEM, rc1; chip = tpm_register_hardware(dev, &tpm_ibmvtpm); if (!chip) { dev_err(dev, "tpm_register_hardware failed\n"); return -ENODEV; } ibmvtpm = kzalloc(sizeof(struct ibmvtpm_dev), GFP_KERNEL); if (!ibmvtpm) { dev_err(dev, "kzalloc for ibmvtpm failed\n"); goto cleanup; } crq_q = &ibmvtpm->crq_queue; crq_q->crq_addr = (struct ibmvtpm_crq *)get_zeroed_page(GFP_KERNEL); if (!crq_q->crq_addr) { dev_err(dev, "Unable to allocate memory for crq_addr\n"); goto cleanup; } crq_q->num_entry = CRQ_RES_BUF_SIZE / sizeof(*crq_q->crq_addr); ibmvtpm->crq_dma_handle = dma_map_single(dev, crq_q->crq_addr, CRQ_RES_BUF_SIZE, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, ibmvtpm->crq_dma_handle)) { dev_err(dev, "dma mapping failed\n"); goto cleanup; } rc = plpar_hcall_norets(H_REG_CRQ, vio_dev->unit_address, ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE); if (rc == H_RESOURCE) rc = ibmvtpm_reset_crq(ibmvtpm); if (rc) { dev_err(dev, "Unable to register CRQ rc=%d\n", rc); goto reg_crq_cleanup; } rc = request_irq(vio_dev->irq, ibmvtpm_interrupt, 0, tpm_ibmvtpm_driver_name, ibmvtpm); if (rc) { dev_err(dev, "Error %d register irq 0x%x\n", rc, vio_dev->irq); goto init_irq_cleanup; } rc = vio_enable_interrupts(vio_dev); if (rc) { dev_err(dev, "Error %d enabling interrupts\n", rc); goto init_irq_cleanup; } init_waitqueue_head(&ibmvtpm->wq); crq_q->index = 0; ibmvtpm->dev = dev; ibmvtpm->vdev = vio_dev; chip->vendor.data = (void *)ibmvtpm; spin_lock_init(&ibmvtpm->rtce_lock); rc = ibmvtpm_crq_send_init(ibmvtpm); if (rc) goto init_irq_cleanup; rc = ibmvtpm_crq_get_version(ibmvtpm); if (rc) goto init_irq_cleanup; rc = ibmvtpm_crq_get_rtce_size(ibmvtpm); if (rc) goto init_irq_cleanup; return rc; init_irq_cleanup: do { rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address); } while (rc1 == H_BUSY || H_IS_LONG_BUSY(rc1)); reg_crq_cleanup: dma_unmap_single(dev, ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE, DMA_BIDIRECTIONAL); cleanup: if (ibmvtpm) { if (crq_q->crq_addr) free_page((unsigned long)crq_q->crq_addr); kfree(ibmvtpm); } tpm_remove_hardware(dev); return rc; }
static long ehca_plpar_hcall9(unsigned long opcode, unsigned long *outs, /* array of 9 outputs */ unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long arg7, unsigned long arg8, unsigned long arg9) { long ret; int i, sleep_msecs, lock_is_set = 0; unsigned long flags; ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx " "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx", opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); for (i = 0; i < 5; i++) { if ((opcode == H_ALLOC_RESOURCE) && (arg2 == 5)) { spin_lock_irqsave(&hcall_lock, flags); lock_is_set = 1; } ret = plpar_hcall9(opcode, outs, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); if (lock_is_set) spin_unlock_irqrestore(&hcall_lock, flags); if (H_IS_LONG_BUSY(ret)) { sleep_msecs = get_longbusy_msecs(ret); msleep_interruptible(sleep_msecs); continue; } if (ret < H_SUCCESS) ehca_gen_err("opcode=%lx ret=%lx" " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" " arg9=%lx" " out1=%lx out2=%lx out3=%lx out4=%lx" " out5=%lx out6=%lx out7=%lx out8=%lx" " out9=%lx", opcode, ret, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, outs[0], outs[1], outs[2], outs[3], outs[4], outs[5], outs[6], outs[7], outs[8]); ehca_gen_dbg("opcode=%lx ret=%lx out1=%lx out2=%lx out3=%lx " "out4=%lx out5=%lx out6=%lx out7=%lx out8=%lx " "out9=%lx", opcode, ret, outs[0], outs[1], outs[2], outs[3], outs[4], outs[5], outs[6], outs[7], outs[8]); return ret; } return H_BUSY; }