"Nicholas A. Bellinger" <nab@xxxxxxxxxxxxxxx> writes: > From: Paolo Bonzini <pbonzini@xxxxxxxxxx> > > This patch refactors existing virtio-scsi code into VirtIOSCSICommon > in order to allow virtio_scsi_init_common() to be used by both internal > virtio_scsi_init() and external vhost-scsi-pci code. > > Changes in Patch-v2: > - Move ->get_features() assignment to virtio_scsi_init() instead of > virtio_scsi_init_common() Any reason we're not doing this as a QOM base class? Similiar to how the in-kernel PIT/PIC work using a common base class... Regards, Anthony Liguori > > Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> > Cc: Michael S. Tsirkin <mst@xxxxxxxxxx> > Cc: Asias He <asias@xxxxxxxxxx> > Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> > --- > hw/virtio-scsi.c | 192 +++++++++++++------------------------------------- > hw/virtio-scsi.h | 130 ++++++++++++++++++++++++++++++++-- > include/qemu/osdep.h | 4 + > 3 files changed, 178 insertions(+), 148 deletions(-) > > diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c > index 8620712..c59e9c6 100644 > --- a/hw/virtio-scsi.c > +++ b/hw/virtio-scsi.c > @@ -18,118 +18,6 @@ > #include <hw/scsi.h> > #include <hw/scsi-defs.h> > > -#define VIRTIO_SCSI_VQ_SIZE 128 > -#define VIRTIO_SCSI_CDB_SIZE 32 > -#define VIRTIO_SCSI_SENSE_SIZE 96 > -#define VIRTIO_SCSI_MAX_CHANNEL 0 > -#define VIRTIO_SCSI_MAX_TARGET 255 > -#define VIRTIO_SCSI_MAX_LUN 16383 > - > -/* Response codes */ > -#define VIRTIO_SCSI_S_OK 0 > -#define VIRTIO_SCSI_S_OVERRUN 1 > -#define VIRTIO_SCSI_S_ABORTED 2 > -#define VIRTIO_SCSI_S_BAD_TARGET 3 > -#define VIRTIO_SCSI_S_RESET 4 > -#define VIRTIO_SCSI_S_BUSY 5 > -#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 > -#define VIRTIO_SCSI_S_TARGET_FAILURE 7 > -#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 > -#define VIRTIO_SCSI_S_FAILURE 9 > -#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10 > -#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11 > -#define VIRTIO_SCSI_S_INCORRECT_LUN 12 > - > -/* Controlq type codes. */ > -#define VIRTIO_SCSI_T_TMF 0 > -#define VIRTIO_SCSI_T_AN_QUERY 1 > -#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 > - > -/* Valid TMF subtypes. */ > -#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 > -#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 > -#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 > -#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 > -#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 > -#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 > -#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 > -#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 > - > -/* Events. */ > -#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000 > -#define VIRTIO_SCSI_T_NO_EVENT 0 > -#define VIRTIO_SCSI_T_TRANSPORT_RESET 1 > -#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 > -#define VIRTIO_SCSI_T_PARAM_CHANGE 3 > - > -/* Reasons for transport reset event */ > -#define VIRTIO_SCSI_EVT_RESET_HARD 0 > -#define VIRTIO_SCSI_EVT_RESET_RESCAN 1 > -#define VIRTIO_SCSI_EVT_RESET_REMOVED 2 > - > -/* SCSI command request, followed by data-out */ > -typedef struct { > - uint8_t lun[8]; /* Logical Unit Number */ > - uint64_t tag; /* Command identifier */ > - uint8_t task_attr; /* Task attribute */ > - uint8_t prio; > - uint8_t crn; > - uint8_t cdb[]; > -} QEMU_PACKED VirtIOSCSICmdReq; > - > -/* Response, followed by sense data and data-in */ > -typedef struct { > - uint32_t sense_len; /* Sense data length */ > - uint32_t resid; /* Residual bytes in data buffer */ > - uint16_t status_qualifier; /* Status qualifier */ > - uint8_t status; /* Command completion status */ > - uint8_t response; /* Response values */ > - uint8_t sense[]; > -} QEMU_PACKED VirtIOSCSICmdResp; > - > -/* Task Management Request */ > -typedef struct { > - uint32_t type; > - uint32_t subtype; > - uint8_t lun[8]; > - uint64_t tag; > -} QEMU_PACKED VirtIOSCSICtrlTMFReq; > - > -typedef struct { > - uint8_t response; > -} QEMU_PACKED VirtIOSCSICtrlTMFResp; > - > -/* Asynchronous notification query/subscription */ > -typedef struct { > - uint32_t type; > - uint8_t lun[8]; > - uint32_t event_requested; > -} QEMU_PACKED VirtIOSCSICtrlANReq; > - > -typedef struct { > - uint32_t event_actual; > - uint8_t response; > -} QEMU_PACKED VirtIOSCSICtrlANResp; > - > -typedef struct { > - uint32_t event; > - uint8_t lun[8]; > - uint32_t reason; > -} QEMU_PACKED VirtIOSCSIEvent; > - > -typedef struct { > - uint32_t num_queues; > - uint32_t seg_max; > - uint32_t max_sectors; > - uint32_t cmd_per_lun; > - uint32_t event_info_size; > - uint32_t sense_size; > - uint32_t cdb_size; > - uint16_t max_channel; > - uint16_t max_target; > - uint32_t max_lun; > -} QEMU_PACKED VirtIOSCSIConfig; > - > typedef struct VirtIOSCSIReq { > VirtIOSCSI *dev; > VirtQueue *vq; > @@ -178,7 +66,7 @@ static void virtio_scsi_complete_req(VirtIOSCSIReq *req) > scsi_req_unref(req->sreq); > } > g_free(req); > - virtio_notify(&s->vdev, vq); > + virtio_notify(&s->vs.vdev, vq); > } > > static void virtio_scsi_bad_req(void) > @@ -237,7 +125,7 @@ static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq) > VirtIOSCSIReq *req = sreq->hba_private; > uint32_t n = virtio_queue_get_id(req->vq) - 2; > > - assert(n < req->dev->conf->num_queues); > + assert(n < req->dev->vs.conf->num_queues); > qemu_put_be32s(f, &n); > qemu_put_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem)); > } > @@ -251,9 +139,9 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq) > > req = g_malloc(sizeof(*req)); > qemu_get_be32s(f, &n); > - assert(n < s->conf->num_queues); > + assert(n < s->vs.conf->num_queues); > qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem)); > - virtio_scsi_parse_req(s, s->cmd_vqs[n], req); > + virtio_scsi_parse_req(s, s->vs.cmd_vqs[n], req); > > scsi_req_ref(sreq); > req->sreq = sreq; > @@ -468,8 +356,8 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq) > > out_size = req->elem.out_sg[0].iov_len; > in_size = req->elem.in_sg[0].iov_len; > - if (out_size < sizeof(VirtIOSCSICmdReq) + s->cdb_size || > - in_size < sizeof(VirtIOSCSICmdResp) + s->sense_size) { > + if (out_size < sizeof(VirtIOSCSICmdReq) + s->vs.cdb_size || > + in_size < sizeof(VirtIOSCSICmdResp) + s->vs.sense_size) { > virtio_scsi_bad_req(); > } > > @@ -511,7 +399,7 @@ static void virtio_scsi_get_config(VirtIODevice *vdev, > uint8_t *config) > { > VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config; > - VirtIOSCSI *s = (VirtIOSCSI *)vdev; > + VirtIOSCSICommon *s = (VirtIOSCSICommon *)vdev; > > stl_raw(&scsiconf->num_queues, s->conf->num_queues); > stl_raw(&scsiconf->seg_max, 128 - 2); > @@ -537,8 +425,8 @@ static void virtio_scsi_set_config(VirtIODevice *vdev, > exit(1); > } > > - s->sense_size = ldl_raw(&scsiconf->sense_size); > - s->cdb_size = ldl_raw(&scsiconf->cdb_size); > + s->vs.sense_size = ldl_raw(&scsiconf->sense_size); > + s->vs.cdb_size = ldl_raw(&scsiconf->cdb_size); > } > > static uint32_t virtio_scsi_get_features(VirtIODevice *vdev, > @@ -555,8 +443,8 @@ static void virtio_scsi_reset(VirtIODevice *vdev) > qbus_reset_all(&s->bus.qbus); > s->resetting--; > > - s->sense_size = VIRTIO_SCSI_SENSE_SIZE; > - s->cdb_size = VIRTIO_SCSI_CDB_SIZE; > + s->vs.sense_size = VIRTIO_SCSI_SENSE_SIZE; > + s->vs.cdb_size = VIRTIO_SCSI_CDB_SIZE; > s->events_dropped = false; > } > > @@ -566,7 +454,7 @@ static void virtio_scsi_reset(VirtIODevice *vdev) > static void virtio_scsi_save(QEMUFile *f, void *opaque) > { > VirtIOSCSI *s = opaque; > - virtio_save(&s->vdev, f); > + virtio_save(&s->vs.vdev, f); > } > > static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id) > @@ -574,7 +462,7 @@ static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id) > VirtIOSCSI *s = opaque; > int ret; > > - ret = virtio_load(&s->vdev, f); > + ret = virtio_load(&s->vs.vdev, f); > if (ret) { > return ret; > } > @@ -584,11 +472,11 @@ static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id) > static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev, > uint32_t event, uint32_t reason) > { > - VirtIOSCSIReq *req = virtio_scsi_pop_req(s, s->event_vq); > + VirtIOSCSIReq *req = virtio_scsi_pop_req(s, s->vs.event_vq); > VirtIOSCSIEvent *evt; > int in_size; > > - if (!(s->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK)) { > + if (!(s->vs.vdev.status & VIRTIO_CONFIG_S_DRIVER_OK)) { > return; > } > > @@ -643,7 +531,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense) > { > VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); > > - if (((s->vdev.guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) && > + if (((s->vs.vdev.guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) && > dev->type != TYPE_ROM) { > virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE, > sense.asc | (sense.ascq << 8)); > @@ -654,7 +542,7 @@ static void virtio_scsi_hotplug(SCSIBus *bus, SCSIDevice *dev) > { > VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); > > - if ((s->vdev.guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { > + if ((s->vs.vdev.guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { > virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET, > VIRTIO_SCSI_EVT_RESET_RESCAN); > } > @@ -664,7 +552,7 @@ static void virtio_scsi_hot_unplug(SCSIBus *bus, SCSIDevice *dev) > { > VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); > > - if ((s->vdev.guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { > + if ((s->vs.vdev.guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { > virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET, > VIRTIO_SCSI_EVT_RESET_REMOVED); > } > @@ -686,35 +574,53 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = { > .load_request = virtio_scsi_load_request, > }; > > -VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf) > +VirtIOSCSICommon *virtio_scsi_init_common(DeviceState *dev, VirtIOSCSIConf *proxyconf, > + size_t sz) > { > - VirtIOSCSI *s; > - static int virtio_scsi_id; > - size_t sz; > + VirtIOSCSICommon *s; > int i; > > - sz = sizeof(VirtIOSCSI) + proxyconf->num_queues * sizeof(VirtQueue *); > - s = (VirtIOSCSI *)virtio_common_init("virtio-scsi", VIRTIO_ID_SCSI, > - sizeof(VirtIOSCSIConfig), sz); > + /* Place the cmd_vqs array at the end of the block that the caller > + * requested. Align the array properly, just in case. > + */ > + sz = ROUND_UP(sz, sizeof(void *)); > + s = (VirtIOSCSICommon *) > + virtio_common_init("virtio-scsi", VIRTIO_ID_SCSI, > + sizeof(VirtIOSCSIConfig), > + sz + sizeof(VirtQueue *) * proxyconf->num_queues); > > s->qdev = dev; > s->conf = proxyconf; > + s->sense_size = VIRTIO_SCSI_SENSE_SIZE; > + s->cdb_size = VIRTIO_SCSI_CDB_SIZE; > > - /* TODO set up vdev function pointers */ > s->vdev.get_config = virtio_scsi_get_config; > - s->vdev.set_config = virtio_scsi_set_config; > - s->vdev.get_features = virtio_scsi_get_features; > - s->vdev.reset = virtio_scsi_reset; > > s->ctrl_vq = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE, > virtio_scsi_handle_ctrl); > s->event_vq = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE, > virtio_scsi_handle_event); > + > + s->cmd_vqs = (VirtQueue **) ((char *)s + sz); > for (i = 0; i < s->conf->num_queues; i++) { > s->cmd_vqs[i] = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE, > virtio_scsi_handle_cmd); > } > > + return s; > +} > + > +VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf) > +{ > + VirtIOSCSI *s; > + static int virtio_scsi_id; > + > + s = (VirtIOSCSI *)virtio_scsi_init_common(dev, proxyconf, sizeof(VirtIOSCSI)); > + > + s->vs.vdev.get_features = virtio_scsi_get_features; > + s->vs.vdev.set_config = virtio_scsi_set_config; > + s->vs.vdev.reset = virtio_scsi_reset; > + > scsi_bus_new(&s->bus, dev, &virtio_scsi_scsi_info); > if (!dev->hotplugged) { > scsi_bus_legacy_handle_cmdline(&s->bus); > @@ -723,12 +629,12 @@ VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf) > register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1, > virtio_scsi_save, virtio_scsi_load, s); > > - return &s->vdev; > + return &s->vs.vdev; > } > > void virtio_scsi_exit(VirtIODevice *vdev) > { > VirtIOSCSI *s = (VirtIOSCSI *)vdev; > - unregister_savevm(s->qdev, "virtio-scsi", s); > + unregister_savevm(s->vs.qdev, "virtio-scsi", s); > virtio_cleanup(vdev); > } > diff --git a/hw/virtio-scsi.h b/hw/virtio-scsi.h > index ccf1e42..2bcf606 100644 > --- a/hw/virtio-scsi.h > +++ b/hw/virtio-scsi.h > @@ -26,25 +26,142 @@ > #define VIRTIO_SCSI_F_HOTPLUG 1 > #define VIRTIO_SCSI_F_CHANGE 2 > > +#define VIRTIO_SCSI_VQ_SIZE 128 > +#define VIRTIO_SCSI_CDB_SIZE 32 > +#define VIRTIO_SCSI_SENSE_SIZE 96 > +#define VIRTIO_SCSI_MAX_CHANNEL 0 > +#define VIRTIO_SCSI_MAX_TARGET 255 > +#define VIRTIO_SCSI_MAX_LUN 16383 > + > +/* Response codes */ > +#define VIRTIO_SCSI_S_OK 0 > +#define VIRTIO_SCSI_S_OVERRUN 1 > +#define VIRTIO_SCSI_S_ABORTED 2 > +#define VIRTIO_SCSI_S_BAD_TARGET 3 > +#define VIRTIO_SCSI_S_RESET 4 > +#define VIRTIO_SCSI_S_BUSY 5 > +#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 > +#define VIRTIO_SCSI_S_TARGET_FAILURE 7 > +#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 > +#define VIRTIO_SCSI_S_FAILURE 9 > +#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10 > +#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11 > +#define VIRTIO_SCSI_S_INCORRECT_LUN 12 > + > +/* Controlq type codes. */ > +#define VIRTIO_SCSI_T_TMF 0 > +#define VIRTIO_SCSI_T_AN_QUERY 1 > +#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 > + > +/* Valid TMF subtypes. */ > +#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 > +#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 > +#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 > +#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 > +#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 > +#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 > +#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 > +#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 > + > +/* Events. */ > +#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000 > +#define VIRTIO_SCSI_T_NO_EVENT 0 > +#define VIRTIO_SCSI_T_TRANSPORT_RESET 1 > +#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 > +#define VIRTIO_SCSI_T_PARAM_CHANGE 3 > + > +/* Reasons for transport reset event */ > +#define VIRTIO_SCSI_EVT_RESET_HARD 0 > +#define VIRTIO_SCSI_EVT_RESET_RESCAN 1 > +#define VIRTIO_SCSI_EVT_RESET_REMOVED 2 > + > +/* SCSI command request, followed by data-out */ > +typedef struct { > + uint8_t lun[8]; /* Logical Unit Number */ > + uint64_t tag; /* Command identifier */ > + uint8_t task_attr; /* Task attribute */ > + uint8_t prio; > + uint8_t crn; > + uint8_t cdb[]; > +} QEMU_PACKED VirtIOSCSICmdReq; > + > +/* Response, followed by sense data and data-in */ > +typedef struct { > + uint32_t sense_len; /* Sense data length */ > + uint32_t resid; /* Residual bytes in data buffer */ > + uint16_t status_qualifier; /* Status qualifier */ > + uint8_t status; /* Command completion status */ > + uint8_t response; /* Response values */ > + uint8_t sense[]; > +} QEMU_PACKED VirtIOSCSICmdResp; > + > +/* Task Management Request */ > +typedef struct { > + uint32_t type; > + uint32_t subtype; > + uint8_t lun[8]; > + uint64_t tag; > +} QEMU_PACKED VirtIOSCSICtrlTMFReq; > + > +typedef struct { > + uint8_t response; > +} QEMU_PACKED VirtIOSCSICtrlTMFResp; > + > +/* Asynchronous notification query/subscription */ > +typedef struct { > + uint32_t type; > + uint8_t lun[8]; > + uint32_t event_requested; > +} QEMU_PACKED VirtIOSCSICtrlANReq; > + > +typedef struct { > + uint32_t event_actual; > + uint8_t response; > +} QEMU_PACKED VirtIOSCSICtrlANResp; > + > +typedef struct { > + uint32_t event; > + uint8_t lun[8]; > + uint32_t reason; > +} QEMU_PACKED VirtIOSCSIEvent; > + > +typedef struct { > + uint32_t num_queues; > + uint32_t seg_max; > + uint32_t max_sectors; > + uint32_t cmd_per_lun; > + uint32_t event_info_size; > + uint32_t sense_size; > + uint32_t cdb_size; > + uint16_t max_channel; > + uint16_t max_target; > + uint32_t max_lun; > +} QEMU_PACKED VirtIOSCSIConfig; > + > struct VirtIOSCSIConf { > uint32_t num_queues; > uint32_t max_sectors; > uint32_t cmd_per_lun; > }; > > -typedef struct VirtIOSCSI { > +typedef struct VirtIOSCSICommon { > VirtIODevice vdev; > DeviceState *qdev; > VirtIOSCSIConf *conf; > > - SCSIBus bus; > uint32_t sense_size; > uint32_t cdb_size; > - int resetting; > - bool events_dropped; > VirtQueue *ctrl_vq; > VirtQueue *event_vq; > - VirtQueue *cmd_vqs[0]; > + VirtQueue **cmd_vqs; > +} VirtIOSCSICommon; > + > +typedef struct { > + VirtIOSCSICommon vs; > + > + SCSIBus bus; > + int resetting; > + bool events_dropped; > } VirtIOSCSI; > > #define DEFINE_VIRTIO_SCSI_PROPERTIES(_state, _features_field, _conf_field) \ > @@ -55,4 +172,7 @@ typedef struct VirtIOSCSI { > DEFINE_PROP_BIT("hotplug", _state, _features_field, VIRTIO_SCSI_F_HOTPLUG, true), \ > DEFINE_PROP_BIT("param_change", _state, _features_field, VIRTIO_SCSI_F_CHANGE, true) > > +VirtIOSCSICommon *virtio_scsi_init_common(DeviceState *dev, VirtIOSCSIConf *proxyconf, > + size_t sz); > + > #endif /* _QEMU_VIRTIO_SCSI_H */ > diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h > index df24400..8b465fd 100644 > --- a/include/qemu/osdep.h > +++ b/include/qemu/osdep.h > @@ -67,6 +67,10 @@ typedef signed int int_fast16_t; > #define MAX(a, b) (((a) > (b)) ? (a) : (b)) > #endif > > +#ifndef ROUND_UP > +#define ROUND_UP(n,d) (((n) + (d) - 1) & -(d)) > +#endif > + > #ifndef DIV_ROUND_UP > #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) > #endif > -- > 1.7.2.5 > > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html