static CcwDevice *s390_get_ccw_device(DeviceState *dev_st) { CcwDevice *ccw_dev = NULL; if (dev_st) { VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *) object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent), TYPE_VIRTIO_CCW_DEVICE); if (virtio_ccw_dev) { ccw_dev = CCW_DEVICE(virtio_ccw_dev); } else { SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st), TYPE_SCSI_DEVICE); if (sd) { SCSIBus *bus = scsi_bus_from_device(sd); VirtIOSCSI *vdev = container_of(bus, VirtIOSCSI, bus); VirtIOSCSICcw *scsi_ccw = container_of(vdev, VirtIOSCSICcw, vdev); ccw_dev = (CcwDevice *)object_dynamic_cast(OBJECT(scsi_ccw), TYPE_CCW_DEVICE); } } } return ccw_dev; }
/* * Invoke device-specific unplug handler, disable the subchannel * (including sending a channel report to the guest) and remove the * device from the virtual css bus. */ static void ccw_device_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { CcwDevice *ccw_dev = CCW_DEVICE(dev); CCWDeviceClass *k = CCW_DEVICE_GET_CLASS(ccw_dev); SubchDev *sch = ccw_dev->sch; Error *err = NULL; if (k->unplug) { k->unplug(hotplug_dev, dev, &err); if (err) { error_propagate(errp, err); return; } } /* * We should arrive here only for device_del, since we don't support * direct hot(un)plug of channels. */ assert(sch != NULL); /* Subchannel is now disabled and no longer valid. */ sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA | PMCW_FLAGS_MASK_DNV); css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0); object_unparent(OBJECT(dev)); }
static bool s390_gen_initial_iplb(S390IPLState *ipl) { DeviceState *dev_st; dev_st = get_boot_device(0); if (dev_st) { VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *) object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent), TYPE_VIRTIO_CCW_DEVICE); SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st), TYPE_SCSI_DEVICE); VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st), TYPE_VIRTIO_NET); if (vn) { ipl->netboot = true; } if (virtio_ccw_dev) { CcwDevice *ccw_dev = CCW_DEVICE(virtio_ccw_dev); ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); ipl->iplb.blk0_len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN); ipl->iplb.pbt = S390_IPL_TYPE_CCW; ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno); ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3; } else if (sd) { SCSIBus *bus = scsi_bus_from_device(sd); VirtIOSCSI *vdev = container_of(bus, VirtIOSCSI, bus); VirtIOSCSICcw *scsi_ccw = container_of(vdev, VirtIOSCSICcw, vdev); CcwDevice *ccw_dev; ccw_dev = (CcwDevice *)object_dynamic_cast(OBJECT(scsi_ccw), TYPE_CCW_DEVICE); if (!ccw_dev) { /* It might be a PCI device instead */ return false; } ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN); ipl->iplb.blk0_len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN); ipl->iplb.pbt = S390_IPL_TYPE_QEMU_SCSI; ipl->iplb.scsi.lun = cpu_to_be32(sd->lun); ipl->iplb.scsi.target = cpu_to_be16(sd->id); ipl->iplb.scsi.channel = cpu_to_be16(sd->channel); ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno); ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3; } else { return false; /* unknown device */ } if (!s390_ipl_set_loadparm(ipl->iplb.loadparm)) { ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID; } return true; } return false; }
static char *virtual_css_bus_get_dev_path(DeviceState *dev) { CcwDevice *ccw_dev = CCW_DEVICE(dev); SubchDev *sch = ccw_dev->sch; VirtualCssBridge *bridge = VIRTUAL_CSS_BRIDGE(qdev_get_parent_bus(dev)->parent); /* * We can't provide a dev path for backward compatibility on * older machines, as it is visible in the migration stream. */ return bridge->css_dev_path ? g_strdup_printf("/%02x.%1x.%04x", sch->cssid, sch->ssid, sch->devno) : NULL; }
struct raw3215_info *raw; unsigned long flags; /* Allow I/O again and flush output buffer. */ raw = dev_get_drvdata(&cdev->dev); spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); raw->port.flags &= ~ASYNC_SUSPENDED; raw->flags |= RAW3215_FLUSHING; raw3215_try_io(raw); raw->flags &= ~RAW3215_FLUSHING; spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); return 0; } static struct ccw_device_id raw3215_id[] = { { CCW_DEVICE(0x3215, 0) }, { /* end of list */ }, }; static struct ccw_driver raw3215_ccw_driver = { .driver = { .name = "3215", .owner = THIS_MODULE, }, .ids = raw3215_id, .probe = &raw3215_probe, .remove = &raw3215_remove, .set_online = &raw3215_set_online, .set_offline = &raw3215_set_offline, .freeze = &raw3215_pm_stop, .thaw = &raw3215_pm_start,
const char *cu3088_type[] = { "not a channel", "CTC/A", "ESCON channel", "FICON channel", "P390 LCS card", "OSA2 card", "unknown channel type", "unsupported channel type", }; /* static definitions */ static struct ccw_device_id cu3088_ids[] = { { CCW_DEVICE(0x3088, 0x08), .driver_info = channel_type_parallel }, { CCW_DEVICE(0x3088, 0x1f), .driver_info = channel_type_escon }, { CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon }, { CCW_DEVICE(0x3088, 0x01), .driver_info = channel_type_p390 }, { CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 }, { /* end of list */ } }; static struct ccw_driver cu3088_driver; static void cu3088_root_dev_release (struct device *dev) { } struct device cu3088_root_dev = {