Message ID | 4B02796E.4020504@redhat.com |
---|---|
State | New |
Headers | show |
Gerd Hoffmann wrote: > On 11/12/09 12:48, Hannes Reinecke wrote: >> >> This patch adds an emulation for the LSI MegaRAID SAS HBA. >> It is build on top of kraxel's scsi.v7 tree. >> >> This is just a rough implementation, many of the more >> advanced topics (like Windows booting :-) are missing. >> >> Signed-off-by: Hannes Reinecke<hare@suse.de> > > Added, will be in scsi.v8. Needs a patch after rebasing due to pci > changes (attached fyi). > Grand. Meanwhile I've dug up some more register definitions, so I'll doing some more updates to the driver. Thanks for including it. Meanwhile I've stumbled across another issue: The megasas HBA insists on returning some data like inquiry or VPD pages during init/configuration. I can't really use the normal command completion here, as eg on megasas configuration command requires me to issue several requests to the underlying device. So what to do? Easiest would it to have a non-completion interface, like req_buf() but without the callback bit. But really don't know if that's best. We could also attach the inquiry data and vpd 0x83 as a property to the device; might be easier as we don't have to add another interface. But the properties stuff is a bit beyond me currently. Cheers, Hannes
On 11/17/09 11:51, Hannes Reinecke wrote: > Grand. Meanwhile I've dug up some more register definitions, > so I'll doing some more updates to the driver. Feel free to send updates (both incremental and replacement are fine). > Meanwhile I've stumbled across another issue: > The megasas HBA insists on returning some data like inquiry > or VPD pages during init/configuration. > > I can't really use the normal command completion here, > as eg on megasas configuration command requires me > to issue several requests to the underlying device. Well, you can, but it probably isn't very convenient ... Easy way out would be calling qemu_aio_wait(), when it returns you can be sure the request is finished (and the completion callback was called). You probably have to flag the request as being special somewhere in req->hba_private so your completion callback will not apply the usual processing. Calling qemu_aio_wait() is only needed if there is actually something in flight asynchronously. req->status is initialized to -1 and set to a status code on completion, so you can use that to figure whenever the request is still being processed. All commands emulated by scsi-disk will complete instantly, i.e. the completion callback will be called before scsi_req_{buf,sgl} returns. Only with scsi-generic you'll find INQUIRY being processed really asynchronously. cheers, Gerd
diff --git a/hw/megasas.c b/hw/megasas.c index 723c586..3d15cc6 100644 --- a/hw/megasas.c +++ b/hw/megasas.c @@ -1034,7 +1034,7 @@ static void megasas_soft_reset(MPTState *s) } static void megasas_mmio_mapfunc(PCIDevice *pci_dev, int region_num, - uint32_t addr, uint32_t size, int type) + pcibus_t addr, pcibus_t size, int type) { MPTState *s = DO_UPCAST(MPTState, dev, pci_dev); @@ -1043,7 +1043,7 @@ static void megasas_mmio_mapfunc(PCIDevice *pci_dev, int region_num, } static void megasas_io_mapfunc(PCIDevice *pci_dev, int region_num, - uint32_t addr, uint32_t size, int type) + pcibus_t addr, pcibus_t size, int type) { MPTState *s = DO_UPCAST(MPTState, dev, pci_dev); @@ -1058,7 +1058,7 @@ static void megasas_io_mapfunc(PCIDevice *pci_dev, int region_num, } static void megasas_queue_mapfunc(PCIDevice *pci_dev, int region_num, - uint32_t addr, uint32_t size, int type) + pcibus_t addr, pcibus_t size, int type) { MPTState *s = DO_UPCAST(MPTState, dev, pci_dev); @@ -1140,11 +1140,11 @@ static int megasas_scsi_init(PCIDevice *dev) s->queue_addr = cpu_register_io_memory(megasas_queue_readfn, megasas_queue_writefn, s); pci_register_bar((struct PCIDevice *)s, 0, 0x40000, - PCI_ADDRESS_SPACE_MEM, megasas_mmio_mapfunc); + PCI_BASE_ADDRESS_SPACE_MEMORY, megasas_mmio_mapfunc); pci_register_bar((struct PCIDevice *)s, 2, 256, - PCI_ADDRESS_SPACE_IO, megasas_io_mapfunc); + PCI_BASE_ADDRESS_SPACE_IO, megasas_io_mapfunc); pci_register_bar((struct PCIDevice *)s, 3, 0x40000, - PCI_ADDRESS_SPACE_MEM, megasas_queue_mapfunc); + PCI_BASE_ADDRESS_SPACE_MEMORY, megasas_queue_mapfunc); s->fw_sge = MEGASAS_MAX_SGE; s->fw_cmds = MEGASAS_MAX_FRAMES; s->fw_luns = (MEGASAS_MAX_LUNS > MAX_SCSI_DEVS) ?