static void __init probe_disk(struct device_node *vio_root, u32 unit) { HvLpEvent_Rc hvrc; struct vio_waitevent we; u16 flags = 0; retry: init_completion(&we.com); /* Send the open event to OS/400 */ hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, HvLpEvent_Type_VirtualIo, viomajorsubtype_blockio | vioblockopen, HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, viopath_sourceinst(viopath_hostLp), viopath_targetinst(viopath_hostLp), (u64)(unsigned long)&we, VIOVERSION << 16, ((u64)unit << 48) | ((u64)flags<< 32), 0, 0, 0); if (hvrc != 0) { printk(KERN_WARNING "probe_disk: bad rc on HV open %d\n", (int)hvrc); return; } wait_for_completion(&we.com); if (we.rc != 0) { if (flags != 0) return; /* try again with read only flag set */ flags = vioblockflags_ro; goto retry; } /* Send the close event to OS/400. We DON'T expect a response */ hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, HvLpEvent_Type_VirtualIo, viomajorsubtype_blockio | vioblockclose, HvLpEvent_AckInd_NoAck, HvLpEvent_AckType_ImmediateAck, viopath_sourceinst(viopath_hostLp), viopath_targetinst(viopath_hostLp), 0, VIOVERSION << 16, ((u64)unit << 48) | ((u64)flags << 32), 0, 0, 0); if (hvrc != 0) { printk(KERN_WARNING "probe_disk: " "bad rc sending event to OS/400 %d\n", (int)hvrc); return; } do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit, "block", "IBM,iSeries-viodasd", NULL); }
static void __init get_viotape_info(struct device_node *vio_root) { HvLpEvent_Rc hvrc; u32 unit; struct vio_resource *unitinfo; dma_addr_t unitinfo_dmaaddr; size_t len = sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALTAPES; struct vio_waitevent we; int ret; init_completion(&we.com); ret = viopath_open(viopath_hostLp, viomajorsubtype_tape, 2); if (ret) { printk(KERN_WARNING "get_viotape_info: " "error on viopath_open to hostlp %d\n", ret); return; } vio_setHandler(viomajorsubtype_tape, handle_tape_event); unitinfo = iseries_hv_alloc(len, &unitinfo_dmaaddr, GFP_ATOMIC); if (!unitinfo) goto clear_handler; memset(unitinfo, 0, len); hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, HvLpEvent_Type_VirtualIo, viomajorsubtype_tape | viotapegetinfo, HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, viopath_sourceinst(viopath_hostLp), viopath_targetinst(viopath_hostLp), (u64)(unsigned long)&we, VIOVERSION << 16, unitinfo_dmaaddr, len, 0, 0); if (hvrc != HvLpEvent_Rc_Good) { printk(KERN_WARNING "get_viotape_info: hv error on op %d\n", (int)hvrc); goto hv_free; } wait_for_completion(&we.com); for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) && unitinfo[unit].rsrcname[0]; unit++) { if (!do_device_node(vio_root, "viotape", FIRST_VIOTAPE + unit, unit, "byte", "IBM,iSeries-viotape", &unitinfo[unit])) break; } hv_free: iseries_hv_free(len, unitinfo, unitinfo_dmaaddr); clear_handler: vio_clearHandler(viomajorsubtype_tape); viopath_close(viopath_hostLp, viomajorsubtype_tape, 2); }
/* * Send an open event */ static int send_open(HvLpIndex remoteLp, void *sem) { return HvCallEvent_signalLpEventFast(remoteLp, HvLpEvent_Type_VirtualIo, viomajorsubtype_chario | viocharopen, HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, viopath_sourceinst(remoteLp), viopath_targetinst(remoteLp), (u64)(unsigned long)sem, VIOVERSION << 16, 0, 0, 0, 0); }
/** * ibmvscsi_send_crq: - Send a CRQ * @hostdata: the adapter * @word1: the first 64 bits of the data * @word2: the second 64 bits of the data */ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) { single_host_data = hostdata; return HvCallEvent_signalLpEventFast(viopath_hostLp, HvLpEvent_Type_VirtualIo, viomajorsubtype_scsi, HvLpEvent_AckInd_NoAck, HvLpEvent_AckType_ImmediateAck, viopath_sourceinst(viopath_hostLp), viopath_targetinst(viopath_hostLp), 0, VIOVERSION << 16, word1, word2, 0, 0); }
static int proc_viopath_show(struct seq_file *m, void *v) { char *buf; u16 vlanMap; dma_addr_t handle; HvLpEvent_Rc hvrc; DECLARE_MUTEX_LOCKED(Semaphore); buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buf) return 0; memset(buf, 0, PAGE_SIZE); handle = dma_map_single(iSeries_vio_dev, buf, PAGE_SIZE, DMA_FROM_DEVICE); hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, HvLpEvent_Type_VirtualIo, viomajorsubtype_config | vioconfigget, HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, viopath_sourceinst(viopath_hostLp), viopath_targetinst(viopath_hostLp), (u64)(unsigned long)&Semaphore, VIOVERSION << 16, ((u64)handle) << 32, PAGE_SIZE, 0, 0); if (hvrc != HvLpEvent_Rc_Good) printk(VIOPATH_KERN_WARN "hv error on op %d\n", (int)hvrc); down(&Semaphore); vlanMap = HvLpConfig_getVirtualLanIndexMap(); buf[PAGE_SIZE-1] = '\0'; seq_printf(m, "%s", buf); seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap); seq_printf(m, "SRLNBR=%c%c%c%c%c%c%c\n", e2a(xItExtVpdPanel.mfgID[2]), e2a(xItExtVpdPanel.mfgID[3]), e2a(xItExtVpdPanel.systemSerial[1]), e2a(xItExtVpdPanel.systemSerial[2]), e2a(xItExtVpdPanel.systemSerial[3]), e2a(xItExtVpdPanel.systemSerial[4]), e2a(xItExtVpdPanel.systemSerial[5])); dma_unmap_single(iSeries_vio_dev, handle, PAGE_SIZE, DMA_FROM_DEVICE); kfree(buf); return 0; }
/* * Initialize the common fields in a charLpEvent */ static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp) { memset(viochar, 0, sizeof(struct viocharlpevent)); viochar->event.xFlags.xValid = 1; viochar->event.xFlags.xFunction = HvLpEvent_Function_Int; viochar->event.xFlags.xAckInd = HvLpEvent_AckInd_NoAck; viochar->event.xFlags.xAckType = HvLpEvent_AckType_DeferredAck; viochar->event.xType = HvLpEvent_Type_VirtualIo; viochar->event.xSubtype = viomajorsubtype_chario | viochardata; viochar->event.xSourceLp = HvLpConfig_getLpIndex(); viochar->event.xTargetLp = lp; viochar->event.xSizeMinus1 = sizeof(struct viocharlpevent); viochar->event.xSourceInstanceId = viopath_sourceinst(lp); viochar->event.xTargetInstanceId = viopath_targetinst(lp); }
static void __init get_viocd_info(struct device_node *vio_root) { HvLpEvent_Rc hvrc; u32 unit; struct vio_waitevent we; struct vio_resource *unitinfo; dma_addr_t unitinfo_dmaaddr; int ret; ret = viopath_open(viopath_hostLp, viomajorsubtype_cdio, 2); if (ret) { printk(KERN_WARNING "get_viocd_info: error opening path to host partition %d\n", viopath_hostLp); return; } /* Initialize our request handler */ vio_setHandler(viomajorsubtype_cdio, handle_cd_event); unitinfo = iseries_hv_alloc( sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, &unitinfo_dmaaddr, GFP_ATOMIC); if (!unitinfo) { printk(KERN_WARNING "get_viocd_info: error allocating unitinfo\n"); goto clear_handler; } memset(unitinfo, 0, sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS); init_completion(&we.com); hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, HvLpEvent_Type_VirtualIo, viomajorsubtype_cdio | viocdgetinfo, HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, viopath_sourceinst(viopath_hostLp), viopath_targetinst(viopath_hostLp), (u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0, sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, 0); if (hvrc != HvLpEvent_Rc_Good) { printk(KERN_WARNING "get_viocd_info: cdrom error sending event. rc %d\n", (int)hvrc); goto hv_free; } wait_for_completion(&we.com); if (we.rc) { printk(KERN_WARNING "get_viocd_info: bad rc %d:0x%04X\n", we.rc, we.sub_result); goto hv_free; } for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) && unitinfo[unit].rsrcname[0]; unit++) { if (!do_device_node(vio_root, "viocd", FIRST_VIOCD + unit, unit, "block", "IBM,iSeries-viocd", &unitinfo[unit])) break; } hv_free: iseries_hv_free(sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, unitinfo, unitinfo_dmaaddr); clear_handler: vio_clearHandler(viomajorsubtype_cdio); viopath_close(viopath_hostLp, viomajorsubtype_cdio, 2); }