* [PATCH 0/5] pvSCSI (SCSI pass through) driver
@ 2007-10-19 5:15 Jun Kamada
2007-10-19 8:38 ` Keir Fraser
` (2 more replies)
0 siblings, 3 replies; 33+ messages in thread
From: Jun Kamada @ 2007-10-19 5:15 UTC (permalink / raw)
To: xen-devel; +Cc: kama
Hi all,
I will send total five patches on following e-mails.
These patches provide functionality that guest domain can issue
complete SCSI command to FC-SCSI HBA(Fibre Channel SCSI Host Bus
Adapter) assigned to the guest domain.
Using this functionality, guest domain can control such as tape device
for backup and so on.
We hope these patches will be merged into Xen 3.2.0.
Thanks,
-----
Jun Kamada
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-19 5:15 [PATCH 0/5] pvSCSI (SCSI pass through) driver Jun Kamada
@ 2007-10-19 8:38 ` Keir Fraser
2007-10-19 10:20 ` Ian Pratt
2007-10-22 0:07 ` James Harper
2007-10-22 8:58 ` Keir Fraser
2 siblings, 1 reply; 33+ messages in thread
From: Keir Fraser @ 2007-10-19 8:38 UTC (permalink / raw)
To: Jun Kamada, xen-devel
This seems to have been hanging around for ages. If there's no argument
otherwise I'll give it a read through and stick it in for 3.2.0.
-- Keir
On 19/10/07 06:15, "Jun Kamada" <kama@jp.fujitsu.com> wrote:
> Hi all,
>
> I will send total five patches on following e-mails.
>
> These patches provide functionality that guest domain can issue
> complete SCSI command to FC-SCSI HBA(Fibre Channel SCSI Host Bus
> Adapter) assigned to the guest domain.
> Using this functionality, guest domain can control such as tape device
> for backup and so on.
>
> We hope these patches will be merged into Xen 3.2.0.
>
> Thanks,
>
> -----
> Jun Kamada
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 33+ messages in thread
* RE: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-19 8:38 ` Keir Fraser
@ 2007-10-19 10:20 ` Ian Pratt
2007-10-22 2:39 ` Jun Kamada
0 siblings, 1 reply; 33+ messages in thread
From: Ian Pratt @ 2007-10-19 10:20 UTC (permalink / raw)
To: Keir Fraser, Jun Kamada, xen-devel
> This seems to have been hanging around for ages. If there's no
argument
> otherwise I'll give it a read through and stick it in for 3.2.0.
Yep, its certainly a candidate for 3.2, but I'd class the API as
"experimental" at this stage and not commit to supporting it going
forward as-is just yet.
Things I'd like to see:
* performance results (hopefully at the summit!)
* variable sized comms rings (fixed at connect time) so we can queue
more descriptors if req'd.
* support for pass through of individual scsi logical units to the
dom0's linux scsi-generic layer rather than whole HBAs -- I think most
users will want to hide all that FC nastiness and just present a LUN.
Best,
Ian
> > These patches provide functionality that guest domain can issue
> > complete SCSI command to FC-SCSI HBA(Fibre Channel SCSI Host Bus
> > Adapter) assigned to the guest domain.
> > Using this functionality, guest domain can control such as tape
> device
> > for backup and so on.
> >
> > We hope these patches will be merged into Xen 3.2.0.
> >
> > Thanks,
> >
> > -----
> > Jun Kamada
> >
> >
> >
> > _______________________________________________
> > Xen-devel mailing list
> > Xen-devel@lists.xensource.com
> > http://lists.xensource.com/xen-devel
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 33+ messages in thread
* RE: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-19 5:15 [PATCH 0/5] pvSCSI (SCSI pass through) driver Jun Kamada
2007-10-19 8:38 ` Keir Fraser
@ 2007-10-22 0:07 ` James Harper
2007-10-23 7:41 ` Jun Kamada
2007-10-22 8:58 ` Keir Fraser
2 siblings, 1 reply; 33+ messages in thread
From: James Harper @ 2007-10-22 0:07 UTC (permalink / raw)
To: Jun Kamada, xen-devel
> Hi all,
>
> I will send total five patches on following e-mails.
>
> These patches provide functionality that guest domain can issue
> complete SCSI command to FC-SCSI HBA(Fibre Channel SCSI Host Bus
> Adapter) assigned to the guest domain.
> Using this functionality, guest domain can control such as tape device
> for backup and so on.
>
> We hope these patches will be merged into Xen 3.2.0.
>
I am very interested in this functionality, but mainly from a Windows
point of view (doing test restores of backups for customers). What would
be involved in getting this working under a HVM domain in the absence of
PV drivers?
Failing that, I'll see if I can incorporate it into the Windows PV
drivers I'm working on...
Thanks
James
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-19 10:20 ` Ian Pratt
@ 2007-10-22 2:39 ` Jun Kamada
0 siblings, 0 replies; 33+ messages in thread
From: Jun Kamada @ 2007-10-22 2:39 UTC (permalink / raw)
To: Ian Pratt; +Cc: kama, xen-devel
Hi Keir-san, Ian-san,
Thank you so much for your positive response.
On Fri, 19 Oct 2007 11:20:28 +0100
"Ian Pratt" <Ian.Pratt@cl.cam.ac.uk> wrote:
> > This seems to have been hanging around for ages. If there's no
> argument
> > otherwise I'll give it a read through and stick it in for 3.2.0.
>
> Yep, its certainly a candidate for 3.2, but I'd class the API as
> "experimental" at this stage and not commit to supporting it going
> forward as-is just yet.
Do you mean that the API is "xm" command interface such as "xm
scsihost-attach" or Xen-API?
If the former, we also consider the expansion of the interface is
needed. The interface should conform to VM migration that the VM can
continue to use same ID before and after the migration. On FC-SCSI,
the ID may be WWPN (World Wide Port Name).
> Things I'd like to see:
> * performance results (hopefully at the summit!)
We are planning to report performance data on next Xen Summit.
> * variable sized comms rings (fixed at connect time) so we can queue
> more descriptors if req'd.
> * support for pass through of individual scsi logical units to the
> dom0's linux scsi-generic layer rather than whole HBAs -- I think most
> users will want to hide all that FC nastiness and just present a LUN.
We also recognize the usefulness of above feature. However, I heard that
the method for specifying LUN is vender dependent. Implementation may be
difficult by non-technical reason.
-----
Jun Kamada
kama@jp.fujitsu.com
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-19 5:15 [PATCH 0/5] pvSCSI (SCSI pass through) driver Jun Kamada
2007-10-19 8:38 ` Keir Fraser
2007-10-22 0:07 ` James Harper
@ 2007-10-22 8:58 ` Keir Fraser
2007-10-23 7:09 ` Jun Kamada
2 siblings, 1 reply; 33+ messages in thread
From: Keir Fraser @ 2007-10-22 8:58 UTC (permalink / raw)
To: Jun Kamada, xen-devel
What's the CONFIG_XEN_FC stuff all about? It doesn't appear to be
configurable (so it's always off), it's ifdef'ed all over the place, and
there are dead files (e.g., fcfront.c) that presumably would depend on that
option.
Either it needs to be plumbed in properly, or the XEN_FC stuff needs to be
stripped out entirely from this patchset.
-- Keir
On 19/10/07 06:15, "Jun Kamada" <kama@jp.fujitsu.com> wrote:
> Hi all,
>
> I will send total five patches on following e-mails.
>
> These patches provide functionality that guest domain can issue
> complete SCSI command to FC-SCSI HBA(Fibre Channel SCSI Host Bus
> Adapter) assigned to the guest domain.
> Using this functionality, guest domain can control such as tape device
> for backup and so on.
>
> We hope these patches will be merged into Xen 3.2.0.
>
> Thanks,
>
> -----
> Jun Kamada
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-22 8:58 ` Keir Fraser
@ 2007-10-23 7:09 ` Jun Kamada
2007-10-23 8:50 ` Keir Fraser
0 siblings, 1 reply; 33+ messages in thread
From: Jun Kamada @ 2007-10-23 7:09 UTC (permalink / raw)
To: Keir Fraser; +Cc: kama, xen-devel
[-- Attachment #1: Type: text/plain, Size: 1057 bytes --]
Dear Keir-san,
On Mon, 22 Oct 2007 09:58:17 +0100
Keir Fraser <Keir.Fraser@cl.cam.ac.uk> wrote:
> What's the CONFIG_XEN_FC stuff all about? It doesn't appear to be
> configurable (so it's always off), it's ifdef'ed all over the place, and
> there are dead files (e.g., fcfront.c) that presumably would depend on that
> option.
>
> Either it needs to be plumbed in properly, or the XEN_FC stuff needs to be
> stripped out entirely from this patchset.
The CONFIG_XEN_FC stuff is used for activating FC(Fibre Channel)
transport layer functionality. I will attach additional patch for the
stuff.
Please note:
The FC transport functionality for PV driver on HVM domain is not
activated even if this stuff is set. It is only available for 2.6.18
kernel for PV domain.
This is why definition of "struct fc_function_template" used for the
FC transport functionality are differrent for each kernel version.
Therefore "#ifdef" switch is needed for each kernel version. We didn't
implement the switch on current implementation.
Best regards,
-----
Jun Kamada
[-- Attachment #2: modify_Make_for_CONFIG_XEN_FC.patch --]
[-- Type: application/octet-stream, Size: 2394 bytes --]
# HG changeset patch
# User t.horikoshi@jp.fujitsu.com
# Date 1193114725 -32400
# Node ID 9ca42e496ee3555e0576fcabd75942dca8b3825f
# Parent b8a4ef7c01aa345d820169266a6aa88c448f7aa5
[LINUX] modify Makefile for CONFIG_XEN_FC
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
diff -r b8a4ef7c01aa -r 9ca42e496ee3 drivers/xen/Kconfig
--- a/drivers/xen/Kconfig Fri Oct 19 08:59:03 2007 +0900
+++ b/drivers/xen/Kconfig Tue Oct 23 13:45:25 2007 +0900
@@ -61,6 +61,21 @@ config XEN_SCSI_BACKEND
help
The SCSI backend driver allows the kernel to export its SCSI HBAs
to other guests via a high-performance shared-memory interface.
+
+choice
+ prompt "SCSI Backend Mode"
+ depends on XEN_SCSI_BACKEND
+ default XEN_SCSI_BACKEND_SCSI
+
+config XEN_SCSI_BACKEND_SCSI
+ bool "Not FC"
+
+config XEN_FC
+ bool "FC driver support"
+ ---help---
+ The function of scsi_transport_fc is add.
+
+endchoice
config XEN_BLKDEV_TAP
tristate "Block-device tap backend driver"
diff -r b8a4ef7c01aa -r 9ca42e496ee3 drivers/xen/scsiback/Makefile
--- a/drivers/xen/scsiback/Makefile Fri Oct 19 08:59:03 2007 +0900
+++ b/drivers/xen/scsiback/Makefile Tue Oct 23 13:45:25 2007 +0900
@@ -1,2 +1,8 @@ obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-sc
-obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-scsibk.o
-xen-scsibk-y += interface.o scsiback.o xenbus.o comback.o traceback.o
+ifeq ($(CONFIG_XEN_FC),y)
+ EXTRA_CFLAGS += -DCONFIG_XEN_FC
+ obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-fcscsibk.o
+ xen-fcscsibk-y += interface.o scsiback.o xenbus.o fcback.o comback.o traceback.o
+else
+ obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-scsibk.o
+ xen-scsibk-y += interface.o scsiback.o xenbus.o comback.o traceback.o
+endif
diff -r b8a4ef7c01aa -r 9ca42e496ee3 drivers/xen/scsifront/Makefile
--- a/drivers/xen/scsifront/Makefile Fri Oct 19 08:59:03 2007 +0900
+++ b/drivers/xen/scsifront/Makefile Tue Oct 23 13:45:25 2007 +0900
@@ -1,2 +1,8 @@
+ifeq ($(CONFIG_XEN_FC),y)
+ EXTRA_CFLAGS += -DCONFIG_XEN_FC
+ obj-$(CONFIG_XEN_SCSI_FRONTEND) := xenfcscsi.o
+ xenfcscsi-objs := scsifront.o fcfront.o comfront.o tracefront.o
+else
obj-$(CONFIG_XEN_SCSI_FRONTEND) := xenscsi.o
xenscsi-objs := scsifront.o comfront.o tracefront.o
+endif
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-22 0:07 ` James Harper
@ 2007-10-23 7:41 ` Jun Kamada
0 siblings, 0 replies; 33+ messages in thread
From: Jun Kamada @ 2007-10-23 7:41 UTC (permalink / raw)
To: James Harper; +Cc: kama, xen-devel
Hi James-san,
Thank you for your interests in our pvSCSI driver.
On Mon, 22 Oct 2007 10:07:40 +1000
"James Harper" <james.harper@bendigoit.com.au> wrote:
> I am very interested in this functionality, but mainly from a Windows
> point of view (doing test restores of backups for customers). What would
> be involved in getting this working under a HVM domain in the absence of
> PV drivers?
>
> Failing that, I'll see if I can incorporate it into the Windows PV
> drivers I'm working on...
I appreciate your proposal because I don't have skill for developing
Windows driver. I suppose that the pvSCSI functionality is useful for
Windows too.
Thanks,
-----
Jun Kamada
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-23 7:09 ` Jun Kamada
@ 2007-10-23 8:50 ` Keir Fraser
2007-10-23 11:35 ` Jun Kamada
0 siblings, 1 reply; 33+ messages in thread
From: Keir Fraser @ 2007-10-23 8:50 UTC (permalink / raw)
To: Jun Kamada; +Cc: xen-devel
> The CONFIG_XEN_FC stuff is used for activating FC(Fibre Channel)
> transport layer functionality. I will attach additional patch for the
> stuff.
Okay, thanks.
Another question about the original patches: did you test that a 64-bit
backend can communicate with 32-bit frontend (and vice versa)? Either you
need to make sure that all the shared-memory structures defined in vscsiif.h
compile identically for 32-bit and 64-bit mode, or you need to detect the
frontend's 'bitness' in scsiback and optionally do 32-to-64 or 64-to-32
conversion. I think it's obvious which is less hassle. ;-)
Handling this is really a prerequisite for putting these patches into a
stable Xen release.
-- Keir
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-23 8:50 ` Keir Fraser
@ 2007-10-23 11:35 ` Jun Kamada
2007-10-23 12:39 ` Keir Fraser
0 siblings, 1 reply; 33+ messages in thread
From: Jun Kamada @ 2007-10-23 11:35 UTC (permalink / raw)
To: Keir Fraser; +Cc: kama, xen-devel
Keir-san,
On Tue, 23 Oct 2007 09:50:38 +0100
Keir Fraser <Keir.Fraser@cl.cam.ac.uk> wrote:
> Another question about the original patches: did you test that a 64-bit
> backend can communicate with 32-bit frontend (and vice versa)? Either you
> need to make sure that all the shared-memory structures defined in vscsiif.h
> compile identically for 32-bit and 64-bit mode, or you need to detect the
> frontend's 'bitness' in scsiback and optionally do 32-to-64 or 64-to-32
> conversion. I think it's obvious which is less hassle. ;-)
I suppose that the VBD uses the later method. (Is it right?) However,
the later method requires 'optimize level of frontend on compile time'
in addition to the 'bitness'. If the frontend is optimized for space,
members in structure are packed. On the other hand, if the frontend is
optimized for speed, each members are aligned on word boundary. (padding
will be inserted.)
How do you think about this?
> Handling this is really a prerequisite for putting these patches into a
> stable Xen release.
I would like to modify and post an additional patch ASAP.
-----
Jun Kamada
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-23 11:35 ` Jun Kamada
@ 2007-10-23 12:39 ` Keir Fraser
2007-10-24 6:22 ` Jun Kamada
0 siblings, 1 reply; 33+ messages in thread
From: Keir Fraser @ 2007-10-23 12:39 UTC (permalink / raw)
To: Jun Kamada; +Cc: xen-devel
On 23/10/07 12:35, "Jun Kamada" <kama@jp.fujitsu.com> wrote:
>> Another question about the original patches: did you test that a 64-bit
>> backend can communicate with 32-bit frontend (and vice versa)? Either you
>> need to make sure that all the shared-memory structures defined in vscsiif.h
>> compile identically for 32-bit and 64-bit mode, or you need to detect the
>> frontend's 'bitness' in scsiback and optionally do 32-to-64 or 64-to-32
>> conversion. I think it's obvious which is less hassle. ;-)
>
> I suppose that the VBD uses the later method. (Is it right?) However,
> the later method requires 'optimize level of frontend on compile time'
> in addition to the 'bitness'. If the frontend is optimized for space,
> members in structure are packed. On the other hand, if the frontend is
> optimized for speed, each members are aligned on word boundary. (padding
> will be inserted.)
> How do you think about this?
The layout of structures is part of the C ABI on the target system:
optimising compilation for space cannot change that (without explicit
pragmas or attributes being added to the code).
Anyway, the right answer is to ensure that your structures compile the same
whether compiled with 32-bit or 64-bit gcc. Check the structure sizes,
fields sizes and field offsets.
-- Keir
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-23 12:39 ` Keir Fraser
@ 2007-10-24 6:22 ` Jun Kamada
2007-10-24 7:42 ` Keir Fraser
0 siblings, 1 reply; 33+ messages in thread
From: Jun Kamada @ 2007-10-24 6:22 UTC (permalink / raw)
To: Keir Fraser; +Cc: kama, xen-devel
Dear Keir-san,
Can I ask one question for my correct understanding?
On Tue, 23 Oct 2007 13:39:24 +0100
Keir Fraser <Keir.Fraser@cl.cam.ac.uk> wrote:
> Anyway, the right answer is to ensure that your structures compile the same
> whether compiled with 32-bit or 64-bit gcc. Check the structure sizes,
> fields sizes and field offsets.
You showed me two options in previous email; i.) all the shared-memory
structures defined in vscsiif.h compile identically for 32-bit and
64-bit mode, ii.) to detect the frontend's 'bitness' in scsiback and
optionally do 32-to-64 or 64-to-32 conversion.
I consider that current VBD implementation takes option ii.), however
you recommended me to take option i.) for pvSCSI driver.
Is my understanding right?
Best regards,
-----
Jun Kamada
Linux Technology Development Div.
Server Systems Unit
Fujitsu Ltd.
kama@jp.fujitsu.com
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-24 6:22 ` Jun Kamada
@ 2007-10-24 7:42 ` Keir Fraser
2007-10-25 1:59 ` Jun Kamada
0 siblings, 1 reply; 33+ messages in thread
From: Keir Fraser @ 2007-10-24 7:42 UTC (permalink / raw)
To: Jun Kamada; +Cc: xen-devel
On 24/10/07 07:22, "Jun Kamada" <kama@jp.fujitsu.com> wrote:
>> Anyway, the right answer is to ensure that your structures compile the same
>> whether compiled with 32-bit or 64-bit gcc. Check the structure sizes,
>> fields sizes and field offsets.
>
> You showed me two options in previous email; i.) all the shared-memory
> structures defined in vscsiif.h compile identically for 32-bit and
> 64-bit mode, ii.) to detect the frontend's 'bitness' in scsiback and
> optionally do 32-to-64 or 64-to-32 conversion.
>
> I consider that current VBD implementation takes option ii.), however
> you recommended me to take option i.) for pvSCSI driver.
> Is my understanding right?
Yes. It was an accident we ended up with structures compiling differently on
32- vs 64-bit. By the time we discovered it was an issue, we couldn't break
backward compatibility.
-- Keir
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/5] pvSCSI (SCSI pass through) driver
2007-10-24 7:42 ` Keir Fraser
@ 2007-10-25 1:59 ` Jun Kamada
2007-10-30 10:39 ` [PATCH 0/6] " Jun Kamada
` (6 more replies)
0 siblings, 7 replies; 33+ messages in thread
From: Jun Kamada @ 2007-10-25 1:59 UTC (permalink / raw)
To: Keir Fraser; +Cc: kama, xen-devel
Keir-san,
On Wed, 24 Oct 2007 08:42:38 +0100
Keir Fraser <Keir.Fraser@cl.cam.ac.uk> wrote:
> On 24/10/07 07:22, "Jun Kamada" <kama@jp.fujitsu.com> wrote:
>
> >> Anyway, the right answer is to ensure that your structures compile the same
> >> whether compiled with 32-bit or 64-bit gcc. Check the structure sizes,
> >> fields sizes and field offsets.
> >
> > You showed me two options in previous email; i.) all the shared-memory
> > structures defined in vscsiif.h compile identically for 32-bit and
> > 64-bit mode, ii.) to detect the frontend's 'bitness' in scsiback and
> > optionally do 32-to-64 or 64-to-32 conversion.
> >
> > I consider that current VBD implementation takes option ii.), however
> > you recommended me to take option i.) for pvSCSI driver.
> > Is my understanding right?
>
> Yes. It was an accident we ended up with structures compiling differently on
> 32- vs 64-bit. By the time we discovered it was an issue, we couldn't break
> backward compatibility.
I understood. I'll try to modify the pvSCSI driver by option i.).
Best regards,
-----
Jun Kamada
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-10-25 1:59 ` Jun Kamada
@ 2007-10-30 10:39 ` Jun Kamada
2007-10-30 10:56 ` Keir Fraser
2007-11-01 12:14 ` Stephen C. Tweedie
2007-10-30 10:39 ` [PATCH 1/6] " Jun Kamada
` (5 subsequent siblings)
6 siblings, 2 replies; 33+ messages in thread
From: Jun Kamada @ 2007-10-30 10:39 UTC (permalink / raw)
Cc: kama, xen-devel
Keir-san,
I have finished the modification of the driver by option i.).
The pvSCSI driver can work on heterogeneous (x86_32 and x86_64)
environment.
I will attach total six patches on following mail.
Best regards,
On Thu, 25 Oct 2007 10:59:31 +0900
Jun Kamada <kama@jp.fujitsu.com> wrote:
> Keir-san,
>
> On Wed, 24 Oct 2007 08:42:38 +0100
> Keir Fraser <Keir.Fraser@cl.cam.ac.uk> wrote:
> > On 24/10/07 07:22, "Jun Kamada" <kama@jp.fujitsu.com> wrote:
> >
> > >> Anyway, the right answer is to ensure that your structures compile the same
> > >> whether compiled with 32-bit or 64-bit gcc. Check the structure sizes,
> > >> fields sizes and field offsets.
> > >
> > > You showed me two options in previous email; i.) all the shared-memory
> > > structures defined in vscsiif.h compile identically for 32-bit and
> > > 64-bit mode, ii.) to detect the frontend's 'bitness' in scsiback and
> > > optionally do 32-to-64 or 64-to-32 conversion.
> > >
> > > I consider that current VBD implementation takes option ii.), however
> > > you recommended me to take option i.) for pvSCSI driver.
> > > Is my understanding right?
> >
> > Yes. It was an accident we ended up with structures compiling differently on
> > 32- vs 64-bit. By the time we discovered it was an issue, we couldn't break
> > backward compatibility.
>
> I understood. I'll try to modify the pvSCSI driver by option i.).
>
> Best regards,
>
> -----
> Jun Kamada
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
-----
Jun Kamada
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 1/6] pvSCSI (SCSI pass through) driver
2007-10-25 1:59 ` Jun Kamada
2007-10-30 10:39 ` [PATCH 0/6] " Jun Kamada
@ 2007-10-30 10:39 ` Jun Kamada
2007-10-30 10:39 ` [PATCH 2/6] " Jun Kamada
` (4 subsequent siblings)
6 siblings, 0 replies; 33+ messages in thread
From: Jun Kamada @ 2007-10-30 10:39 UTC (permalink / raw)
Cc: kama, xen-devel
[-- Attachment #1: Type: text/plain, Size: 287 bytes --]
This patch is for frontend driver.
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
-----
Jun Kamada
[-- Attachment #2: linux_scsifront.patch --]
[-- Type: application/octet-stream, Size: 64658 bytes --]
# HG changeset patch
# User t.horikoshi@jp.fujitsu.com
# Date 1193730096 -32400
# Node ID 24e0cb9fe9df6f4a6df226823562bec3089072e6
# Parent 709db80c03c3d7606744a71f48f5186358a5e659
[LINUX][scsifront] add scsi frontend driver
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
diff -r 709db80c03c3 -r 24e0cb9fe9df drivers/xen/scsifront/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsifront/Makefile Tue Oct 30 16:41:36 2007 +0900
@@ -0,0 +1,8 @@
+ifeq ($(CONFIG_XEN_FC),y)
+ EXTRA_CFLAGS += -DCONFIG_XEN_FC
+ obj-$(CONFIG_XEN_SCSI_FRONTEND) := xenfcscsi.o
+ xenfcscsi-objs := scsifront.o fcfront.o comfront.o tracefront.o
+else
+ obj-$(CONFIG_XEN_SCSI_FRONTEND) := xenscsi.o
+ xenscsi-objs := scsifront.o comfront.o tracefront.o
+endif
diff -r 709db80c03c3 -r 24e0cb9fe9df drivers/xen/scsifront/comfront.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsifront/comfront.c Tue Oct 30 16:41:36 2007 +0900
@@ -0,0 +1,265 @@
+/*
+ * Xen SCSI frontend driver
+ *
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * Based on the scsifront driver code by FUJITA Tomonori
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+
+#include <linux/version.h>
+#include "comfront.h"
+
+extern int scsifront_cmd_done(struct comfront_info *, struct vscsiif_btf_request *);
+static void comfront_notify_work(struct comfront_info *info);
+#ifdef CONFIG_XEN_FC
+extern void fcfront_cmd_done(struct comfront_info *, struct vscsiif_btf_request *);
+#endif
+
+extern void scsi_trace(unsigned long, unsigned char *, unsigned int);
+
+static inline int GET_ID_FROM_FREELIST(struct comfront_info *info)
+{
+ unsigned long flags;
+ uint32_t free;
+
+ spin_lock_irqsave(&info->shadow_lock, flags);
+
+ free = info->shadow_free;
+ BUG_ON(free > DEFAULT_CAN_QUEUE);
+ info->shadow_free = info->shadow[free].rqid;
+ info->shadow[free].rqid = 0x0fffffee; /* debug */
+
+ info->shadow[free].cond = 0;
+
+ spin_unlock_irqrestore(&info->shadow_lock, flags);
+
+ return free;
+}
+
+void ADD_ID_TO_FREELIST(struct comfront_info *info, uint32_t id)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&info->shadow_lock, flags);
+
+ info->shadow[id].rqid = info->shadow_free;
+ info->shadow[id].u.scsi.req_scsi_cmnd = 0;
+ info->shadow_free = id;
+
+ spin_unlock_irqrestore(&info->shadow_lock, flags);
+}
+
+
+/* ------------------------------------------------------------ */
+/* for frontend to backend communication */
+/* ------------------------------------------------------------ */
+
+int read_ftb_ring_resp_cons(struct comfront_info *info)
+{
+ RING_IDX i, ftb_rp;
+ struct vscsiif_ftb_response *ring_res;
+ int err;
+
+ ftb_rp = info->ftb_ring.sring->rsp_prod;
+ err = SCSIIF_REQ_OKAY;
+ rmb();
+
+ for (i = info->ftb_ring.rsp_cons; i != ftb_rp; i++) {
+ ring_res = RING_GET_RESPONSE(&info->ftb_ring, i);
+
+ if (ring_res->status == SCSIIF_BTFRING_BUSY) {
+ err = SCSIIF_BTFRING_BUSY;
+ comfront_notify_work(info);
+ }
+ }
+
+ info->ftb_ring.rsp_cons = i;
+
+ return err;
+}
+
+struct vscsiif_ftb_request * comfront_pre_request(struct comfront_info *info)
+{
+ struct vscsiif_ftb_front_ring *ring = &(info->ftb_ring);
+ struct vscsiif_ftb_request *ring_req;
+ uint32_t id;
+
+ ring_req = RING_GET_REQUEST(&(info->ftb_ring), ring->req_prod_pvt);
+
+ id = GET_ID_FROM_FREELIST(info); /* use id by response */
+ ring_req->rqid = id;
+
+ return ring_req;
+}
+
+void comfront_do_request(struct comfront_info *info)
+{
+ struct vscsiif_ftb_front_ring *ring = &(info->ftb_ring);
+ unsigned int irq = info->irq;
+ int notify;
+
+ ring->req_prod_pvt++;
+
+ RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(ring, notify);
+
+ if (notify)
+ notify_remote_via_irq(irq);
+
+ /***** Front to Back response consume *****/
+ read_ftb_ring_resp_cons(info);
+}
+
+
+/* ------------------------------------------------------------ */
+/* for backend to frontend communication */
+/* ------------------------------------------------------------ */
+
+static void comfront_notify_work(struct comfront_info *info)
+{
+
+ info->waiting_resp = 1;
+ wake_up(&info->wq);
+}
+
+irqreturn_t comfront_intr(int irq, void *dev_id, struct pt_regs *ptregs)
+{
+ comfront_notify_work((struct comfront_info *)dev_id);
+ return IRQ_HANDLED;
+}
+
+static void __sync_cmd_done(struct comfront_info *info,
+ struct vscsiif_btf_request *btf_req)
+{
+ uint32_t id = btf_req->rqid;
+
+ info->btf_req = *btf_req;
+
+ info->shadow[id].cond++;
+ wake_up(&(info->shadow[id].wq));
+}
+
+int do_comfront_cmd_done(struct comfront_info *info)
+{
+ struct vscsiif_btf_back_ring *btf_ring = &info->btf_ring;
+ struct vscsiif_btf_request *btf_req;
+
+ int btf_rc, btf_rp;
+ int more_to_do = 0;
+
+ if (info->dev->state != XenbusStateConnected)
+ return 0;
+
+ /***** Back to Front request consume *****/
+ DPRINTK("%s\n",__FUNCTION__);
+
+ btf_rc = btf_ring->req_cons;
+ btf_rp = btf_ring->sring->req_prod;
+
+ while ((btf_rc != btf_rp) &&
+ !RING_REQUEST_CONS_OVERFLOW(btf_ring, btf_rc)) {
+
+ rmb();
+ btf_req = RING_GET_REQUEST(btf_ring, btf_rc);
+ btf_ring->req_cons = ++btf_rc;
+
+ if (info->shadow[btf_req->rqid].cmnd == CMND_SCSI) {
+ scsi_trace(2, (unsigned char *)btf_req,
+ sizeof(struct vscsiif_btf_request));
+
+ if (scsifront_cmd_done(info, btf_req)) {
+ BUG();
+ }
+
+ } else {
+ __sync_cmd_done(info, btf_req);
+ }
+
+ btf_ring->rsp_prod_pvt++;
+ RING_PUSH_RESPONSES(btf_ring);
+ }
+
+ if (btf_ring->rsp_prod_pvt == btf_rc) {
+ RING_FINAL_CHECK_FOR_REQUESTS(btf_ring, more_to_do);
+
+ } else if (RING_HAS_UNCONSUMED_REQUESTS(btf_ring)) {
+ more_to_do = 1;
+ }
+
+ return more_to_do;
+}
+
+int comfront_schedule(void *data)
+{
+ struct comfront_info *info = (struct comfront_info *)data;
+
+ while (!kthread_should_stop()) {
+ wait_event_interruptible(
+ info->wq,
+ info->waiting_resp || kthread_should_stop());
+
+ info->waiting_resp = 0;
+ smp_mb();
+
+ if (do_comfront_cmd_done(info))
+ info->waiting_resp = 1;
+
+ read_ftb_ring_resp_cons(info);
+
+ }
+
+ info->kthread = NULL;
+
+ return 0;
+}
+
+struct vscsiif_btf_request *comfront_do_request_and_wait_response(
+ struct comfront_info *info,
+ struct vscsiif_ftb_request *ring_req)
+{
+ struct vscsiif_btf_request *ring_res;
+ uint32_t rqid = ring_req->rqid;
+
+ info->shadow[rqid].cmnd = ring_req->cmnd;
+
+ scsi_trace(1, (unsigned char *)ring_req,
+ sizeof(struct vscsiif_ftb_request));
+
+ comfront_do_request(info);
+ wait_event_interruptible(info->shadow[rqid].wq,
+ info->shadow[rqid].cond);
+ info->shadow[rqid].cond--;
+
+ ADD_ID_TO_FREELIST(info, rqid);
+
+ ring_res = &(info->btf_req);
+
+ scsi_trace(2, (unsigned char *)ring_res,
+ sizeof(struct vscsiif_btf_request));
+
+ return ring_res;
+}
diff -r 709db80c03c3 -r 24e0cb9fe9df drivers/xen/scsifront/comfront.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsifront/comfront.h Tue Oct 30 16:41:36 2007 +0900
@@ -0,0 +1,130 @@
+/*
+ * Xen SCSI frontend driver
+ *
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * Based on the scsifront driver code by FUJITA Tomonori
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __XEN_DRIVERS_SCSIFRONT_H__
+#define __XEN_DRIVERS_SCSIFRONT_H__
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/blkdev.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#ifdef CONFIG_XEN_FC
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+#endif
+#include <xen/xenbus.h>
+#include <xen/gnttab.h>
+#include <xen/evtchn.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/io/ring.h>
+#include <xen/interface/io/vscsiif.h>
+#include <asm/delay.h>
+
+
+#define GRANT_INVALID_REF 0
+
+struct comfront_shadow {
+ uint32_t rqid;
+ unsigned int cmnd;
+ wait_queue_head_t wq;
+ int cond;
+ union {
+ struct {
+ unsigned int sc_data_direction;
+ unsigned int use_sg;
+ unsigned int request_bufflen;
+ unsigned long req_scsi_cmnd;
+ int gref[SG_TABLESIZE];
+ } scsi;
+#ifdef CONFIG_XEN_FC
+ struct {
+ } fc;
+#endif
+ } u;
+};
+
+struct comfront_info {
+ struct xenbus_device *dev;
+ struct Scsi_Host *host;
+ spinlock_t io_lock;
+ spinlock_t shadow_lock;
+ unsigned int evtchn;
+ unsigned int irq;
+ int ftb_ring_ref;
+ int btf_ring_ref;
+ struct vscsiif_ftb_front_ring ftb_ring;
+ struct vscsiif_btf_back_ring btf_ring;
+ struct comfront_shadow shadow[DEFAULT_CAN_QUEUE];
+ uint32_t shadow_free;
+ struct vscsiif_btf_request btf_req;
+
+ struct task_struct *kthread;
+ wait_queue_head_t wq;
+ unsigned int waiting_resp;
+
+ void *fcinfo;
+};
+
+#define DPRINTK(_f, _a...) \
+ pr_debug("(file=%s, line=%d) " _f, \
+ __FILE__ , __LINE__ , ## _a )
+
+
+void ADD_ID_TO_FREELIST(struct comfront_info *info, uint32_t id);
+
+#ifdef CONFIG_XEN_FC
+extern int fcfront_get_initial_attribute(struct comfront_info *cominfo);
+extern int fcfront_get_function_template(struct comfront_info *cominfo);
+extern int fcfront_connection_setup(struct comfront_info *cominfo);
+extern void fcfront_connection_unsetup(struct comfront_info *cominfo);
+#endif
+
+
+struct vscsiif_ftb_request * comfront_pre_request(struct comfront_info *);
+struct vscsiif_btf_request *comfront_do_request_and_wait_response(
+ struct comfront_info *info,
+ struct vscsiif_ftb_request *ring_req);
+void comfront_do_request(struct comfront_info *);
+irqreturn_t comfront_intr(int, void *, struct pt_regs *);
+int comfront_schedule(void *);
+
+#endif /* __XEN_DRIVERS_SCSIFRONT_H__ */
diff -r 709db80c03c3 -r 24e0cb9fe9df drivers/xen/scsifront/fcfront.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsifront/fcfront.c Tue Oct 30 16:41:36 2007 +0900
@@ -0,0 +1,777 @@
+/*
+ * Xen SCSI FC frontend driver
+ *
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * Based on the scsifront driver code by FUJITA Tomonori
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/version.h>
+#include "comfront.h"
+#include "fcfront.h"
+
+
+extern void notify_remote_via_irq(int);
+extern int irq_to_evtchn_port(int);
+extern int bind_listening_port_to_irqhandler(unsigned int,
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long, const char *, void *);
+extern void unbind_from_irqhandler(unsigned int, void *);
+extern int gnttab_grant_foreign_access(domid_t, unsigned long, int);
+extern int gnttab_end_foreign_access_ref(grant_ref_t, int);
+extern void gnttab_end_foreign_access(grant_ref_t, int, unsigned long);
+
+extern struct vscsiif_ftb_request *comfront_pre_request(struct comfront_info *);
+extern void comfront_do_request(struct comfront_info *);
+
+extern struct vscsiif_btf_request *comfront_do_request_and_wait_response(
+ struct comfront_info *,
+ struct vscsiif_ftb_request *);
+
+
+
+/* ---------------------------------------------------------------------- */
+
+static void fc_get_host_port_id(struct Scsi_Host *shost)
+{
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_HOST_PORT_ID;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ fc_host_port_id(shost) = ring_res->u.ghpi.port_id;
+ } else {
+ fc_host_port_id(shost) = (u32)0xffffffff;
+ }
+
+}
+
+static void fc_get_host_port_type(struct Scsi_Host *shost)
+{
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_HOST_PORT_TYPE;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ fc_host_port_type(shost) = ring_res->u.ghpt.port_type;
+ } else {
+ fc_host_port_type(shost) = (u32)0xffffffff;
+ }
+
+}
+
+static void fc_get_host_port_state(struct Scsi_Host *shost)
+{
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_HOST_PORT_STATE;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ fc_host_port_state(shost) = ring_res->u.ghps.port_state;
+ } else {
+ fc_host_port_state(shost) = (u32)0xffffffff;
+ }
+
+}
+
+static void fc_get_host_active_fc4s(struct Scsi_Host *shost)
+{
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_HOST_ACTIVE_FC4S;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ memcpy(fc_host_active_fc4s(shost),
+ ring_res->u.ghaf.active_fc4s,
+ sizeof(fc_host_active_fc4s(shost)));
+ } else {
+ memset(fc_host_active_fc4s(shost), 0,
+ sizeof(fc_host_active_fc4s(shost)));
+ }
+
+}
+
+static void fc_get_host_speed(struct Scsi_Host *shost)
+{
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_HOST_SPEED;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ fc_host_speed(shost) = ring_res->u.ghsp.speed;
+ } else {
+ fc_host_speed(shost) = (u32)0xffffffff;
+ }
+
+}
+
+static void fc_get_host_fabric_name(struct Scsi_Host *shost)
+{
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_HOST_FABRIC_NAME;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ fc_host_fabric_name(shost) = ring_res->u.ghfn.fabric_name;
+ } else {
+ fc_host_fabric_name(shost) = (u32)0xffffffff;
+ }
+
+}
+
+static struct fc_host_statistics * fc_get_stats(struct Scsi_Host *shost)
+{
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct fcfront_info *fcinfo = (struct fcfront_info *)
+ (cominfo->fcinfo);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+ struct fc_host_statistics *ret;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_HOST_STATS;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ /* "info->hs" is appropriate position ? */
+ memcpy(&(fcinfo->hs), &(ring_res->u.ghst.stats),
+ sizeof(fcinfo->hs));
+ ret = &(ring_res->u.ghst.stats);
+ } else {
+ ret = NULL;
+ }
+
+ return ret;
+}
+
+static void fc_reset_stats(struct Scsi_Host *shost)
+{
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_RESET_HOST_STATS;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+}
+
+static int fc_issue_lip(struct Scsi_Host *shost)
+{
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_ISSUE_HOST_LIP;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ return ring_res->rslt;
+}
+
+static void fc_get_starget_port_id(struct scsi_target *starget)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_STARGET_PORT_ID;
+ ring_req->u.gtpi.channel = starget->channel;
+ ring_req->u.gtpi.id = starget->id;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ fc_starget_port_id(starget) = ring_res->u.gtpi.port_id;
+ } else {
+ fc_starget_port_id(starget) = (u32)0xffffffff;
+ }
+
+}
+
+static void fc_get_starget_node_name(struct scsi_target *starget)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_STARGET_NODE_NAME;
+ ring_req->u.gtnn.channel = starget->channel;
+ ring_req->u.gtnn.id = starget->id;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ fc_starget_node_name(starget) = ring_res->u.gtnn.node_name;
+ } else {
+ fc_starget_node_name(starget) = (u32)0xffffffff;
+ }
+
+}
+
+static void fc_get_starget_port_name(struct scsi_target *starget)
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_STARGET_PORT_NAME;
+ ring_req->u.gtpn.channel = starget->channel;
+ ring_req->u.gtpn.id = starget->id;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ fc_starget_port_name(starget) = ring_res->u.gtpn.port_name;
+ } else {
+ fc_starget_port_name(starget) = (u32)0xffffffff;
+ }
+
+}
+
+static void fc_get_rport_loss_tmo(struct fc_rport *rport)
+{
+ struct Scsi_Host *shost = rport_to_shost(rport);
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_RPORT_LOSS_TMO;
+ ring_req->u.gplt.node_name = rport->node_name;
+ ring_req->u.gplt.port_name = rport->port_name;
+ ring_req->u.gplt.port_id = rport->port_id;
+ ring_req->u.gplt.roles = rport->roles;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ rport->dev_loss_tmo = ring_res->u.gplt.timeout;
+ } else {
+ rport->dev_loss_tmo = (u32)0xffffffff;
+ }
+
+}
+
+static void fc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
+{
+ struct Scsi_Host *shost = rport_to_shost(rport);
+ struct comfront_info *cominfo = (struct comfront_info *)
+ (shost->hostdata);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_SET_RPORT_LOSS_TMO;
+ ring_req->u.splt.node_name = rport->node_name;
+ ring_req->u.splt.port_name = rport->port_name;
+ ring_req->u.splt.port_id = rport->port_id;
+ ring_req->u.splt.roles = rport->roles;
+ ring_req->u.splt.timeout = timeout;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+ rport->dev_loss_tmo = ring_res->u.splt.timeout;
+ } else {
+ rport->dev_loss_tmo = (u32)0xffffffff;
+ }
+
+}
+
+struct fc_function_template fc_transport_functions = {
+ .get_rport_dev_loss_tmo = fc_get_rport_loss_tmo,
+ .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
+ .get_starget_node_name = fc_get_starget_node_name,
+ .get_starget_port_name = fc_get_starget_port_name,
+ .get_starget_port_id = fc_get_starget_port_id,
+ .get_host_port_id = fc_get_host_port_id,
+ .get_host_port_type = fc_get_host_port_type,
+ .get_host_port_state = fc_get_host_port_state,
+ .get_host_active_fc4s = fc_get_host_active_fc4s,
+ /* lpfc does not support */
+ .get_host_speed = fc_get_host_speed,
+ .get_host_fabric_name = fc_get_host_fabric_name,
+ .get_fc_host_stats = fc_get_stats,
+ .reset_fc_host_stats = fc_reset_stats,
+ .issue_fc_host_lip = fc_issue_lip,
+
+ /* remote port fixed attributes */
+ .show_rport_maxframe_size = 1,
+ .show_rport_supported_classes = 1,
+ .show_rport_dev_loss_tmo = 1,
+
+ /* target dynamic attributes */
+ .show_starget_node_name = 1,
+ .show_starget_port_name = 1,
+ .show_starget_port_id = 1,
+
+ /* host fixed attributes */
+ .show_host_node_name = 1,
+ .show_host_port_name = 1,
+ .show_host_permanent_port_name = 1, /* lpfc does not support */
+ .show_host_supported_classes = 1,
+ .show_host_supported_fc4s = 1,
+ .show_host_symbolic_name = 1,
+ .show_host_supported_speeds = 1,
+ .show_host_maxframe_size = 1,
+ .show_host_serial_number = 1, /* lpfc does not support */
+
+ /* host dynamic attribute */
+ .show_host_port_id = 1,
+ .show_host_port_type = 1,
+ .show_host_port_state = 1,
+ .show_host_active_fc4s = 1,
+ .show_host_speed = 1,
+ .show_host_fabric_name = 1,
+};
+
+
+/* ---------------------------------------------------------------------- */
+
+static int __setup_grant_table(struct fcfront_info *info)
+{
+ void *addr;
+ int gntref;
+
+ if ((addr = kmalloc(PAGE_SIZE, GFP_KERNEL)) == NULL) {
+ return -ENOMEM;
+ }
+
+ gntref = gnttab_grant_foreign_access(info->cominfo->dev->otherend_id,
+ virt_to_mfn(addr), 0);
+ if (gntref < 0) {
+ printk(KERN_ERR
+ "fcfront: %s: gnttab_grant_foreign_access() error\n",
+ __FUNCTION__);
+ return gntref;
+ }
+
+ info->addr = addr;
+ info->gntref = gntref;
+
+ return 0;
+}
+
+static void __unsetup_grant_table(struct fcfront_info *info)
+{
+ /* currently, nothing to do */
+}
+
+static int __setup_xenstore(struct fcfront_info *info)
+{
+ struct xenbus_device *dev = info->cominfo->dev;
+ struct xenbus_transaction xbt;
+ int ret = 0;
+
+again:
+ if ((ret = xenbus_transaction_start(&xbt)) != 0) {
+ printk(KERN_ERR
+ "fcfront: %s: xenbus_transaction_start() error\n",
+ __FUNCTION__);
+ goto out0;
+ }
+
+ if ((ret = xenbus_printf(xbt, dev->nodename,
+ "fc_gntref", "%d", info->gntref)) != 0) {
+ printk(KERN_ERR "fcfront: %s: xenbus_printf() error\n",
+ __FUNCTION__);
+ goto out1;
+ }
+
+ if ((ret = xenbus_transaction_end(xbt, 0)) != 0) {
+ if (ret == -EAGAIN) {
+ goto again;
+ } else {
+ printk(KERN_ERR
+ "fcfront: %s: xenbus_transaction_end() error\n",
+ __FUNCTION__);
+ goto out0;
+ }
+ }
+
+ return 0;
+
+out1:
+ (void)xenbus_transaction_end(xbt, 0);
+
+out0:
+ return ret;
+}
+
+static void __unsetup_xenstore(struct fcfront_info *info)
+{
+ /* currently, nothing to do */
+}
+
+int fcfront_connection_setup(struct comfront_info *cominfo)
+{
+ struct fcfront_info *info;
+ int ret;
+
+#if 0 /* for DEBUG */
+ printk(KERN_ERR "%s: giha=%ld\n", sizeof(struct giha), __FUNCTION__);
+ printk(KERN_ERR "%s: gita=%ld\n", sizeof(struct gita), __FUNCTION__);
+ printk(KERN_ERR "%s: gipa=%ld\n", sizeof(struct gipa), __FUNCTION__);
+ printk(KERN_ERR "%s: gftp=%ld\n", sizeof(struct gftp), __FUNCTION__);
+#endif
+
+ {
+ cominfo->fcinfo = kmalloc(sizeof(struct fcfront_info),
+ GFP_KERNEL);
+ if (cominfo->fcinfo == NULL) {
+ ret = -ENOMEM;
+ goto out0;
+ }
+ memset(cominfo->fcinfo, 0, sizeof(struct fcfront_info));
+ info = (struct fcfront_info *)(cominfo->fcinfo);
+ info->cominfo = cominfo;
+ }
+
+ /* prepare for grant table */
+ if ((ret = __setup_grant_table(info)) != 0) {
+ printk(KERN_ERR "fcfront: %s: __setup_grant_table() error\n",
+ __FUNCTION__);
+ goto out1;
+ }
+
+ /* exchange various parameters through xenstore */
+ if ((ret = __setup_xenstore(info)) != 0) {
+ printk(KERN_ERR "fcfront: %s: "
+ "__setup_xenstore() error\n", __FUNCTION__);
+ goto out2;
+ }
+
+ return 0;
+
+out2:
+ __unsetup_grant_table(info);
+
+out1:
+ kfree(cominfo->fcinfo);
+
+out0:
+ return ret;
+}
+
+void fcfront_connection_unsetup(struct comfront_info *cominfo)
+{
+ struct fcfront_info *info = (struct fcfront_info *)(cominfo->fcinfo);
+
+ __unsetup_xenstore(info);
+ __unsetup_grant_table(info);
+
+ kfree(cominfo->fcinfo);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+static int __get_host_attrib(struct comfront_info *cominfo)
+{
+ struct fcfront_info *fcinfo = (struct fcfront_info *)(cominfo->fcinfo);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+ struct fc_host_attrs *host_attrs =
+ (struct fc_host_attrs *)(cominfo->host->shost_data);
+ struct giha *giha = (struct giha *)(fcinfo->addr);
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_INITIAL_SHOST_ATTRIB;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt != 0) {
+ return 0;
+ }
+
+ memcpy(host_attrs->active_fc4s, giha->active_fc4s,
+ sizeof(host_attrs->active_fc4s));
+ host_attrs->fabric_name = giha->fabric_name;
+ host_attrs->maxframe_size = giha->maxframe_size;
+ host_attrs->node_name = giha->node_name;
+ host_attrs->permanent_port_name = giha->permanent_port_name;
+ host_attrs->port_id = giha->port_id;
+ host_attrs->port_name = giha->port_name;
+ host_attrs->port_state = giha->port_state;
+ host_attrs->port_type = giha->port_type;
+ memcpy(host_attrs->serial_number, giha->serial_number,
+ sizeof(host_attrs->serial_number));
+ host_attrs->speed = giha->speed;
+ /* "fcinfo->hs" is appropriate position ? */
+ memcpy(&(fcinfo->hs), &(giha->stats), sizeof(fcinfo->hs));
+ host_attrs->supported_classes = giha->supported_classes;
+ memcpy(host_attrs->supported_fc4s, giha->supported_fc4s,
+ sizeof(host_attrs->supported_fc4s));
+ host_attrs->supported_speeds = giha->supported_speeds;
+ memcpy(host_attrs->symbolic_name, giha->symbolic_name,
+ sizeof(host_attrs->symbolic_name));
+ host_attrs->tgtid_bind_type = giha->tgtid_bind_type;
+
+ return 0;
+}
+
+static int __get_target_attrib(struct comfront_info *cominfo)
+{
+ struct fcfront_info *fcinfo = (struct fcfront_info *)(cominfo->fcinfo);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+ struct scsi_target *starget;
+ struct fc_starget_attrs *starget_attrs;
+ struct gita *gita = (struct gita *)(fcinfo->addr);
+ unsigned int i;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_INITIAL_STARGET_ATTRIB;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt != 0) {
+ return 0;
+ }
+
+ for (i = 0; i < gita->num; i++) {
+ list_for_each_entry(starget, &(cominfo->host->__targets),
+ siblings) {
+ starget_attrs = (struct fc_starget_attrs *)
+ (&(starget->starget_data));
+ if ((starget->channel == gita->e[i].channel) &&
+ (starget->id == gita->e[i].id)) {
+ starget_attrs->node_name =
+ gita->e[i].node_name;
+ starget_attrs->port_id =
+ gita->e[i].port_id;
+ starget_attrs->port_name =
+ gita->e[i].port_name;
+ break;
+ } else {
+ /* printk(KERN_ERR
+ "fcfront: %s: SCSI target not added\n",
+ __FUNCTION__);*/
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int __get_port_attrib(struct comfront_info *cominfo)
+{
+ struct fcfront_info *fcinfo = (struct fcfront_info *)(cominfo->fcinfo);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+ int channel;
+ struct fc_rport_identifiers ids;
+ struct fc_rport *rport;
+ struct gipa *gipa = (struct gipa *)(fcinfo->addr);
+ unsigned int i;
+ int ret = 0;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_INITIAL_RPORT_ATTRIB;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt != 0) {
+ return ret;
+ }
+
+ for (i = 0; i < gipa->num; i++) {
+ channel = gipa->e[i].channel;
+ ids.node_name = gipa->e[i].node_name;
+ ids.port_id = gipa->e[i].port_id;
+ ids.port_name = gipa->e[i].port_name;
+ ids.roles = gipa->e[i].roles;
+
+ rport = fc_remote_port_add(cominfo->host, channel, &ids);
+ if (rport == NULL) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ rport->dev_loss_tmo = gipa->e[i].dev_loss_tmo;
+ rport->maxframe_size = gipa->e[i].maxframe_size;
+ rport->port_state = gipa->e[i].port_state;
+ rport->scsi_target_id = gipa->e[i].scsi_target_id;
+ rport->supported_classes = gipa->e[i].supported_classes;
+ }
+
+ return ret;
+}
+
+int fcfront_get_initial_attribute(struct comfront_info *cominfo)
+{
+ int ret = 0;
+
+ /* get SCSI host attributes */
+ (void)__get_host_attrib(cominfo);
+
+ /* get SCSI target attributes */
+ (void)__get_target_attrib(cominfo);
+
+ /* get remote port attibutes */
+ ret = __get_port_attrib(cominfo);
+
+ return ret;
+}
+
+#define CORRECT_FT(s, f, v, d) \
+ if (((s)->f) == (v)) { \
+ (d)->f = (v); \
+ }
+
+int fcfront_get_function_template(struct comfront_info *cominfo)
+{
+ struct fcfront_info *fcinfo = (struct fcfront_info *)(cominfo->fcinfo);
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+ struct gftp *gftp = (struct gftp *)(fcinfo->addr);
+ struct fc_function_template_shared *ft = &(gftp->ft);
+ struct fc_function_template *pvfcft = &fc_transport_functions;
+
+ ring_req = comfront_pre_request(cominfo);
+
+ ring_req->cmnd = CMND_GET_FUNCTION_TEMPLATE;
+
+ ring_res = comfront_do_request_and_wait_response(cominfo, ring_req);
+
+ if (ring_res->rslt == 0) {
+
+ CORRECT_FT(ft, get_rport_dev_loss_tmo, 0, pvfcft);
+ CORRECT_FT(ft, set_rport_dev_loss_tmo, 0, pvfcft);
+ CORRECT_FT(ft, get_starget_node_name, 0, pvfcft);
+ CORRECT_FT(ft, get_starget_port_name, 0, pvfcft);
+ CORRECT_FT(ft, get_starget_port_id, 0, pvfcft);
+ CORRECT_FT(ft, get_host_port_id, 0, pvfcft);
+ CORRECT_FT(ft, get_host_port_type, 0, pvfcft);
+ CORRECT_FT(ft, get_host_port_state, 0, pvfcft);
+ CORRECT_FT(ft, get_host_active_fc4s, 0, pvfcft);
+ CORRECT_FT(ft, get_host_speed, 0, pvfcft);
+ CORRECT_FT(ft, get_host_fabric_name, 0, pvfcft);
+ CORRECT_FT(ft, get_fc_host_stats, 0, pvfcft);
+ CORRECT_FT(ft, reset_fc_host_stats, 0, pvfcft);
+ CORRECT_FT(ft, issue_fc_host_lip, 0, pvfcft);
+
+ pvfcft->dd_fcrport_size = ft->dd_fcrport_size;
+
+ CORRECT_FT(ft, show_rport_maxframe_size, 0, pvfcft);
+ CORRECT_FT(ft, show_rport_supported_classes, 0, pvfcft);
+ CORRECT_FT(ft, show_rport_dev_loss_tmo, 0, pvfcft);
+ CORRECT_FT(ft, show_starget_node_name, 0, pvfcft);
+ CORRECT_FT(ft, show_starget_port_name, 0, pvfcft);
+ CORRECT_FT(ft, show_starget_port_id, 0, pvfcft);
+ CORRECT_FT(ft, show_host_node_name, 0, pvfcft);
+ CORRECT_FT(ft, show_host_port_name, 0, pvfcft);
+ CORRECT_FT(ft, show_host_permanent_port_name, 0, pvfcft);
+ CORRECT_FT(ft, show_host_supported_classes, 0, pvfcft);
+ CORRECT_FT(ft, show_host_supported_fc4s, 0, pvfcft);
+ CORRECT_FT(ft, show_host_symbolic_name, 0, pvfcft);
+ CORRECT_FT(ft, show_host_supported_speeds, 0, pvfcft);
+ CORRECT_FT(ft, show_host_maxframe_size, 0, pvfcft);
+ CORRECT_FT(ft, show_host_serial_number, 0, pvfcft);
+ CORRECT_FT(ft, show_host_port_id, 0, pvfcft);
+ CORRECT_FT(ft, show_host_port_type, 0, pvfcft);
+ CORRECT_FT(ft, show_host_port_state, 0, pvfcft);
+ CORRECT_FT(ft, show_host_active_fc4s, 0, pvfcft);
+ CORRECT_FT(ft, show_host_speed, 0, pvfcft);
+ CORRECT_FT(ft, show_host_fabric_name, 0, pvfcft);
+ }
+
+ return 0;
+}
+
+MODULE_DESCRIPTION("Xen Para-Virtual SCSI Fibre Channel Frontend Driver");
+MODULE_LICENSE("GPL");
diff -r 709db80c03c3 -r 24e0cb9fe9df drivers/xen/scsifront/fcfront.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsifront/fcfront.h Tue Oct 30 16:41:36 2007 +0900
@@ -0,0 +1,179 @@
+/*
+ * Xen SCSI frontend driver
+ *
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * Based on the scsifront driver code by FUJITA Tomonori
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+
+#ifndef __XEN_DRIVERS_FCFRONT_H__
+#define __XEN_DRIVERS_FCFRONT_H__
+
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+
+/* ----------------------------------------------------------------------
+ Definition of Grant Table Structures
+ ---------------------------------------------------------------------- */
+
+#define SCSI_FC_MAX_STARGET 32 /* limited by PAGE_SIZE */
+#define SCSI_FC_MAX_RPORT 32 /* limited by PAGE_SIZE */
+
+struct giha {
+ u8 active_fc4s[FC_FC4_LIST_SIZE];
+ u64 fabric_name;
+ u64 node_name;
+ u64 permanent_port_name;
+ u32 maxframe_size;
+ u32 port_id;
+ u64 port_name;
+ enum fc_port_state port_state;
+ enum fc_port_type port_type;
+ char serial_number[FC_SERIAL_NUMBER_SIZE];
+ struct fc_host_statistics stats;
+ u32 speed;
+ u32 supported_classes;
+ u8 supported_fc4s[FC_FC4_LIST_SIZE];
+ char symbolic_name[FC_SYMBOLIC_NAME_SIZE];
+ u32 supported_speeds;
+ enum fc_tgtid_binding_type tgtid_bind_type;
+};
+
+struct gita {
+ u32 num;
+ u32 padding1;
+ struct {
+ u64 node_name;
+ u64 port_name;
+ u32 port_id;
+ u32 channel;
+ u32 id;
+ u32 padding2;
+ } e[SCSI_FC_MAX_STARGET];
+};
+
+struct gipa {
+ u32 num;
+ u32 padding1;
+ struct {
+ u32 dev_loss_tmo;
+ u32 maxframe_size;
+ u64 node_name;
+ u64 port_name;
+ u32 port_id;
+ enum fc_port_state port_state;
+ u32 roles;
+ u32 scsi_target_id;
+ u32 supported_classes;
+ u32 channel;
+ } e[SCSI_FC_MAX_RPORT];
+};
+
+struct fc_function_template_shared {
+ u64 get_rport_dev_loss_tmo:1;
+ u64 set_rport_dev_loss_tmo:1;
+ u64 get_starget_node_name:1;
+ u64 get_starget_port_name:1;
+ u64 get_starget_port_id:1;
+ u64 get_host_port_id:1;
+ u64 get_host_port_type:1;
+ u64 get_host_port_state:1;
+ u64 get_host_active_fc4s:1;
+ u64 get_host_speed:1;
+ u64 get_host_fabric_name:1;
+ u64 get_fc_host_stats:1;
+ u64 reset_fc_host_stats:1;
+ u64 issue_fc_host_lip:1;
+ u64 padding1:50;
+
+ u64 show_rport_maxframe_size:1;
+ u64 show_rport_supported_classes:1;
+ u64 show_rport_dev_loss_tmo:1;
+ u64 show_starget_node_name:1;
+ u64 show_starget_port_name:1;
+ u64 show_starget_port_id:1;
+ u64 show_host_node_name:1;
+ u64 show_host_port_name:1;
+ u64 show_host_permanent_port_name:1;
+ u64 show_host_supported_classes:1;
+ u64 show_host_supported_fc4s:1;
+ u64 show_host_symbolic_name:1;
+ u64 show_host_supported_speeds:1;
+ u64 show_host_maxframe_size:1;
+ u64 show_host_serial_number:1;
+ u64 show_host_port_id:1;
+ u64 show_host_port_type:1;
+ u64 show_host_port_state:1;
+ u64 show_host_active_fc4s:1;
+ u64 show_host_speed:1;
+ u64 show_host_fabric_name:1;
+ u64 padding2:43;
+
+ u32 dd_fcrport_size;
+ u32 padding3;
+};
+
+struct gftp {
+ struct fc_function_template_shared ft;
+};
+
+
+/* ----------------------------------------------------------------------
+ Definition of Internal Information Structures
+ ---------------------------------------------------------------------- */
+
+struct fcfront_info {
+ struct comfront_info *cominfo;
+
+ int gntref;
+ void *addr;
+
+ /* On backend, "hs" is stored in ***_hba */
+ struct fc_host_statistics hs;
+};
+
+struct fcback_info {
+ struct comback_info *cominfo;
+
+ int gntref;
+ struct vm_struct *gnt_area;
+
+ struct vscsiif_ftb_request ftb_req;
+};
+
+
+/* ----------------------------------------------------------------------
+ Definition of Front/Back common functions
+ ---------------------------------------------------------------------- */
+
+struct fc_internal_head {
+ struct scsi_transport_template t;
+ struct fc_function_template *f;
+};
+
+#endif /*__XEN_DRIVERS_FCFRONT_H__*/
diff -r 709db80c03c3 -r 24e0cb9fe9df drivers/xen/scsifront/scsifront.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsifront/scsifront.c Tue Oct 30 16:41:36 2007 +0900
@@ -0,0 +1,739 @@
+/*
+ * Xen SCSI frontend driver
+ *
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * Based on the scsifront driver code by FUJITA Tomonori
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+
+#include <linux/version.h>
+#include "comfront.h"
+
+
+#define DEFAULT_CMD_PER_LUN 10
+#define DEFAULT_TASK_COMM_LEN 16
+
+extern int scsi_trace_init(void);
+extern void scsi_trace(unsigned long, unsigned char *, unsigned int);
+
+static int req_per_lun = DEFAULT_CMD_PER_LUN;
+module_param_named(cmds_lun, req_per_lun, int, 0);
+MODULE_PARM_DESC(reqs, "Number of lun requests to allocate");
+
+#ifdef CONFIG_XEN_FC
+extern struct fc_function_template fc_transport_functions;
+static struct scsi_transport_template * fc_transport_template = NULL;
+#endif
+extern int read_ftb_ring_resp_cons(struct comfront_info *info);
+
+static void scsifront_free(struct comfront_info *info)
+{
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
+ if (info->host->shost_state != SHOST_DEL) {
+#else
+ if (!test_bit(SHOST_DEL, &info->host->shost_state)) {
+#endif
+
+#ifdef CONFIG_XEN_FC
+ fc_remove_host(info->host);
+#endif
+ scsi_remove_host(info->host);
+ scsi_host_put(info->host);
+ }
+
+ flush_scheduled_work();
+
+ if (info->ftb_ring_ref != GRANT_INVALID_REF) {
+ gnttab_end_foreign_access(info->ftb_ring_ref, 0,
+ (unsigned long)info->ftb_ring.sring);
+ info->ftb_ring_ref = GRANT_INVALID_REF;
+ info->ftb_ring.sring = NULL;
+ }
+
+ if (info->btf_ring_ref != GRANT_INVALID_REF) {
+ gnttab_end_foreign_access(info->btf_ring_ref, 0,
+ (unsigned long)info->btf_ring.sring);
+ info->btf_ring_ref = GRANT_INVALID_REF;
+ info->btf_ring.sring = NULL;
+ }
+
+ if (info->irq)
+ unbind_from_irqhandler(info->irq, info);
+ info->irq = 0;
+}
+
+
+static int map_data_for_request(struct comfront_info *info,
+ struct scsi_cmnd *sc, struct vscsiif_ftb_request *ftb_req, uint32_t id)
+{
+ grant_ref_t gref_head;
+ struct page *page;
+ int err, i, ref, ref_cnt = 0;
+ int write = (sc->sc_data_direction == DMA_TO_DEVICE);
+ int nr_pages, off, len, bytes;
+ unsigned long buffer_pfn;
+
+ if (sc->sc_data_direction == DMA_NONE)
+ return 0;
+
+ err = gnttab_alloc_grant_references(SG_TABLESIZE, &gref_head);
+ if (err) {
+ printk(KERN_ERR "scsifront: gnttab_alloc_grant_references() error\n");
+ return -ENOMEM;
+ }
+
+ if (sc->use_sg) {
+ /* quoted scsi_lib.c/scsi_req_map_sg . */
+ struct scatterlist *sg = (struct scatterlist *)sc->request_buffer;
+ unsigned int data_len = 0;
+ nr_pages = (sc->request_bufflen + sg[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ if (nr_pages > SG_TABLESIZE) {
+ ref_cnt = (-ENOMEM);
+ goto big_to_sg;
+ }
+
+ for (i = 0; i < sc->use_sg; i++) {
+ page = sg[i].page;
+ off = sg[i].offset;
+ len = sg[i].length;
+ data_len += len;
+
+ buffer_pfn = page_to_phys(page) >> PAGE_SHIFT;
+
+ while (len > 0) {
+ bytes = min_t(unsigned int, len, PAGE_SIZE - off);
+
+ ref = gnttab_claim_grant_reference(&gref_head);
+ BUG_ON(ref == -ENOSPC); /*FIXME*/
+
+ gnttab_grant_foreign_access_ref(ref, info->dev->otherend_id,
+ buffer_pfn, write);
+
+ info->shadow[id].u.scsi.gref[ref_cnt] = ref;
+ ftb_req->u.scsi.seg[ref_cnt].gref = ref;
+ ftb_req->u.scsi.seg[ref_cnt].offset = off;
+ ftb_req->u.scsi.seg[ref_cnt].length = bytes;
+
+ buffer_pfn++;
+ len -= bytes;
+ off = 0;
+ ref_cnt++;
+ }
+ }
+ } else if (sc->request_bufflen) {
+ unsigned long end = ((unsigned long)sc->request_buffer
+ + sc->request_bufflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ unsigned long start = (unsigned long)sc->request_buffer >> PAGE_SHIFT;
+
+ page = virt_to_page(sc->request_buffer);
+ nr_pages = end - start;
+ len = sc->request_bufflen;
+
+ if (nr_pages > SG_TABLESIZE) {
+ ref_cnt = (-ENOMEM);
+ goto big_to_sg;
+ }
+
+ buffer_pfn = page_to_phys(page) >> PAGE_SHIFT;
+
+ off = offset_in_page((unsigned long)sc->request_buffer);
+ for (i = 0; i < nr_pages; i++) {
+ bytes = PAGE_SIZE - off;
+
+ if (bytes > len)
+ bytes = len;
+
+ ref = gnttab_claim_grant_reference(&gref_head);
+ BUG_ON(ref == -ENOSPC); /*FIXME*/
+
+ gnttab_grant_foreign_access_ref(ref, info->dev->otherend_id,
+ buffer_pfn, write);
+
+ info->shadow[id].u.scsi.gref[i] = ref;
+ ftb_req->u.scsi.seg[i].gref = ref;
+ ftb_req->u.scsi.seg[i].offset = off;
+ ftb_req->u.scsi.seg[i].length = bytes;
+
+/* page = pfn_to_page(++buffer_mfn);*/
+ buffer_pfn++;
+ len -= bytes;
+ off = 0;
+ ref_cnt++;
+ }
+ }
+
+big_to_sg:
+
+ gnttab_free_grant_references(gref_head);
+
+ return ref_cnt;
+}
+
+static int scsifront_queuecommand(struct scsi_cmnd *sc,
+ void (*done)(struct scsi_cmnd *))
+{
+ struct Scsi_Host *host = sc->device->host;
+ struct comfront_info *info = (struct comfront_info *) host->hostdata;
+ struct vscsiif_ftb_request *ftb_req;
+ int ref_cnt;
+
+ if (info->dev->state != XenbusStateConnected) {
+ printk(KERN_ERR "scsifront: XenbusState not connected %u!\n",
+ info->dev->state);
+ sc->result = DID_NO_CONNECT << 16;
+ done(sc);
+ return 0;
+ }
+
+ if (RING_FULL(&info->ftb_ring)) {
+ /*printk(KERN_INFO "scsifront: FTB Ring Full busy\n");*/
+ return SCSI_MLQUEUE_HOST_BUSY;
+ }
+
+ if (read_ftb_ring_resp_cons(info)) {
+ /*printk("scsifront: BTF Ring Full busy\n");*/
+ return SCSI_MLQUEUE_HOST_BUSY;
+ }
+
+ sc->scsi_done = done;
+ sc->result = 0;
+
+ ftb_req = comfront_pre_request(info);
+ ftb_req->cmnd = CMND_SCSI;
+
+ ftb_req->u.scsi.id = sc->device->id;
+ ftb_req->u.scsi.lun = sc->device->lun;
+ ftb_req->u.scsi.channel = sc->device->channel;
+ ftb_req->u.scsi.cmd_len = sc->cmd_len;
+
+ BUG_ON(sc->cmd_len > VSCSI_MAX_COMMAND_SIZE);
+ BUG_ON(sc == NULL);
+
+ if ( sc->cmd_len )
+ memcpy(ftb_req->u.scsi.cmnd, sc->cmnd, sc->cmd_len);
+ else
+ memset(ftb_req->u.scsi.cmnd, 0, VSCSI_MAX_COMMAND_SIZE);
+
+ ftb_req->u.scsi.sc_data_direction = sc->sc_data_direction;
+ ftb_req->u.scsi.request_bufflen = sc->request_bufflen;
+ ftb_req->u.scsi.timeout_per_command = sc->timeout_per_command;
+
+ info->shadow[ftb_req->rqid].u.scsi.req_scsi_cmnd = (unsigned long)sc;
+ info->shadow[ftb_req->rqid].u.scsi.sc_data_direction
+ = sc->sc_data_direction;
+ info->shadow[ftb_req->rqid].u.scsi.request_bufflen
+ = sc->request_bufflen;
+ info->shadow[ftb_req->rqid].cmnd = ftb_req->cmnd;
+
+ ref_cnt = map_data_for_request(info, sc, ftb_req, ftb_req->rqid);
+ if (unlikely(ref_cnt < 0)) {
+ ADD_ID_TO_FREELIST(info, ftb_req->rqid);
+ notify_remote_via_irq(info->irq);
+ return SCSI_MLQUEUE_HOST_BUSY;
+ }
+
+ ftb_req->u.scsi.use_sg = ref_cnt;
+ info->shadow[ftb_req->rqid].u.scsi.use_sg = ref_cnt;
+
+ scsi_trace(1, (unsigned char *)ftb_req,
+ sizeof(struct vscsiif_ftb_request));
+
+ comfront_do_request(info);
+
+ return 0;
+}
+
+
+static int scsifront_eh_abort_handler(struct scsi_cmnd *sc)
+{
+ /* not implemented */
+ printk(KERN_ERR "scsifront: abort! 0 return.\n");
+ return (FAILED);
+}
+
+
+static int scsifront_eh_host_reset_handler(struct scsi_cmnd *sc)
+{
+ struct Scsi_Host *host = sc->device->host;
+ struct comfront_info *info = (struct comfront_info *) host->hostdata;
+ struct vscsiif_ftb_request *ring_req;
+ struct vscsiif_btf_request *ring_res;
+ int err = FAILED;
+
+ printk(KERN_INFO "scsifront: reset.\n");
+
+ scsi_block_requests(host);
+
+ ring_req = comfront_pre_request(info);
+
+ ring_req->cmnd = CMND_SCSI_RESET;
+ ring_req->u.scsi.id = sc->device->id;
+ ring_req->u.scsi.lun = sc->device->lun;
+ ring_req->u.scsi.channel = sc->device->channel;
+
+ spin_unlock_irq(info->host->host_lock);
+
+ ring_res = comfront_do_request_and_wait_response(info, ring_req);
+
+ err = (ring_res->rslt ? SUCCESS : FAILED);
+
+ scsi_unblock_requests(host);
+
+ return (err);
+}
+
+
+static void scsifront_gnttab_done(struct comfront_shadow *s, uint32_t id)
+{
+ int i;
+
+ if (s->u.scsi.sc_data_direction == DMA_NONE)
+ return;
+
+ if (s->u.scsi.use_sg) {
+ for (i = 0; i < s->u.scsi.use_sg; i++) {
+ if (unlikely(gnttab_query_foreign_access(
+ s->u.scsi.gref[i]) != 0)) {
+ printk(KERN_ALERT "scsifront: "
+ "grant still in use by backend.\n");
+ BUG();
+ }
+ gnttab_end_foreign_access(s->u.scsi.gref[i], 0, 0UL);
+ }
+ } else if (s->u.scsi.request_bufflen) {
+ gnttab_end_foreign_access(s->u.scsi.gref[0], 0, 0UL);
+ } else {
+ return;
+ }
+}
+
+
+int scsifront_cmd_done(struct comfront_info *info,
+ struct vscsiif_btf_request *btf_req)
+{
+ struct scsi_cmnd *sc;
+ uint32_t id;
+
+ id = btf_req->rqid;
+ sc = (struct scsi_cmnd *)info->shadow[id].u.scsi.req_scsi_cmnd;
+
+ if (sc == NULL)
+ return 1;
+
+ scsifront_gnttab_done(&info->shadow[id], id);
+ ADD_ID_TO_FREELIST(info, id);
+
+ sc->result = btf_req->rslt;
+ sc->resid = 0;
+
+ BUG_ON(btf_req->u.scsi.sense_len > SCSI_SENSE_BUFFERSIZE);
+
+ if( btf_req->rslt != 0 ) {
+ if (btf_req->u.scsi.sense_len)
+ memcpy(sc->sense_buffer, btf_req->u.scsi.sense_buffer,
+ btf_req->u.scsi.sense_len);
+ }
+
+ sc->scsi_done(sc);
+
+ return 0;
+}
+
+
+static int scsifront_alloc_ring(struct comfront_info *info)
+{
+ struct xenbus_device *dev = info->dev;
+ struct vscsiif_ftb_sring *ftb;
+ struct vscsiif_btf_sring *btf;
+ int err = -ENOMEM;
+
+ info->ftb_ring_ref = GRANT_INVALID_REF;
+ info->btf_ring_ref = GRANT_INVALID_REF;
+
+ /***** Frontend to Backend ring start *****/
+ ftb = (struct vscsiif_ftb_sring *) __get_free_page(GFP_KERNEL);
+ if (!ftb) {
+ xenbus_dev_fatal(dev, err, "fail to allocate shared ring (Front to Back)");
+ return err;
+ }
+ SHARED_RING_INIT(ftb);
+ FRONT_RING_INIT(&info->ftb_ring, ftb, PAGE_SIZE);
+
+ err = xenbus_grant_ring(dev, virt_to_mfn(ftb));
+ if (err < 0) {
+ free_page((unsigned long) ftb);
+ info->ftb_ring.sring = NULL;
+ xenbus_dev_fatal(dev, err, "fail to grant shared ring (Front to Back)");
+ goto free_sring;
+ }
+ info->ftb_ring_ref = err;
+
+ /***** Backend to Frontend ring start *****/
+ btf = (struct vscsiif_btf_sring *) __get_free_page(GFP_KERNEL);
+ if (!btf) {
+ xenbus_dev_fatal(dev, err, "fail to allocate shared ring (Back to Front)");
+ return err;
+ }
+ SHARED_RING_INIT(btf);
+ BACK_RING_INIT(&info->btf_ring, btf, PAGE_SIZE);
+
+ err = xenbus_grant_ring(dev, virt_to_mfn(btf));
+ if (err < 0) {
+ free_page((unsigned long) btf);
+ info->btf_ring.sring = NULL;
+ xenbus_dev_fatal(dev, err, "fail to grant shared ring (Back to Front)");
+ goto free_sring;
+ }
+ info->btf_ring_ref = err;
+
+ err = bind_listening_port_to_irqhandler(
+ dev->otherend_id, comfront_intr,
+ SA_SAMPLE_RANDOM, "scsifront", info);
+
+ if (err <= 0) {
+ xenbus_dev_fatal(dev, err, "bind_listening_port_to_irqhandler");
+ goto fail;
+ }
+ info->irq = err;
+
+ return 0;
+fail:
+ /* free resource */
+free_sring:
+ scsifront_free(info);
+
+ return err;
+}
+
+static int scsifront_init_ring(struct comfront_info *info)
+{
+ struct xenbus_device *dev = info->dev;
+ struct xenbus_transaction xbt;
+ int err;
+
+ DPRINTK("%s\n",__FUNCTION__);
+
+ err = scsifront_alloc_ring(info);
+ if (err)
+ return err;
+ DPRINTK("%u %u %u\n", info->ftb_ring_ref, info->ftb_ring_ref, info->evtchn);
+
+again:
+ err = xenbus_transaction_start(&xbt);
+ if (err) {
+ xenbus_dev_fatal(dev, err, "starting transaction");
+ }
+
+ err = xenbus_printf(xbt, dev->nodename, "ftb-ring-ref", "%u",
+ info->ftb_ring_ref);
+ if (err) {
+ xenbus_dev_fatal(dev, err, "%s", "writing ftb-ring-ref");
+ goto fail;
+ }
+ err = xenbus_printf(xbt, dev->nodename, "btf-ring-ref", "%u",
+ info->btf_ring_ref);
+ if (err) {
+ xenbus_dev_fatal(dev, err, "%s", "writing btf-ring-ref");
+ goto fail;
+ }
+
+ err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
+ irq_to_evtchn_port(info->irq));
+
+ if (err) {
+ xenbus_dev_fatal(dev, err, "%s", "writing event-channel");
+ goto fail;
+ }
+
+ err = xenbus_printf(xbt, dev->nodename, "vhostno", "%d",
+ info->host->host_no);
+
+ if (err) {
+ xenbus_dev_fatal(dev, err, "%s", "writing event-channel");
+ goto fail;
+ }
+
+ err = xenbus_transaction_end(xbt, 0);
+ if (err) {
+ if (err == -EAGAIN)
+ goto again;
+ xenbus_dev_fatal(dev, err, "completing transaction");
+ } else
+ xenbus_switch_state(dev, XenbusStateInitialised);
+
+ return 0;
+fail:
+ xenbus_transaction_end(xbt, 1);
+ /* free resource */
+ scsifront_free(info);
+
+ return err;
+}
+
+static struct scsi_host_template scsifront_sht = {
+ .module = THIS_MODULE,
+ .name = "Xen SCSI frontend driver",
+ .queuecommand = scsifront_queuecommand,
+ .eh_abort_handler = scsifront_eh_abort_handler,
+ .eh_host_reset_handler = scsifront_eh_host_reset_handler,
+ .cmd_per_lun = DEFAULT_CMD_PER_LUN,
+ .can_queue = 16,
+ .this_id = -1,
+ .sg_tablesize = SG_TABLESIZE,
+ .use_clustering = DISABLE_CLUSTERING,
+ .proc_name = "scsifront",
+};
+
+static int scsifront_connect(struct comfront_info *info)
+{
+ struct xenbus_device *dev = info->dev;
+ struct Scsi_Host *host = info->host;
+
+ int err = -ENOMEM;
+
+ DPRINTK("%u\n", dev->state);
+ if (dev->state == XenbusStateConnected)
+ return 0;
+
+ xenbus_switch_state(dev, XenbusStateConnected);
+
+#ifdef CONFIG_XEN_FC
+ (void)fcfront_get_function_template(info);
+
+ fc_transport_template = fc_attach_transport(&fc_transport_functions);
+ host->transportt = fc_transport_template;
+#endif
+ /* FIXME */
+ host->max_id = 64;
+ host->max_channel = 0;
+ host->max_lun = 128;
+ host->max_sectors = (SG_TABLESIZE * PAGE_SIZE / 512);
+ host->cmd_per_lun = req_per_lun;
+
+ err = scsi_add_host(host, &dev->dev);
+ if (err) {
+ printk(KERN_ERR "scsifront: fail to add scsi host %d\n", err);
+ return err;
+ }
+
+ scsi_scan_host(host);
+
+#ifdef CONFIG_XEN_FC
+ (void)fcfront_get_initial_attribute(info);
+#endif
+
+ return 0;
+}
+
+static int scsifront_disconnect(struct comfront_info *info)
+{
+ struct xenbus_device *dev = info->dev;
+
+ DPRINTK("%s: %s remove\n",__FUNCTION__ ,dev->nodename);
+
+#ifdef CONFIG_XEN_FC
+ fc_remove_host(info->host);
+#endif
+ scsi_remove_host(info->host);
+ scsi_host_put(info->host);
+
+ xenbus_frontend_closed(dev);
+
+ return 0;
+}
+
+static int scsifront_probe(struct xenbus_device *dev,
+ const struct xenbus_device_id *id)
+{
+ struct Scsi_Host *host;
+ struct comfront_info *info;
+ int i, err = -ENOMEM;
+ char name[DEFAULT_TASK_COMM_LEN];
+
+ host = scsi_host_alloc(&scsifront_sht, sizeof(*info));
+ if (!host) {
+ xenbus_dev_fatal(dev, err, "fail to allocate scsi host");
+ return err;
+ }
+ info = (struct comfront_info *) host->hostdata;
+ dev->dev.driver_data = info;
+ info->dev = dev;
+ info->host = host;
+
+ for (i = 0; i < DEFAULT_CAN_QUEUE; i++) {
+ info->shadow[i].rqid = i + 1;
+ init_waitqueue_head(&(info->shadow[i].wq));
+ info->shadow[i].cond = 0;
+ }
+ info->shadow[DEFAULT_CAN_QUEUE - 1].rqid = 0x0fffffff;
+
+#ifdef CONFIG_XEN_FC
+ if ((err = fcfront_connection_setup(info)) != 0) {
+ printk(KERN_ERR
+ "scsifront: %s: fcfront_connection_setup() error\n",
+ __FUNCTION__);
+ return err;
+ }
+#endif
+
+ err = scsifront_init_ring(info);
+ if (err) {
+ scsi_host_put(host);
+ return err;
+ }
+
+ init_waitqueue_head(&info->wq);
+ spin_lock_init(&info->io_lock);
+ spin_lock_init(&info->shadow_lock);
+
+ snprintf(name, DEFAULT_TASK_COMM_LEN, "scsiif.%d", info->host->host_no);
+
+ info->kthread = kthread_run(comfront_schedule, info, name);
+ if (IS_ERR(info->kthread)) {
+ err = PTR_ERR(info->kthread);
+ info->kthread = NULL;
+ }
+
+ return 0;
+}
+
+
+static int scsifront_remove(struct xenbus_device *dev)
+{
+ struct comfront_info *info = dev->dev.driver_data;
+
+ DPRINTK("%s: %s removed\n",__FUNCTION__ ,dev->nodename);
+
+ if (info->kthread) {
+ kthread_stop(info->kthread);
+ info->kthread = NULL;
+ }
+
+#ifdef CONFIG_XEN_FC
+ fcfront_connection_unsetup(info);
+#endif
+ scsifront_free(info);
+
+ /*kfree(info);*/
+ return 0;
+}
+
+static void scsifront_backend_changed(struct xenbus_device *dev,
+ XenbusState backend_state)
+{
+ struct comfront_info *info = dev->dev.driver_data;
+
+ DPRINTK("%p %u %u\n", dev, dev->state, backend_state);
+
+ switch (backend_state) {
+ case XenbusStateUnknown:
+ case XenbusStateInitialising:
+ case XenbusStateInitWait:
+ case XenbusStateInitialised:
+ case XenbusStateClosed:
+ break;
+
+ case XenbusStateConnected:
+ scsifront_connect(info);
+ break;
+
+ case XenbusStateClosing:
+ scsifront_disconnect(info);
+ break;
+ }
+}
+
+static struct xenbus_device_id scsifront_ids[] = {
+ { "scsihost" },
+ { "" }
+};
+
+
+static struct xenbus_driver scsifront_driver = {
+ .name = "scsihost",
+ .owner = THIS_MODULE,
+ .ids = scsifront_ids,
+ .probe = scsifront_probe,
+ .remove = scsifront_remove,
+/* .resume = scsifront_resume, */
+ .otherend_changed = scsifront_backend_changed,
+};
+
+static int __init scsifront_init(void)
+{
+ int err;
+
+#if 0 /* for DEBUG */
+ printk(KERN_ERR "%s: ftb_req=%d\n", __FUNCTION__,
+ sizeof(struct vscsiif_ftb_request));
+ printk(KERN_ERR "%s: ftb_res=%d\n", __FUNCTION__,
+ sizeof(struct vscsiif_ftb_response));
+ printk(KERN_ERR "%s: btf_req=%d\n", __FUNCTION__,
+ sizeof(struct vscsiif_btf_request));
+ printk(KERN_ERR "%s: btf_res=%d\n", __FUNCTION__,
+ sizeof(struct vscsiif_btf_response));
+
+ printk("%s SCSI_RING_SIZE_ftb=%ld\n", __FUNCTION__,
+ __RING_SIZE((struct vscsiif_ftb_sring *)0, PAGE_SIZE));
+ printk("%s SCSI_RING_SIZE_btf=%ld\n", __FUNCTION__,
+ __RING_SIZE((struct vscsiif_btf_sring *)0, PAGE_SIZE));
+
+#endif /* for DEBUG */
+
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+#ifdef CONFIG_XEN_FC
+ if (is_initial_xendomain()) {
+ return 0;
+ }
+#endif
+
+ err = xenbus_register_frontend(&scsifront_driver);
+
+ (void)scsi_trace_init();
+
+ return err;
+}
+
+static void scsifront_exit(void)
+{
+ xenbus_unregister_driver(&scsifront_driver);
+
+#ifdef CONFIG_XEN_FC
+ fc_release_transport(fc_transport_template);
+#endif
+}
+
+module_init(scsifront_init);
+module_exit(scsifront_exit);
+
+MODULE_DESCRIPTION("Xen SCSI frontend driver");
+MODULE_LICENSE("GPL");
diff -r 709db80c03c3 -r 24e0cb9fe9df drivers/xen/scsifront/tracefront.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsifront/tracefront.c Tue Oct 30 16:41:36 2007 +0900
@@ -0,0 +1,107 @@
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+
+#include <linux/time.h>
+//#include <asm/delay.h>
+
+
+#define MAX_DATA_SIZE 472 /* should be modified */
+ /* according to data */
+ /* to be recorded */
+#define ENTRY_NUM (16 * 1024)
+
+struct scsi_trace_entry {
+ unsigned long dir; /* direction */
+ /* 0: pending(BE) */
+ /* 1: request(FE) */
+ /* 2: response(FE) */
+ unsigned long serial; /* incremental counter */
+ /* starts at 0 */
+ struct timeval tv; /* timeofday */
+// unsigned long itc; /* itc */
+ unsigned int size; /* data size */
+ unsigned char data[MAX_DATA_SIZE]; /* data body */
+};
+
+static struct scsi_trace_entry *scsi_trace_buf;
+EXPORT_SYMBOL(scsi_trace_buf); /* for DUMP */
+
+static DEFINE_SPINLOCK(scsi_trace_lock);
+
+void
+scsi_trace(unsigned long dir, unsigned char *data, unsigned int size)
+{
+ static unsigned long index = 0;
+ static unsigned long serial = 0;
+ unsigned long flags;
+
+ if (size > MAX_DATA_SIZE) {
+ printk(KERN_ERR "%s: data given is too big.\n"
+ "must be smaller than %d bytes.\n",
+ __FUNCTION__, MAX_DATA_SIZE);
+ return;
+ }
+
+ spin_lock_irqsave(&scsi_trace_lock, flags);
+
+ scsi_trace_buf[index].dir = dir;
+ do_gettimeofday(&(scsi_trace_buf[index].tv));
+// scsi_trace_buf[index].itc = ia64_get_itc();
+ scsi_trace_buf[index].size = size;
+// memset(scsi_trace_buf[index].data, 0, MAX_DATA_SIZE);
+ memcpy(scsi_trace_buf[index].data, data, size);
+
+ /* This indicates that the record is successfully recorded */
+ scsi_trace_buf[index].serial = serial++;
+
+ index = (index + 1) % ENTRY_NUM;
+
+ spin_unlock_irqrestore(&scsi_trace_lock, flags);
+
+}
+
+static int
+scsi_trace_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = sizeof(struct scsi_trace_entry) * ENTRY_NUM;
+ unsigned long flags;
+
+ spin_lock_irqsave(&scsi_trace_lock, flags);
+
+ if (len <= off + count) {
+ *eof = 1;
+ }
+ *start = page;
+ len -= off;
+ if (len > count) {
+ len = count;
+ }
+ if (len < 0) {
+ len = 0;
+ } else {
+ memcpy(page, ((unsigned char *)scsi_trace_buf) + off, len);
+ }
+
+ spin_unlock_irqrestore(&scsi_trace_lock, flags);
+
+ return len;
+}
+
+int
+scsi_trace_init(void)
+{
+ unsigned int scsi_trace_buf_size;
+
+ scsi_trace_buf_size = sizeof(struct scsi_trace_entry) * ENTRY_NUM;
+ if ((scsi_trace_buf = vmalloc(scsi_trace_buf_size)) == NULL) {
+ return -1;
+ }
+ memset(scsi_trace_buf, 0, scsi_trace_buf_size);
+
+ create_proc_read_entry("scsi_trace", 0, NULL,
+ scsi_trace_read_proc, NULL);
+
+ return 0;
+}
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 2/6] pvSCSI (SCSI pass through) driver
2007-10-25 1:59 ` Jun Kamada
2007-10-30 10:39 ` [PATCH 0/6] " Jun Kamada
2007-10-30 10:39 ` [PATCH 1/6] " Jun Kamada
@ 2007-10-30 10:39 ` Jun Kamada
2007-10-30 10:39 ` [PATCH 3/6] " Jun Kamada
` (3 subsequent siblings)
6 siblings, 0 replies; 33+ messages in thread
From: Jun Kamada @ 2007-10-30 10:39 UTC (permalink / raw)
Cc: kama, xen-devel
[-- Attachment #1: Type: text/plain, Size: 286 bytes --]
This patch is for backend driver.
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
-----
Jun Kamada
[-- Attachment #2: linux_scsiback.patch --]
[-- Type: application/octet-stream, Size: 69814 bytes --]
# HG changeset patch
# User t.horikoshi@jp.fujitsu.com
# Date 1193730190 -32400
# Node ID 374aa5b731056b2182ff60d2efa9f3524232d8d8
# Parent 24e0cb9fe9df6f4a6df226823562bec3089072e6
[LINUX][scsiback] add scsi backend driver
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
diff -r 24e0cb9fe9df -r 374aa5b73105 drivers/xen/scsiback/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsiback/Makefile Tue Oct 30 16:43:10 2007 +0900
@@ -0,0 +1,8 @@
+ifeq ($(CONFIG_XEN_FC),y)
+ EXTRA_CFLAGS += -DCONFIG_XEN_FC
+ obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-fcscsibk.o
+ xen-fcscsibk-y += interface.o scsiback.o xenbus.o fcback.o comback.o traceback.o
+else
+ obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-scsibk.o
+ xen-scsibk-y += interface.o scsiback.o xenbus.o comback.o traceback.o
+endif
diff -r 24e0cb9fe9df -r 374aa5b73105 drivers/xen/scsiback/comback.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsiback/comback.c Tue Oct 30 16:43:10 2007 +0900
@@ -0,0 +1,272 @@
+/*
+ * Xen SCSI backend driver
+ *
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * Based on the blkback driver code.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#ifdef CONFIG_XEN_FC
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+#endif
+
+#include "comback.h"
+
+extern struct list_head pending_free;
+extern int vscsiif_reqs;
+
+static DEFINE_SPINLOCK(pending_free_lock);
+static DECLARE_WAIT_QUEUE_HEAD(pending_free_wq);
+
+extern void scsiback_cmd_exec(pending_req_t *);
+extern int copy_request_ring_info(struct comback_info *,
+ struct vscsiif_ftb_request *, pending_req_t *);
+extern void scsiback_reset_exec(pending_req_t *);
+extern void scsi_trace(unsigned long, unsigned char *, unsigned int);
+
+#ifdef CONFIG_XEN_FC
+extern void fcback_cmd_exec(pending_req_t *);
+#endif
+
+static void read_btf_ring_resp_cons(struct comback_info *info);
+
+/* ------------------------------------------------------------ */
+/* for frontend to backend communication */
+/* ------------------------------------------------------------ */
+
+static pending_req_t * alloc_req(void)
+{
+ pending_req_t *req = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pending_free_lock, flags);
+ if (!list_empty(&pending_free)) {
+ req = list_entry(pending_free.next, pending_req_t, u.scsi.free_list);
+ list_del(&req->u.scsi.free_list);
+ }
+ spin_unlock_irqrestore(&pending_free_lock, flags);
+ return req;
+}
+
+void free_req(pending_req_t *req)
+{
+ unsigned long flags;
+ int was_empty;
+
+ spin_lock_irqsave(&pending_free_lock, flags);
+ was_empty = list_empty(&pending_free);
+ list_add(&req->u.scsi.free_list, &pending_free);
+ spin_unlock_irqrestore(&pending_free_lock, flags);
+ if (was_empty)
+ wake_up(&pending_free_wq);
+}
+
+static void comback_notify_work(struct comback_info *info)
+{
+ info->waiting_reqs = 1;
+ wake_up(&info->wq);
+}
+
+irqreturn_t comback_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ comback_notify_work((struct comback_info *)dev_id);
+ return IRQ_HANDLED;
+}
+
+static int __copy_request_ring_info(struct comback_info *info,
+ struct vscsiif_ftb_request *ftb_req, pending_req_t *pending_req)
+{
+ pending_req->cmnd = ftb_req->cmnd;
+ pending_req->info = info;
+
+ if (ftb_req->cmnd == CMND_SCSI || ftb_req->cmnd == CMND_SCSI_RESET) {
+ return copy_request_ring_info(info, ftb_req, pending_req);
+ } else {
+#ifdef CONFIG_XEN_FC
+ pending_req->u.fc.ftb_req = *ftb_req;
+#else
+ BUG();
+#endif
+ }
+ return 0;
+}
+
+static int do_comback_cmd_fn(struct comback_info *info)
+{
+ struct vscsiif_ftb_back_ring *ftb_ring = &info->ftb_ring;
+ struct vscsiif_ftb_request *ftb_req;
+ struct vscsiif_ftb_response *ftb_resp;
+
+ pending_req_t *pending_req[vscsiif_reqs];
+ RING_IDX rc, rp;
+ int i, err, more_to_do = 0;
+ int queued = 0;
+ int notify;
+
+ DPRINTK("%s\n",__FUNCTION__);
+
+ rc = ftb_ring->req_cons;
+ rp = ftb_ring->sring->req_prod;
+ rmb();
+
+ while ((rc != rp) && !RING_REQUEST_CONS_OVERFLOW(ftb_ring, rc)) {
+ pending_req[queued] = alloc_req();
+ if (NULL == pending_req[queued]) {
+ more_to_do = 1;
+ break;
+ }
+
+ /***** Front to Back request consume *****/
+
+ ftb_req = RING_GET_REQUEST(ftb_ring, rc);
+ ftb_ring->req_cons = ++rc;
+
+ err = __copy_request_ring_info(info, ftb_req, pending_req[queued]);
+
+ scsi_trace(0, (unsigned char *)(pending_req[queued]),
+ sizeof(pending_req_t));
+
+ /* It responds immediately after the command is issued. */
+ ftb_resp = RING_GET_RESPONSE(ftb_ring,
+ ftb_ring->rsp_prod_pvt);
+
+ if (!RING_FULL(&info->btf_ring)) {
+ ftb_resp->status = SCSIIF_REQ_OKAY;
+ } else {
+ ftb_resp->status = SCSIIF_BTFRING_BUSY;
+ RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->btf_ring, notify);
+ if (notify)
+ notify_remote_via_irq(info->irq);
+ }
+
+ ftb_ring->rsp_prod_pvt++;
+ RING_PUSH_RESPONSES(ftb_ring);
+
+ queued++;
+ }
+
+ for (i = 0; i < queued; i++) {
+ if (pending_req[i]->cmnd == CMND_SCSI) {
+ scsiback_cmd_exec(pending_req[i]);
+ } else if (pending_req[i]->cmnd == CMND_SCSI_RESET) {
+ scsiback_reset_exec(pending_req[i]);
+#ifndef CONFIG_XEN_FC
+ }
+#else
+ } else {
+ fcback_cmd_exec(pending_req[i]);
+ }
+#endif
+ }
+
+ if (ftb_ring->rsp_prod_pvt == rc) {
+ RING_FINAL_CHECK_FOR_REQUESTS(ftb_ring, more_to_do);
+
+ } else if (RING_HAS_UNCONSUMED_REQUESTS(ftb_ring)) {
+ more_to_do = 1;
+ }
+
+ return more_to_do;
+}
+
+int comback_schedule(void *data)
+{
+ struct comback_info *info = (struct comback_info *)data;
+
+ DPRINTK("%s\n",__FUNCTION__);
+
+ scsiback_get(info);
+
+ while (!kthread_should_stop()) {
+ wait_event_interruptible(
+ info->wq,
+ info->waiting_reqs || kthread_should_stop());
+ wait_event_interruptible(
+ pending_free_wq,
+ !list_empty(&pending_free) || kthread_should_stop());
+
+ info->waiting_reqs = 0;
+ smp_mb();
+
+ if (do_comback_cmd_fn(info))
+ info->waiting_reqs = 1;
+
+ /***** Back to Front response consume *****/
+ read_btf_ring_resp_cons(info);
+ }
+
+ info->kthread = NULL;
+ scsiback_put(info);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------ */
+/* for backend to frontend communication */
+/* ------------------------------------------------------------ */
+
+struct vscsiif_btf_request *comback_pre_reply(struct comback_info *info)
+{
+ struct vscsiif_btf_request *btf_req;
+
+ rmb();
+ btf_req = RING_GET_REQUEST(&info->btf_ring, info->btf_ring.req_prod_pvt);
+ info->btf_ring.req_prod_pvt++;
+
+ return btf_req;
+}
+
+static void read_btf_ring_resp_cons(struct comback_info *info)
+{
+ RING_IDX rp;
+
+ rp = info->btf_ring.sring->rsp_prod;
+ rmb();
+
+ if (info->btf_ring.rsp_cons != rp)
+ info->btf_ring.rsp_cons = rp;
+}
+
+void comback_do_reply(struct comback_info *info)
+{
+ int notify;
+
+ RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->btf_ring, notify);
+ if (notify)
+ notify_remote_via_irq(info->irq);
+
+ /***** Back to Front response consume *****/
+ read_btf_ring_resp_cons(info);
+
+ if (RING_HAS_UNCONSUMED_REQUESTS(&info->ftb_ring)) {
+ comback_notify_work(info);
+ }
+}
diff -r 24e0cb9fe9df -r 374aa5b73105 drivers/xen/scsiback/comback.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsiback/comback.h Tue Oct 30 16:43:10 2007 +0900
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * Based on the blkback driver code.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __SCSIIF__BACKEND__COMMON_H__
+#define __SCSIIF__BACKEND__COMMON_H__
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/pgalloc.h>
+#include <asm/delay.h>
+#include <xen/evtchn.h>
+#include <asm/hypervisor.h>
+#include <xen/gnttab.h>
+#include <xen/driver_util.h>
+#include <xen/xenbus.h>
+#include <xen/interface/io/ring.h>
+#include <xen/interface/grant_table.h>
+#include <xen/interface/io/vscsiif.h>
+
+
+#define DPRINTK(_f, _a...) \
+ pr_debug("(file=%s, line=%d) " _f, \
+ __FILE__ , __LINE__ , ## _a )
+
+struct comback_info {
+ struct xenbus_device *dev;
+ struct Scsi_Host *host;
+
+ domid_t domid;
+ unsigned int evtchn;
+ unsigned int irq;
+
+ unsigned short host_no;
+
+ struct vscsiif_ftb_back_ring ftb_ring;
+ struct vscsiif_btf_front_ring btf_ring;
+ struct vm_struct *ftb_ring_area;
+ struct vm_struct *btf_ring_area;
+
+ grant_handle_t ftb_shmem_handle;
+ grant_ref_t ftb_shmem_ref;
+ grant_handle_t btf_shmem_handle;
+ grant_ref_t btf_shmem_ref;
+
+ struct work_struct scsiback_work;
+
+ spinlock_t ring_lock_ftb;
+ spinlock_t ring_lock_btf;
+ atomic_t refcnt;
+
+ struct task_struct *kthread;
+ wait_queue_head_t waiting_to_free;
+ wait_queue_head_t wq;
+ unsigned int waiting_reqs;
+#ifdef CONFIG_XEN_FC
+ void *fcinfo;
+#endif
+ struct page **mmap_pages;
+
+};
+
+typedef struct {
+ unsigned int cmnd;
+ struct comback_info *info;
+ union {
+ struct scsi_pending_req {
+ struct scsi_device *sdev;
+ unsigned short data_dir;
+ uint32_t rqid;
+ int use_sg;
+ int request_bufflen;
+ atomic_t pendcnt;
+ struct request *rq;
+ struct scsiback_request_segment{
+ grant_ref_t gref;
+ uint32_t offset;
+ uint32_t length;
+ } pend_seg[SG_TABLESIZE];
+ struct list_head free_list;
+ } scsi;
+#ifdef CONFIG_XEN_FC
+ struct {
+ struct vscsiif_ftb_request ftb_req;
+ } fc;
+#endif
+ } u;
+} pending_req_t;
+
+typedef struct scsi_pending_req scsi_pending_req_t;
+
+irqreturn_t scsiback_intr(int, void *, struct pt_regs *);
+int scsiback_init_sring(struct comback_info *,
+ unsigned long, unsigned long, unsigned int);
+int scsiback_schedule(void *data);
+
+
+#define scsiback_get(_b) (atomic_inc(&(_b)->refcnt))
+#define scsiback_put(_b) \
+ do { \
+ if (atomic_dec_and_test(&(_b)->refcnt)) \
+ wake_up(&(_b)->waiting_to_free);\
+ } while (0)
+
+struct comback_info *scsiinfo_alloc(domid_t domid);
+void scsiback_free(struct comback_info *info);
+void scsiback_disconnect(struct comback_info *info);
+void __init scsiback_interface_init(void);
+void __exit scsiback_interface_exit(void);
+int scsiif_xenbus_init(void);
+void scsiif_xenbus_unregister(void);
+
+
+#endif /* __SCSIIF__BACKEND__COMMON_H__ */
diff -r 24e0cb9fe9df -r 374aa5b73105 drivers/xen/scsiback/fcback.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsiback/fcback.c Tue Oct 30 16:43:10 2007 +0900
@@ -0,0 +1,610 @@
+/*
+ * Xen SCSI FC backend driver
+ *
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kthread.h>
+#include <linux/kernel.h>
+#include <xen/xenbus.h>
+#include <xen/interface/grant_table.h>
+#include <xen/interface/io/ring.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+#include <asm/delay.h>
+
+#include "comback.h"
+#include "fcback.h"
+
+#define SET_FT(x, z, y) \
+ if ((x)->z == 0) { \
+ (y)->z = 0; \
+ } else { \
+ (y)->z = 1; \
+ }
+
+
+extern void unbind_from_irqhandler(unsigned int, void *);
+extern struct fc_function_template *fc_shost2ft(struct Scsi_Host *);
+extern struct vscsiif_btf_request *comback_pre_reply(struct comback_info *);
+extern void comback_do_reply(struct comback_info *);
+
+
+/* ---------------------------------------------------------------------- */
+
+static struct scsi_target *shost_to_starget(struct Scsi_Host *shost,
+ unsigned int channel,
+ unsigned int id)
+{
+ struct scsi_target *starget, *found_starget = NULL;
+
+ list_for_each_entry(starget, &(shost->__targets), siblings) {
+ if ((starget->channel == channel) && (starget->id == id)) {
+ found_starget = starget;
+ break;
+ }
+ }
+
+ return found_starget;
+}
+
+static struct fc_rport *shost_to_rport(struct Scsi_Host *shost, u64 node_name,
+ u64 port_name, u32 port_id, u32 roles)
+{
+ struct fc_rport *rport, *found_rport = NULL;
+
+ list_for_each_entry(rport, &fc_host_rports(shost), peers) {
+ if ((rport->node_name == node_name) &&
+ (rport->port_name == port_name) &&
+ (rport->port_id == port_id) &&
+ (rport->roles == roles)) {
+ found_rport = rport;
+ break;
+ }
+ }
+
+ return found_rport;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+static int fcback_main(struct fcback_info *info,
+ struct vscsiif_ftb_request *ring_req_tmp)
+{
+ struct comback_info *cominfo = info->cominfo;
+ struct vscsiif_ftb_request *ring_req = &(info->ftb_req);
+ struct vscsiif_btf_request *ring_res;
+ struct fc_function_template *ft = fc_shost2ft(cominfo->host);
+ struct scsi_target *starget;
+ struct fc_rport *rport;
+
+ /* Must check by class or something ... */
+ if ((strcmp(cominfo->host->hostt->name, "qla2xxx") != 0) &&
+ (strcmp(cominfo->host->hostt->name, "lpfc") != 0)) {
+ printk(KERN_ERR
+ "fcback: %s: not a supported fibre channel card>>>\n",
+ __FUNCTION__);
+ return -1;
+ }
+
+ memcpy(ring_req, ring_req_tmp, sizeof(struct vscsiif_ftb_request));
+
+ /*
+ Perform specified function and send response to DomU
+ */
+
+ ring_res = comback_pre_reply(cominfo);
+
+ ring_res->rslt = -1;
+
+ switch (ring_req->cmnd) {
+ case CMND_GET_HOST_PORT_ID:
+ if ((ft->show_host_port_id != 0) &&
+ (ft->get_host_port_id != NULL)) {
+ ft->get_host_port_id(cominfo->host);
+ ring_res->u.ghpi.port_id = ((struct fc_host_attrs *)
+ (cominfo->host->shost_data))->port_id;
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_GET_HOST_PORT_TYPE:
+ if ((ft->show_host_port_type != 0) &&
+ (ft->get_host_port_type != NULL)) {
+ ft->get_host_port_type(cominfo->host);
+ ring_res->u.ghpt.port_type = ((struct fc_host_attrs *)
+ (cominfo->host->shost_data))->port_type;
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_GET_HOST_PORT_STATE:
+ if ((ft->show_host_port_state != 0) &&
+ (ft->get_host_port_state != NULL)) {
+ ft->get_host_port_state(cominfo->host);
+ ring_res->u.ghps.port_state = ((struct fc_host_attrs *)
+ (cominfo->host->shost_data))->port_state;
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_GET_HOST_ACTIVE_FC4S:
+ if ((ft->show_host_active_fc4s != 0) &&
+ (ft->get_host_active_fc4s != NULL)) {
+ ft->get_host_active_fc4s(cominfo->host);
+ memcpy(ring_res->u.ghaf.active_fc4s,
+ ((struct fc_host_attrs *)
+ (cominfo->host->shost_data))->active_fc4s,
+ sizeof(ring_res->u.ghaf.active_fc4s));
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_GET_HOST_SPEED:
+ if ((ft->show_host_speed != 0) &&
+ (ft->get_host_speed != NULL)) {
+ ft->get_host_speed(cominfo->host);
+ ring_res->u.ghsp.speed = ((struct fc_host_attrs *)
+ (cominfo->host->shost_data))->speed;
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_GET_HOST_FABRIC_NAME:
+ if ((ft->show_host_fabric_name != 0) &&
+ (ft->get_host_fabric_name != NULL)) {
+ ft->get_host_fabric_name(cominfo->host);
+ ring_res->u.ghfn.fabric_name =
+ ((struct fc_host_attrs *)
+ (cominfo->host->shost_data))->fabric_name;
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_GET_HOST_STATS: {
+ struct fc_host_statistics *hs;
+
+ if (ft->get_fc_host_stats != NULL) {
+ if ((hs = ft->get_fc_host_stats(
+ cominfo->host)) == NULL) {
+ break;
+ }
+ ring_res->u.ghst.stats = *hs;
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break; }
+
+ case CMND_RESET_HOST_STATS:
+ if (ft->reset_fc_host_stats != NULL) {
+ ft->reset_fc_host_stats(cominfo->host);
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_ISSUE_HOST_LIP:
+ if (ft->issue_fc_host_lip != NULL) {
+ ring_res->rslt = ft->issue_fc_host_lip(cominfo->host);
+ ring_res->rqid = ring_req->rqid;
+ }
+ break;
+
+ case CMND_GET_STARGET_PORT_ID:
+ if ((ft->show_starget_port_id != 0) &&
+ (ft->get_starget_port_id != NULL)) {
+ if ((starget = shost_to_starget(cominfo->host,
+ ring_req->u.gtpi.channel,
+ ring_req->u.gtpi.id)) == NULL) {
+ break;
+ }
+ ft->get_starget_port_id(starget);
+ ring_res->u.gtpi.port_id = ((struct fc_starget_attrs *)
+ (&(starget->starget_data)))->port_id;
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_GET_STARGET_NODE_NAME:
+ if ((ft->show_starget_node_name != 0) &&
+ (ft->get_starget_node_name != NULL)) {
+ if ((starget = shost_to_starget(cominfo->host,
+ ring_req->u.gtnn.channel,
+ ring_req->u.gtnn.id)) == NULL) {
+ break;
+ }
+ ft->get_starget_node_name(starget);
+ ring_res->u.gtnn.node_name =
+ ((struct fc_starget_attrs *)
+ (&(starget->starget_data)))->node_name;
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_GET_STARGET_PORT_NAME:
+ if ((ft->show_starget_port_name != 0) &&
+ (ft->get_starget_port_name != NULL)) {
+ if ((starget = shost_to_starget(cominfo->host,
+ ring_req->u.gtpn.channel,
+ ring_req->u.gtpn.id)) == NULL) {
+ break;
+ }
+ ft->get_starget_port_name(starget);
+ ring_res->u.gtpn.port_name =
+ ((struct fc_starget_attrs *)
+ (&(starget->starget_data)))->port_name;
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_GET_RPORT_LOSS_TMO:
+ if ((ft->show_rport_dev_loss_tmo != 0) &&
+ (ft->get_rport_dev_loss_tmo != NULL)) {
+ if ((rport = shost_to_rport(cominfo->host,
+ ring_req->u.gplt.node_name,
+ ring_req->u.gplt.port_name,
+ ring_req->u.gplt.port_id,
+ ring_req->u.gplt.roles)) == NULL) {
+ break;
+ }
+ ft->get_rport_dev_loss_tmo(rport);
+ ring_res->u.gplt.timeout = rport->dev_loss_tmo;
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_SET_RPORT_LOSS_TMO:
+ if (ft->set_rport_dev_loss_tmo != NULL) {
+ if ((rport = shost_to_rport(cominfo->host,
+ ring_req->u.splt.node_name,
+ ring_req->u.splt.port_name,
+ ring_req->u.splt.port_id,
+ ring_req->u.splt.roles)) == NULL) {
+ break;
+ }
+ ft->set_rport_dev_loss_tmo(rport,
+ ring_req->u.splt.timeout);
+ ring_res->u.splt.timeout = rport->dev_loss_tmo;
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+ }
+ break;
+
+ case CMND_GET_INITIAL_SHOST_ATTRIB: {
+ struct fc_host_attrs *host_attrs = (struct fc_host_attrs *)
+ (cominfo->host->shost_data);
+ struct giha *giha = (struct giha *)(info->gnt_area->addr);
+
+ memcpy(giha->active_fc4s, host_attrs->active_fc4s,
+ sizeof(giha->active_fc4s));
+ giha->fabric_name = host_attrs->fabric_name;
+ giha->maxframe_size = host_attrs->maxframe_size;
+ giha->node_name = host_attrs->node_name;
+ giha->permanent_port_name
+ = host_attrs->permanent_port_name;
+ giha->port_id = host_attrs->port_id;
+ giha->port_name = host_attrs->port_name;
+ giha->port_state = host_attrs->port_state;
+ giha->port_type = host_attrs->port_type;
+ memcpy(giha->serial_number, host_attrs->serial_number,
+ sizeof(giha->serial_number));
+ giha->speed = host_attrs->speed;
+ {
+ struct fc_host_statistics *hs;
+
+ if (ft->get_fc_host_stats != NULL) {
+ if ((hs = ft->get_fc_host_stats(
+ cominfo->host)) != NULL) {
+ giha->stats = *hs;
+ } else {
+ memset(&(giha->stats), 0,
+ sizeof(giha->stats));
+ }
+ }
+ }
+ giha->supported_classes = host_attrs->supported_classes;
+ memcpy(giha->supported_fc4s, host_attrs->supported_fc4s,
+ sizeof(giha->supported_fc4s));
+ giha->supported_speeds = host_attrs->supported_speeds;
+ memcpy(giha->symbolic_name, host_attrs->symbolic_name,
+ sizeof(giha->symbolic_name));
+ giha->tgtid_bind_type = host_attrs->tgtid_bind_type;
+
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+
+ break; }
+
+ case CMND_GET_INITIAL_STARGET_ATTRIB: {
+ struct scsi_target *starget;
+ struct fc_starget_attrs *starget_attrs;
+ unsigned int i = 0;
+ struct gita *gita = (struct gita *)(info->gnt_area->addr);
+
+ list_for_each_entry(starget,
+ &(cominfo->host->__targets), siblings) {
+ starget_attrs = (struct fc_starget_attrs *)
+ (&(starget->starget_data));
+ gita->e[i].channel = starget->channel;
+ gita->e[i].id = starget->id;
+ gita->e[i].node_name = starget_attrs->node_name;
+ gita->e[i].port_id = starget_attrs->port_id;
+ gita->e[i].port_name = starget_attrs->port_name;
+ i++;
+ if (i > SCSI_FC_MAX_STARGET) {
+ ring_res->rslt = -1;
+ goto out_gita;
+ }
+ }
+ gita->num = i;
+
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+
+out_gita:
+ break; }
+
+ case CMND_GET_INITIAL_RPORT_ATTRIB: {
+ struct fc_rport *found_rport;
+ unsigned int i = 0;
+ struct gipa *gipa = (struct gipa *)(info->gnt_area->addr);
+
+ list_for_each_entry(found_rport,
+ &fc_host_rports(cominfo->host), peers) {
+ gipa->e[i].dev_loss_tmo = found_rport->dev_loss_tmo;
+ gipa->e[i].maxframe_size = found_rport->maxframe_size;
+ gipa->e[i].node_name = found_rport->node_name;
+ gipa->e[i].port_id = found_rport->port_id;
+ gipa->e[i].port_name = found_rport->port_name;
+ gipa->e[i].port_state = found_rport->port_state;
+ gipa->e[i].roles = found_rport->roles;
+ gipa->e[i].scsi_target_id
+ = found_rport->scsi_target_id;
+ gipa->e[i].supported_classes
+ = found_rport->supported_classes;
+ gipa->e[i].channel = found_rport->channel;
+ i++;
+ if (i > SCSI_FC_MAX_RPORT) {
+ ring_res->rslt = -1;
+ goto out_gipa;
+ }
+ }
+ gipa->num = i;
+
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+
+out_gipa:
+ break; }
+
+ case CMND_GET_FUNCTION_TEMPLATE: {
+ struct fc_function_template *ft;
+ struct gftp *gftp = (struct gftp *)(info->gnt_area->addr);
+ struct fc_function_template_shared *fts = &(gftp->ft);
+
+ ft = fc_shost2ft(cominfo->host);
+
+ SET_FT(ft, get_rport_dev_loss_tmo, fts);
+ SET_FT(ft, set_rport_dev_loss_tmo, fts);
+ SET_FT(ft, get_starget_node_name, fts);
+ SET_FT(ft, get_starget_port_name, fts);
+ SET_FT(ft, get_starget_port_id, fts);
+ SET_FT(ft, get_host_port_id, fts);
+ SET_FT(ft, get_host_port_type, fts);
+ SET_FT(ft, get_host_port_state, fts);
+ SET_FT(ft, get_host_active_fc4s, fts);
+ SET_FT(ft, get_host_speed, fts);
+ SET_FT(ft, get_host_fabric_name, fts);
+ SET_FT(ft, get_fc_host_stats, fts);
+ SET_FT(ft, reset_fc_host_stats, fts);
+ SET_FT(ft, issue_fc_host_lip, fts);
+
+ fts->dd_fcrport_size = ft->dd_fcrport_size;
+
+ SET_FT(ft, show_rport_maxframe_size, fts);
+ SET_FT(ft, show_rport_supported_classes, fts);
+ SET_FT(ft, show_rport_dev_loss_tmo, fts);
+ SET_FT(ft, show_starget_node_name, fts);
+ SET_FT(ft, show_starget_port_name, fts);
+ SET_FT(ft, show_starget_port_id, fts);
+ SET_FT(ft, show_host_node_name, fts);
+ SET_FT(ft, show_host_port_name, fts);
+ SET_FT(ft, show_host_permanent_port_name, fts);
+ SET_FT(ft, show_host_supported_classes, fts);
+ SET_FT(ft, show_host_supported_fc4s, fts);
+ SET_FT(ft, show_host_symbolic_name, fts);
+ SET_FT(ft, show_host_supported_speeds, fts);
+ SET_FT(ft, show_host_maxframe_size, fts);
+ SET_FT(ft, show_host_serial_number, fts);
+ SET_FT(ft, show_host_port_id, fts);
+ SET_FT(ft, show_host_port_type, fts);
+ SET_FT(ft, show_host_port_state, fts);
+ SET_FT(ft, show_host_active_fc4s, fts);
+ SET_FT(ft, show_host_speed, fts);
+ SET_FT(ft, show_host_fabric_name, fts);
+
+ ring_res->rqid = ring_req->rqid;
+ ring_res->rslt = 0;
+
+ break; }
+
+ default:
+ printk(KERN_ERR "fcback: %s: unknown command>>>\n",
+ __FUNCTION__);
+ ring_res->rslt = -1;
+ break;
+ }
+
+ comback_do_reply(cominfo);
+
+ return 0;
+}
+
+void fcback_cmd_exec(pending_req_t *pending_req)
+{
+ (void)fcback_main((struct fcback_info *)(pending_req->info->fcinfo),
+ &(pending_req->u.fc.ftb_req));
+}
+
+
+/* ---------------------------------------------------------------------- */
+static int __setup_xenstore(struct fcback_info *info)
+{
+ struct xenbus_device *dev = info->cominfo->dev;
+ int gntref;
+ int ret = 0;
+
+ if ((ret = xenbus_gather(XBT_NIL, dev->otherend,
+ "fc_gntref", "%d", &gntref, NULL)) != 0) {
+ printk(KERN_ERR "fcback: %s: xenbus_gather() error>>>\n",
+ __FUNCTION__);
+ return ret;
+ }
+
+ info->gntref = gntref;
+
+ return 0;
+}
+
+static void __unsetup_xenstore(struct fcback_info *info)
+{
+ /* currently, nothing to do */
+}
+
+static int __setup_grant_table(struct fcback_info *info)
+{
+ struct gnttab_map_grant_ref op;
+ struct vm_struct *gnt_area;
+ int err;
+
+ if ((gnt_area = alloc_vm_area(PAGE_SIZE)) == NULL) {
+ printk(KERN_ERR "fcback: %s: alloc_vm_area() error>>>\n",
+ __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ gnttab_set_map_op(&op, (unsigned long)(gnt_area->addr),
+ GNTMAP_host_map,
+ info->gntref, info->cominfo->dev->otherend_id);
+
+ err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
+ if (op.status) {
+ printk(KERN_ERR
+ "fcback: %s: HYPERVISOR_grant_table_op() error>>>\n",
+ __FUNCTION__);
+ return op.status;
+ }
+
+ info->gnt_area = gnt_area;
+
+ return 0;
+}
+
+static void __unsetup_grant_table(struct fcback_info *info)
+{
+ /* currently, nothing to do */
+}
+
+int fcback_connection_setup(struct comback_info *cominfo)
+{
+ struct fcback_info *info;
+ int ret = 0;
+
+#if 0 /* for DEBUG */
+ printk(KERN_ERR "%s: giha=%ld\n", sizeof(struct giha), __FUNCTION__);
+ printk(KERN_ERR "%s: gita=%ld\n", sizeof(struct gita), __FUNCTION__);
+ printk(KERN_ERR "%s: gipa=%ld\n", sizeof(struct gipa), __FUNCTION__);
+ printk(KERN_ERR "%s: gftp=%ld\n", sizeof(struct gftp), __FUNCTION__);
+#endif
+
+ {
+ cominfo->fcinfo = kmalloc(sizeof(struct fcback_info),
+ GFP_KERNEL);
+ if (cominfo->fcinfo == NULL) {
+ ret = -ENOMEM;
+ goto out0;
+ }
+ memset(cominfo->fcinfo, 0, sizeof(struct fcback_info));
+ info = (struct fcback_info *)(cominfo->fcinfo);
+ info->cominfo = cominfo;
+ }
+
+ /* exchange various parameters through xenstore */
+ if ((ret = __setup_xenstore(info)) != 0) {
+ printk(KERN_ERR "fcback: %s: __setup_xenstore() error>>>\n",
+ __FUNCTION__);
+ goto out1;
+ }
+
+ /* prepare for grant table */
+ if ((ret = __setup_grant_table(info)) != 0) {
+ printk(KERN_ERR "fcback: %s: __setup_grant_table() error>>>\n",
+ __FUNCTION__);
+ goto out2;
+ }
+
+ return 0;
+
+out2:
+ __unsetup_xenstore(info);
+
+out1:
+ kfree(cominfo->fcinfo);
+
+out0:
+ return ret;
+}
+
+void
+fcback_connection_unsetup(struct comback_info *cominfo)
+{
+ struct fcback_info *info = (struct fcback_info *)(cominfo->fcinfo);
+
+ __unsetup_grant_table(info);
+ __unsetup_xenstore(info);
+
+ kfree(cominfo->fcinfo);
+}
+
+
+MODULE_DESCRIPTION("Xen Para-Virtual SCSI Fibre Channel Backend Driver");
+MODULE_LICENSE("GPL");
diff -r 24e0cb9fe9df -r 374aa5b73105 drivers/xen/scsiback/fcback.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsiback/fcback.h Tue Oct 30 16:43:10 2007 +0900
@@ -0,0 +1,191 @@
+/*
+ * Xen SCSI frontend driver
+ *
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * Based on the scsifront driver code by FUJITA Tomonori
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+
+#ifndef __XEN_DRIVERS_FCFRONT_H__
+#define __XEN_DRIVERS_FCFRONT_H__
+
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+
+/* ----------------------------------------------------------------------
+ Definition of Grant Table Structures
+ ---------------------------------------------------------------------- */
+
+#define SCSI_FC_MAX_STARGET 32 /* limited by PAGE_SIZE */
+#define SCSI_FC_MAX_RPORT 32 /* limited by PAGE_SIZE */
+
+struct giha {
+ u8 active_fc4s[FC_FC4_LIST_SIZE];
+ u64 fabric_name;
+ u64 node_name;
+ u64 permanent_port_name;
+ u32 maxframe_size;
+ u32 port_id;
+ u64 port_name;
+ enum fc_port_state port_state;
+ enum fc_port_type port_type;
+ char serial_number[FC_SERIAL_NUMBER_SIZE];
+ struct fc_host_statistics stats;
+ u32 speed;
+ u32 supported_classes;
+ u8 supported_fc4s[FC_FC4_LIST_SIZE];
+ char symbolic_name[FC_SYMBOLIC_NAME_SIZE];
+ u32 supported_speeds;
+ enum fc_tgtid_binding_type tgtid_bind_type;
+};
+
+struct gita {
+ u32 num;
+ u32 padding1;
+ struct {
+ u64 node_name;
+ u64 port_name;
+ u32 port_id;
+ u32 channel;
+ u32 id;
+ u32 padding2;
+ } e[SCSI_FC_MAX_STARGET];
+};
+
+struct gipa {
+ u32 num;
+ u32 padding1;
+ struct {
+ u32 dev_loss_tmo;
+ u32 maxframe_size;
+ u64 node_name;
+ u64 port_name;
+ u32 port_id;
+ enum fc_port_state port_state;
+ u32 roles;
+ u32 scsi_target_id;
+ u32 supported_classes;
+ u32 channel;
+ } e[SCSI_FC_MAX_RPORT];
+};
+
+struct fc_function_template_shared {
+ u64 get_rport_dev_loss_tmo:1;
+ u64 set_rport_dev_loss_tmo:1;
+ u64 get_starget_node_name:1;
+ u64 get_starget_port_name:1;
+ u64 get_starget_port_id:1;
+ u64 get_host_port_id:1;
+ u64 get_host_port_type:1;
+ u64 get_host_port_state:1;
+ u64 get_host_active_fc4s:1;
+ u64 get_host_speed:1;
+ u64 get_host_fabric_name:1;
+ u64 get_fc_host_stats:1;
+ u64 reset_fc_host_stats:1;
+ u64 issue_fc_host_lip:1;
+ u64 padding1:50;
+
+ u64 show_rport_maxframe_size:1;
+ u64 show_rport_supported_classes:1;
+ u64 show_rport_dev_loss_tmo:1;
+ u64 show_starget_node_name:1;
+ u64 show_starget_port_name:1;
+ u64 show_starget_port_id:1;
+ u64 show_host_node_name:1;
+ u64 show_host_port_name:1;
+ u64 show_host_permanent_port_name:1;
+ u64 show_host_supported_classes:1;
+ u64 show_host_supported_fc4s:1;
+ u64 show_host_symbolic_name:1;
+ u64 show_host_supported_speeds:1;
+ u64 show_host_maxframe_size:1;
+ u64 show_host_serial_number:1;
+ u64 show_host_port_id:1;
+ u64 show_host_port_type:1;
+ u64 show_host_port_state:1;
+ u64 show_host_active_fc4s:1;
+ u64 show_host_speed:1;
+ u64 show_host_fabric_name:1;
+ u64 padding2:43;
+
+ u32 dd_fcrport_size;
+ u32 padding3;
+};
+
+struct gftp {
+
+ struct fc_function_template_shared ft;
+
+};
+
+
+/* ----------------------------------------------------------------------
+ Definition of Internal Information Structures
+ ---------------------------------------------------------------------- */
+
+struct fcfront_info {
+ struct comfront_info *cominfo;
+
+ int gntref;
+ void *addr;
+
+ /* On backend, "hs" is stored in ***_hba */
+ struct fc_host_statistics hs;
+};
+
+struct fcback_info {
+ struct comback_info *cominfo;
+
+ int gntref;
+ struct vm_struct *gnt_area;
+
+ struct vscsiif_ftb_request ftb_req;
+};
+
+
+/* ----------------------------------------------------------------------
+ Definition of Front/Back common functions
+ ---------------------------------------------------------------------- */
+
+struct fc_internal_head {
+ struct scsi_transport_template t;
+ struct fc_function_template *f;
+};
+
+
+static struct fc_function_template *
+fc_shost2ft(struct Scsi_Host *shost)
+{
+ struct fc_internal_head *i;
+
+ i = container_of(shost->transportt, struct fc_internal_head, t);
+ return i->f;
+}
+
+#endif /*__XEN_DRIVERS_FCFRONT_H__*/
diff -r 24e0cb9fe9df -r 374aa5b73105 drivers/xen/scsiback/interface.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsiback/interface.c Tue Oct 30 16:43:10 2007 +0900
@@ -0,0 +1,215 @@
+/*
+ * interface management.
+ *
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * Based on the blkback driver code.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#ifdef CONFIG_XEN_FC
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+#endif
+
+#include "comback.h"
+
+#include <xen/evtchn.h>
+#include <linux/kthread.h>
+
+extern irqreturn_t comback_intr(int, void *, struct pt_regs *);
+
+
+static kmem_cache_t *scsiback_cachep;
+
+struct comback_info *scsiinfo_alloc(domid_t domid)
+{
+ struct comback_info *info;
+
+ info = kmem_cache_alloc(scsiback_cachep, GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+
+ memset(info, 0, sizeof(*info));
+ info->domid = domid;
+/* spin_lock_init(&info->ring_lock_ftb);*/
+ spin_lock_init(&info->ring_lock_btf);
+ atomic_set(&info->refcnt, 1);
+ init_waitqueue_head(&info->wq);
+ init_waitqueue_head(&info->waiting_to_free);
+
+ return info;
+}
+
+static int map_frontend_page( struct comback_info *info,
+ unsigned long ftb_ring_ref, unsigned long btf_ring_ref)
+{
+ struct gnttab_map_grant_ref op;
+ int err;
+
+ gnttab_set_map_op(&op, (unsigned long)info->ftb_ring_area->addr,
+ GNTMAP_host_map, ftb_ring_ref,
+ info->domid);
+
+ err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
+ BUG_ON(err);
+
+ if (op.status) {
+ printk(KERN_ERR "scsiback: Grant table operation failure !\n");
+ return op.status;
+ }
+
+ info->ftb_shmem_ref = ftb_ring_ref;
+ info->ftb_shmem_handle = op.handle;
+
+ gnttab_set_map_op(&op, (unsigned long)info->btf_ring_area->addr,
+ GNTMAP_host_map, btf_ring_ref, info->domid);
+
+ err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
+ BUG_ON(err);
+
+ if (op.status) {
+ printk(KERN_ERR "scsiback: Grant table operation failure !\n");
+ return op.status;
+ }
+
+ info->btf_shmem_ref = btf_ring_ref;
+ info->btf_shmem_handle = op.handle;
+
+ return 0;
+}
+
+static void unmap_frontend_page(struct comback_info *info)
+{
+ struct gnttab_unmap_grant_ref op;
+ int err;
+
+ gnttab_set_unmap_op(&op, (unsigned long)info->ftb_ring_area->addr,
+ GNTMAP_host_map, info->ftb_shmem_handle);
+
+ err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
+ BUG_ON(err);
+
+ gnttab_set_unmap_op(&op, (unsigned long)info->btf_ring_area->addr,
+ GNTMAP_host_map, info->btf_shmem_handle);
+
+ err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
+ BUG_ON(err);
+}
+
+int scsiback_init_sring(struct comback_info *info,
+ unsigned long ftb_ring_ref, unsigned long btf_ring_ref, unsigned int evtchn)
+{
+ struct vscsiif_ftb_sring *ftb_sring;
+ struct vscsiif_btf_sring *btf_sring;
+ int err;
+
+ if (info->irq) {
+ printk(KERN_ERR "scsiback: Already connected through?\n");
+ return 0;
+ }
+
+ info->ftb_ring_area = alloc_vm_area(PAGE_SIZE);
+ if (!info)
+ return -ENOMEM;
+ info->btf_ring_area = alloc_vm_area(PAGE_SIZE);
+ if (!info)
+ return -ENOMEM;
+
+ err = map_frontend_page(info, ftb_ring_ref, btf_ring_ref);
+ if (err)
+ goto free_vm;
+
+ ftb_sring = (struct vscsiif_ftb_sring *) info->ftb_ring_area->addr;
+ BACK_RING_INIT(&info->ftb_ring, ftb_sring, PAGE_SIZE);
+
+ btf_sring = (struct vscsiif_btf_sring *) info->btf_ring_area->addr;
+ FRONT_RING_INIT(&info->btf_ring, btf_sring, PAGE_SIZE);
+
+ err = bind_interdomain_evtchn_to_irqhandler(
+ info->domid, evtchn,
+ comback_intr, 0, "scsiif-backend", info);
+
+ if (err < 0)
+ goto unmap_page;
+
+ info->irq = err;
+
+ return 0;
+
+unmap_page:
+ unmap_frontend_page(info);
+free_vm:
+ free_vm_area(info->ftb_ring_area);
+ free_vm_area(info->btf_ring_area);
+ return err;
+}
+
+void scsiback_disconnect(struct comback_info *info)
+{
+ if (info->kthread) {
+ kthread_stop(info->kthread);
+ info->kthread = NULL;
+ }
+
+ atomic_dec(&info->refcnt);
+ wait_event(info->waiting_to_free, atomic_read(&info->refcnt) == 0);
+ atomic_inc(&info->refcnt);
+
+ if (info->irq) {
+ unbind_from_irqhandler(info->irq, info);
+ info->irq = 0;
+ }
+
+ if (info->ftb_ring.sring || info->btf_ring.sring) {
+ unmap_frontend_page(info);
+ free_vm_area(info->ftb_ring_area);
+ free_vm_area(info->btf_ring_area);
+ info->ftb_ring.sring = NULL;
+ info->btf_ring.sring = NULL;
+ }
+}
+
+void scsiback_free(struct comback_info *info)
+{
+ if (!atomic_dec_and_test(&info->refcnt))
+ BUG();
+ kmem_cache_free(scsiback_cachep, info);
+}
+
+void __init scsiback_interface_init(void)
+{
+ scsiback_cachep = kmem_cache_create("scsiif_cache",
+ sizeof(struct comback_info), 0, 0, NULL, NULL);
+}
+
+void __exit scsiback_interface_exit(void)
+{
+ kmem_cache_destroy(scsiback_cachep);
+}
diff -r 24e0cb9fe9df -r 374aa5b73105 drivers/xen/scsiback/scsiback.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsiback/scsiback.c Tue Oct 30 16:43:10 2007 +0900
@@ -0,0 +1,556 @@
+/*
+ * Xen SCSI backend driver
+ *
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * Based on the blkback driver code.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/list.h>
+#include <linux/blkdev.h>
+#include <linux/kthread.h>
+#include <xen/balloon.h>
+#include <asm/hypervisor.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_eh.h>
+
+#ifdef CONFIG_XEN_FC
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+#endif
+
+#include "comback.h"
+
+extern struct vscsiif_btf_request * comback_pre_reply(struct comback_info *);
+extern void comback_do_reply(struct comback_info *);
+extern void free_req(pending_req_t *req);
+extern int __init scsi_trace_init(void);
+extern void __exit scsi_trace_exit(void);
+
+int vscsiif_reqs = DEFAULT_CAN_QUEUE;
+module_param_named(reqs, vscsiif_reqs, int, 0);
+MODULE_PARM_DESC(reqs, "Number of scsiback requests to allocate");
+
+
+#define INVALID_GRANT_HANDLE 0xFFFF
+#define SCSIBACK_INVALID_HANDLE (~0)
+
+static pending_req_t *pending_reqs;
+struct list_head pending_free;
+static struct page **pending_pages;
+static grant_handle_t *pending_grant_handles;
+
+static inline int vaddr_pagenr(pending_req_t *req, int seg)
+{
+ return (req - pending_reqs) * SG_TABLESIZE + seg;
+}
+
+static inline unsigned long vaddr(pending_req_t *req, int seg)
+{
+ unsigned long pfn = page_to_pfn(pending_pages[vaddr_pagenr(req, seg)]);
+ return (unsigned long)pfn_to_kaddr(pfn);
+}
+
+#define pending_handle(_req, _seg) \
+ (pending_grant_handles[vaddr_pagenr(_req, _seg)])
+
+
+static void fast_flush_area(pending_req_t *req)
+{
+ struct gnttab_unmap_grant_ref unmap[SG_TABLESIZE];
+ unsigned int i, invcount = 0;
+ grant_handle_t handle;
+ int err;
+
+ if (req->u.scsi.use_sg) {
+ for (i = 0; i < req->u.scsi.use_sg; i++) {
+ handle = pending_handle(req, i);
+ if (handle == SCSIBACK_INVALID_HANDLE)
+ continue;
+ gnttab_set_unmap_op(&unmap[i], vaddr(req, i),
+ GNTMAP_host_map, handle);
+ pending_handle(req, i) = SCSIBACK_INVALID_HANDLE;
+ invcount++;
+ }
+
+ err = HYPERVISOR_grant_table_op(
+ GNTTABOP_unmap_grant_ref, unmap, invcount);
+ BUG_ON(err);
+ } else if (req->u.scsi.request_bufflen) {
+ handle = pending_handle(req, 0);
+ if (handle == SCSIBACK_INVALID_HANDLE)
+ return;
+ gnttab_set_unmap_op(&unmap[0], vaddr(req, 0),
+ GNTMAP_host_map, handle);
+ pending_handle(req, 0) = SCSIBACK_INVALID_HANDLE;
+
+ err = HYPERVISOR_grant_table_op(
+ GNTTABOP_unmap_grant_ref, unmap, 1);
+ BUG_ON(err);
+ }
+
+ return;
+}
+
+
+static void make_sense(struct comback_info *info, struct request *req,
+ int32_t result, uint64_t rqid)
+{
+ struct vscsiif_btf_request *btf_req;
+
+ DPRINTK("%s\n",__FUNCTION__);
+
+ btf_req = comback_pre_reply(info);
+
+ memset(btf_req->u.scsi.sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+
+ btf_req->rslt = result;
+ btf_req->rqid = rqid;
+
+ if (result != 0 && req != NULL ) {
+ memcpy(btf_req->u.scsi.sense_buffer, req->sense, req->sense_len);
+ btf_req->u.scsi.sense_len = req->sense_len;
+ } else
+ btf_req->u.scsi.sense_len = 0;
+
+ comback_do_reply(info);
+
+}
+
+
+static void scsiback_end_cmd_fn(struct request *req, int error)
+{
+ unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];
+ pending_req_t *pending_req = req->end_io_data;
+ pending_req->u.scsi.rq = req;
+
+ DPRINTK("%s\n",__FUNCTION__);
+
+ if (req->errors != 0) {
+
+ printk("scsiback: SCSI CMD return. req->errors = 0x%08x\n",
+ req->errors);
+ printk("scsiback: status = 0x%02x, message = 0x%02x, host = 0x%02x, driver = 0x%02x\n",
+ status_byte(req->errors), msg_byte(req->errors),
+ host_byte(req->errors), driver_byte(req->errors));
+ memcpy(sense_buffer, req->sense, req->sense_len);
+ __scsi_print_sense("scsiback", sense_buffer, req->sense_len);
+
+ }
+
+ if (atomic_dec_and_test(&pending_req->u.scsi.pendcnt)) {
+ fast_flush_area(pending_req);
+ make_sense(pending_req->info, pending_req->u.scsi.rq,
+ req->errors, pending_req->u.scsi.rqid);
+ scsiback_put(pending_req->info);
+ free_req(pending_req);
+ }
+
+ __blk_put_request(req->q, req);
+
+}
+
+
+/* quoted scsi_lib.c/scsi_merge_bio */
+static int scsiback_merge_bio(struct request *rq, struct bio *bio)
+{
+ struct request_queue *q = rq->q;
+
+ bio->bi_flags &= ~(1 << BIO_SEG_VALID);
+ if (rq_data_dir(rq) == WRITE)
+ bio->bi_rw |= (1 << BIO_RW);
+
+ blk_queue_bounce(q, &bio);
+
+ if (!rq->bio)
+ blk_rq_bio_prep(q, rq, bio);
+ else if (!q->back_merge_fn(q, rq, bio))
+ return -EINVAL;
+ else {
+ rq->biotail->bi_next = bio;
+ rq->biotail = bio;
+ rq->hard_nr_sectors += bio_sectors(bio);
+ rq->nr_sectors = rq->hard_nr_sectors;
+ }
+
+ return 0;
+}
+
+
+/* quoted scsi_lib.c/scsi_bi_endio */
+static int scsiback_bi_endio(struct bio *bio, unsigned int bytes_done, int error)
+{
+ if (bio->bi_size)
+ return 1;
+
+ bio_put(bio);
+ return 0;
+}
+
+
+/* quoted scsi_lib.c/scsi_req_map_sg . */
+static int requset_map_sg(pending_req_t *pending_req, int count)
+{
+ struct request *rq = pending_req->u.scsi.rq;
+ struct request_queue *q = pending_req->u.scsi.rq->q;
+ int nr_pages;
+ int nsegs = count;
+
+ unsigned int data_len = 0, len, bytes, off;
+ struct page *page;
+ struct bio *bio = NULL;
+ int i, err, nr_vecs = 0;
+
+ for (i = 0; i < nsegs; i++) {
+ page = virt_to_page(vaddr(pending_req, i));
+
+ off = pending_req->u.scsi.pend_seg[i].offset;
+ len = pending_req->u.scsi.pend_seg[i].length;
+ data_len += len;
+
+ nr_pages = (len + off + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ while (len > 0) {
+ bytes = min_t(unsigned int, len, PAGE_SIZE - off);
+
+ if (!bio) {
+ nr_vecs = min_t(int, BIO_MAX_PAGES, nr_pages);
+ nr_pages -= nr_vecs;
+ bio = bio_alloc(GFP_KERNEL, nr_vecs);
+ if (!bio) {
+ err = -ENOMEM;
+ goto free_bios;
+ }
+ bio->bi_end_io = scsiback_bi_endio;
+ }
+
+ if (bio_add_pc_page(q, bio, page, bytes, off) !=
+ bytes) {
+ bio_put(bio);
+ err = -EINVAL;
+ goto free_bios;
+ }
+
+ if (bio->bi_vcnt >= nr_vecs) {
+ err = scsiback_merge_bio(rq, bio);
+ if (err) {
+ bio_endio(bio, bio->bi_size, 0);
+ goto free_bios;
+ }
+ bio = NULL;
+ }
+
+ page++;
+ len -= bytes;
+ off = 0;
+ }
+ }
+
+ rq->buffer = rq->data = NULL;
+ rq->data_len = data_len;
+ return 0;
+
+free_bios:
+ while ((bio = rq->bio) != NULL) {
+ rq->bio = bio->bi_next;
+ /*
+ * call endio instead of bio_put incase it was bounced
+ */
+ bio_endio(bio, bio->bi_size, 0);
+ }
+
+ return err;
+}
+
+int copy_request_ring_info(struct comback_info *info,
+ struct vscsiif_ftb_request *ftb_req, pending_req_t *pending_req)
+{
+ int write;
+ char sense[SCSI_SENSE_BUFFERSIZE];
+ int i;
+
+ DPRINTK("%s\n",__FUNCTION__);
+
+ pending_req->u.scsi.rqid = ftb_req->rqid;
+ pending_req->u.scsi.sdev = scsi_device_lookup(info->host,
+ ftb_req->u.scsi.channel, ftb_req->u.scsi.id, ftb_req->u.scsi.lun);
+ if (!pending_req->u.scsi.sdev) {
+ goto fail_response;
+ }
+
+ write = (ftb_req->u.scsi.sc_data_direction == DMA_TO_DEVICE);
+ pending_req->u.scsi.data_dir = ftb_req->u.scsi.sc_data_direction;
+ pending_req->u.scsi.rq =
+ blk_get_request(pending_req->u.scsi.sdev->request_queue,
+ write, GFP_KERNEL);
+ pending_req->info = info;
+ pending_req->u.scsi.use_sg = ftb_req->u.scsi.use_sg;
+ pending_req->u.scsi.request_bufflen = ftb_req->u.scsi.request_bufflen;
+
+
+ pending_req->u.scsi.rq->flags |= REQ_BLOCK_PC;
+ pending_req->u.scsi.rq->cmd_len = ftb_req->u.scsi.cmd_len;
+ memcpy(pending_req->u.scsi.rq->cmd, ftb_req->u.scsi.cmnd,
+ ftb_req->u.scsi.cmd_len);
+
+ memset(sense, 0, sizeof(sense)); /*FIXME*/
+ pending_req->u.scsi.rq->sense = sense;
+ pending_req->u.scsi.rq->sense_len = SCSI_SENSE_BUFFERSIZE;
+
+/* pending_req->u.scsi.rq->retries = ftb_req->u.scsi.retries;*/
+ pending_req->u.scsi.rq->retries = 0;
+ pending_req->u.scsi.rq->timeout = ftb_req->u.scsi.timeout_per_command;
+
+ pending_req->u.scsi.rq->end_io_data = pending_req;
+
+ if (ftb_req->u.scsi.use_sg) {
+ for (i = 0; i < ftb_req->u.scsi.use_sg; i++) {
+ pending_req->u.scsi.pend_seg[i].gref = ftb_req->u.scsi.seg[i].gref;
+ pending_req->u.scsi.pend_seg[i].offset = ftb_req->u.scsi.seg[i].offset;
+ pending_req->u.scsi.pend_seg[i].length = ftb_req->u.scsi.seg[i].length;
+ }
+ } else if (ftb_req->u.scsi.request_bufflen) {
+ pending_req->u.scsi.pend_seg[0].gref = ftb_req->u.scsi.seg[0].gref;
+ pending_req->u.scsi.pend_seg[0].offset = ftb_req->u.scsi.seg[0].offset;
+ pending_req->u.scsi.pend_seg[0].length = ftb_req->u.scsi.seg[0].length;
+ }
+
+ return 0;
+
+fail_response:
+ return 1;
+}
+
+
+void scsiback_cmd_exec(pending_req_t *pending_req)
+{
+
+ struct gnttab_map_grant_ref map[SG_TABLESIZE];
+ struct comback_info *info = pending_req->info;
+
+ int write = (pending_req->u.scsi.data_dir == DMA_TO_DEVICE);
+ u32 flags;
+ int i, err = 0;
+
+ DPRINTK("%s\n",__FUNCTION__);
+
+ if (!pending_req->u.scsi.sdev) {
+ goto fail_response;
+ }
+
+ if (pending_req->u.scsi.use_sg) {
+
+ for (i = 0; i < pending_req->u.scsi.use_sg; i++) {
+ flags = GNTMAP_host_map;
+ if (write)
+ flags |= GNTMAP_readonly;
+ gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags,
+ pending_req->u.scsi.pend_seg[i].gref,
+ info->domid);
+ }
+
+ err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
+ map, pending_req->u.scsi.use_sg);
+ BUG_ON(err);
+
+ for (i = 0; i < pending_req->u.scsi.use_sg; i++) {
+ if (unlikely(map[i].status != 0)) {
+ printk(KERN_ERR "scsiback: invalid buffer -- could not remap it\n");
+ map[i].handle = SCSIBACK_INVALID_HANDLE;
+ err |= 1;
+ }
+
+ pending_handle(pending_req, i) = map[i].handle;
+
+ if (err)
+ continue;
+
+ set_phys_to_machine(__pa(vaddr(
+ pending_req, i)) >> PAGE_SHIFT,
+ FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
+ }
+
+ if (err)
+ goto fail_flush;
+
+ if (requset_map_sg(pending_req, pending_req->u.scsi.use_sg)) {
+ printk(KERN_ERR "scsiback: SG Request Map Error\n");
+ goto fail_map;
+ }
+
+ } else if (pending_req->u.scsi.request_bufflen) {
+
+ flags = GNTMAP_host_map;
+ if (write)
+ flags |= GNTMAP_readonly;
+ gnttab_set_map_op(&map[0], vaddr(pending_req, 0), flags,
+ pending_req->u.scsi.pend_seg[0].gref,
+ info->domid);
+
+ err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, 1);
+ BUG_ON(err);
+
+ if (unlikely(map[0].status != 0)) {
+ printk(KERN_ERR "scsiback: invalid buffer single -- could not remap it\n");
+ map[0].handle = SCSIBACK_INVALID_HANDLE;
+ err |= 1;
+ }
+
+ pending_handle(pending_req, 0) = map[0].handle;
+
+ set_phys_to_machine(__pa(vaddr(
+ pending_req, 0)) >> PAGE_SHIFT,
+ FOREIGN_FRAME(map[0].dev_bus_addr >> PAGE_SHIFT));
+
+ if (err)
+ goto fail_flush;
+
+ if (requset_map_sg(pending_req, 1)) {
+ printk(KERN_ERR "scsiback: SG Request Map Error\n");
+ goto fail_map;
+ }
+ }
+
+ atomic_set(&pending_req->u.scsi.pendcnt, 1);
+ scsiback_get(info);
+
+ blk_execute_rq_nowait(pending_req->u.scsi.rq->q, NULL,
+ pending_req->u.scsi.rq, 1, scsiback_end_cmd_fn);
+
+ return ;
+
+fail_map:
+fail_flush:
+ fast_flush_area(pending_req);
+fail_response:
+ make_sense(info, NULL, (DID_NO_CONNECT << 16), pending_req->u.scsi.rqid);
+ free_req(pending_req);
+
+}
+
+
+void scsiback_reset_exec(pending_req_t *pending_req)
+{
+ struct scsi_device *sdev = pending_req->u.scsi.sdev;
+ struct comback_info *info = pending_req->info;
+ struct vscsiif_btf_request *ring_res;
+ int err;
+
+ err = scsi_reset_provider(sdev, SCSI_TRY_RESET_HOST);
+ if (err != SUCCESS)
+ err = scsi_reset_provider(sdev, SCSI_TRY_RESET_BUS);
+
+ ring_res = comback_pre_reply(info);
+
+ ring_res->rqid = pending_req->u.scsi.rqid;
+ ring_res->rslt = err;
+
+ comback_do_reply(info);
+
+}
+
+
+static int __init scsiback_init(void)
+{
+ int i, mmap_pages;
+
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+ mmap_pages = vscsiif_reqs * SG_TABLESIZE;
+
+ pending_reqs = kmalloc(sizeof(pending_reqs[0]) *
+ vscsiif_reqs, GFP_KERNEL);
+ pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
+ mmap_pages, GFP_KERNEL);
+ pending_pages = alloc_empty_pages_and_pagevec(mmap_pages);
+
+ if (!pending_reqs || !pending_grant_handles || !pending_pages)
+ goto out_of_memory;
+
+ for (i = 0; i < mmap_pages; i++)
+ pending_grant_handles[i] = SCSIBACK_INVALID_HANDLE;
+
+ scsiback_interface_init();
+
+ memset(pending_reqs, 0, sizeof(pending_reqs));
+ INIT_LIST_HEAD(&pending_free);
+
+ for (i = 0; i < vscsiif_reqs; i++)
+ list_add_tail(&pending_reqs[i].u.scsi.free_list, &pending_free);
+
+ if (scsiif_xenbus_init())
+ goto out_of_memory;
+
+ (void)scsi_trace_init();
+
+#if 0 /*DEBUG*/
+ printk(KERN_ERR "%s: ftb_req=%ld\n", __FUNCTION__,
+ sizeof(struct vscsiif_ftb_request));
+ printk(KERN_ERR "%s: ftb_res=%ld\n", __FUNCTION__,
+ sizeof(struct vscsiif_ftb_response));
+ printk(KERN_ERR "%s: btf_req=%ld\n", __FUNCTION__,
+ sizeof(struct vscsiif_btf_request));
+ printk(KERN_ERR "%s: btf_res=%ld\n", __FUNCTION__,
+ sizeof(struct vscsiif_btf_response));
+ printk("%s SCSI_RING_SIZE_ftb=%ld\n", __FUNCTION__,
+ __RING_SIZE((struct vscsiif_ftb_sring *)0, PAGE_SIZE));
+ printk("%s SCSI_RING_SIZE_btf=%ld\n", __FUNCTION__,
+ __RING_SIZE((struct vscsiif_btf_sring *)0, PAGE_SIZE));
+
+#endif /*DEBUG*/
+
+
+ return 0;
+
+ out_of_memory:
+ kfree(pending_reqs);
+ kfree(pending_grant_handles);
+ free_empty_pages_and_pagevec(pending_pages, mmap_pages);
+ printk(KERN_ERR "scsiback: %s: out of memory\n", __FUNCTION__);
+ return -ENOMEM;
+}
+
+static void __exit scsiback_exit(void)
+{
+ scsiif_xenbus_unregister();
+ scsiback_interface_exit();
+ scsi_trace_exit();
+ kfree(pending_reqs);
+ kfree(pending_grant_handles);
+ free_empty_pages_and_pagevec(pending_pages, (vscsiif_reqs * SG_TABLESIZE));
+}
+
+module_init(scsiback_init);
+module_exit(scsiback_exit);
+
+MODULE_DESCRIPTION("Xen SCSI backend driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff -r 24e0cb9fe9df -r 374aa5b73105 drivers/xen/scsiback/traceback.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsiback/traceback.c Tue Oct 30 16:43:10 2007 +0900
@@ -0,0 +1,109 @@
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+
+#include <linux/time.h>
+
+
+#define MAX_DATA_SIZE 472 /* should be modified */
+ /* according to data */
+ /* to be recorded */
+#define ENTRY_NUM (16 * 1024)
+
+struct scsi_trace_entry {
+ unsigned long dir; /* direction */
+ /* 0: pending(BE) */
+ /* 1: request(FE) */
+ /* 2: response(FE) */
+ unsigned long serial; /* incremental counter */
+ /* starts at 0 */
+ struct timeval tv; /* timeofday */
+ unsigned int size; /* data size */
+ unsigned char data[MAX_DATA_SIZE]; /* data body */
+};
+
+static struct scsi_trace_entry *scsi_trace_buf;
+EXPORT_SYMBOL(scsi_trace_buf); /* for DUMP */
+
+static DEFINE_SPINLOCK(scsi_trace_lock);
+
+void
+scsi_trace(unsigned long dir, unsigned char *data, unsigned int size)
+{
+ static unsigned long index = 0;
+ static unsigned long serial = 0;
+ unsigned long flags;
+
+ if (size > MAX_DATA_SIZE) {
+ printk(KERN_ERR "%s: data given is too big.\n"
+ "must be smaller than %d bytes.\n",
+ __FUNCTION__, MAX_DATA_SIZE);
+ return;
+ }
+
+ spin_lock_irqsave(&scsi_trace_lock, flags);
+
+ scsi_trace_buf[index].dir = dir;
+ do_gettimeofday(&(scsi_trace_buf[index].tv));
+ scsi_trace_buf[index].size = size;
+ memcpy(scsi_trace_buf[index].data, data, size);
+
+ /* This indicates that the record is successfully recorded */
+ scsi_trace_buf[index].serial = serial++;
+
+ index = (index + 1) % ENTRY_NUM;
+
+ spin_unlock_irqrestore(&scsi_trace_lock, flags);
+
+}
+
+static int
+scsi_trace_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = sizeof(struct scsi_trace_entry) * ENTRY_NUM;
+ unsigned long flags;
+
+ spin_lock_irqsave(&scsi_trace_lock, flags);
+
+ if (len <= off + count) {
+ *eof = 1;
+ }
+ *start = page;
+ len -= off;
+ if (len > count) {
+ len = count;
+ }
+ if (len < 0) {
+ len = 0;
+ } else {
+ memcpy(page, ((unsigned char *)scsi_trace_buf) + off, len);
+ }
+
+ spin_unlock_irqrestore(&scsi_trace_lock, flags);
+
+ return len;
+}
+
+int __init scsi_trace_init(void)
+{
+ unsigned int scsi_trace_buf_size;
+
+ scsi_trace_buf_size = sizeof(struct scsi_trace_entry) * ENTRY_NUM;
+ if ((scsi_trace_buf = vmalloc(scsi_trace_buf_size)) == NULL) {
+ return -1;
+ }
+ memset(scsi_trace_buf, 0, scsi_trace_buf_size);
+
+ create_proc_read_entry("scsi_trace", 0, NULL,
+ scsi_trace_read_proc, NULL);
+
+ return 0;
+}
+
+void __exit scsi_trace_exit(void)
+{
+ vfree(scsi_trace_buf);
+ remove_proc_entry("scsi_trace", NULL);
+}
+
diff -r 24e0cb9fe9df -r 374aa5b73105 drivers/xen/scsiback/xenbus.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/xen/scsiback/xenbus.c Tue Oct 30 16:43:10 2007 +0900
@@ -0,0 +1,300 @@
+/*
+ * Xen SCSI backend driver
+ *
+ * Copyright (c) 2007, FUJITSU Limited
+ *
+ * Based on the blkback driver code.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdarg.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+
+#ifdef CONFIG_XEN_FC
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+#endif
+
+#include "comback.h"
+
+extern int comback_schedule(void *);
+#ifdef CONFIG_XEN_FC
+extern int fcback_connection_setup(struct comback_info *cominfo);
+#endif
+
+struct backend_info
+{
+ struct xenbus_device *dev;
+ struct comback_info *info;
+ struct xenbus_watch backend_watch;
+};
+
+
+static int scsiback_remove(struct xenbus_device *dev)
+{
+ struct backend_info *be = dev->dev.driver_data;
+
+ if (be->backend_watch.node) {
+ unregister_xenbus_watch(&be->backend_watch);
+ kfree(be->backend_watch.node);
+ be->backend_watch.node = NULL;
+ }
+
+ if (be->info) {
+ scsiback_disconnect(be->info);
+ scsiback_free(be->info);
+ be->info = NULL;
+ }
+
+ kfree(be);
+ dev->dev.driver_data = NULL;
+
+ return 0;
+}
+
+static int scsiif_name(struct backend_info *be, char *buf)
+{
+ char *devpath;
+ struct xenbus_device *dev = be->dev;
+
+ devpath = xenbus_read(XBT_NIL, dev->nodename, "hostno", NULL);
+ if (IS_ERR(devpath))
+ return PTR_ERR(devpath);
+
+ snprintf(buf, TASK_COMM_LEN, "scsiif.%d.%s", be->info->domid, devpath);
+ kfree(devpath);
+
+ return 0;
+}
+
+static int scsiback_connect(struct backend_info *be)
+{
+ struct xenbus_device *dev = be->dev;
+ unsigned long ftb_ring_ref, btf_ring_ref;
+ unsigned int evtchn;
+ int err;
+ char name[TASK_COMM_LEN];
+
+ err = xenbus_gather(XBT_NIL, dev->otherend,
+ "ftb-ring-ref", "%lu", &ftb_ring_ref,
+ "btf-ring-ref", "%lu", &btf_ring_ref,
+ "event-channel", "%u", &evtchn, NULL);
+ if (err) {
+ xenbus_dev_fatal(dev, err, "reading %s ring", dev->otherend);
+ return err;
+ }
+
+ err = scsiback_init_sring(be->info,
+ ftb_ring_ref, btf_ring_ref, evtchn);
+ if (err)
+ return err;
+
+ err = scsiif_name(be, name);
+ if (err) {
+ xenbus_dev_error(dev, err, "get scsiback dev name");
+ return err;
+ }
+
+ be->info->kthread = kthread_run(comback_schedule, be->info, name);
+ if (IS_ERR(be->info->kthread)) {
+ err = PTR_ERR(be->info->kthread);
+ be->info->kthread = NULL;
+ xenbus_dev_error(be->dev, err, "start scsiif");
+ return err;
+ }
+
+#ifdef CONFIG_XEN_FC
+ {
+ int ret;
+
+ if ((ret = fcback_connection_setup(be->info)) != 0) {
+ printk(KERN_ERR "scsiback: %s: fcback_setup() error>>>\n",
+ __FUNCTION__);
+ return ret;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+static void scsiback_frontend_changed(struct xenbus_device *dev,
+ enum xenbus_state frontend_state)
+{
+ struct backend_info *be = dev->dev.driver_data;
+ int err;
+
+ switch (frontend_state) {
+ case XenbusStateInitialising:
+ break;
+
+ case XenbusStateInitialised:
+ case XenbusStateConnected:
+ if (dev->state == XenbusStateConnected)
+ break;
+
+ err = scsiback_connect(be);
+ if (err)
+ break;
+
+ err = xenbus_switch_state(dev, XenbusStateConnected);
+ if (err)
+ xenbus_dev_fatal(dev, err, "switching to Connected state",
+ dev->nodename);
+ break;
+
+ case XenbusStateClosing:
+ scsiback_disconnect(be->info);
+ xenbus_switch_state(dev, XenbusStateClosing);
+ break;
+
+ case XenbusStateClosed:
+ xenbus_switch_state(dev, XenbusStateClosed);
+ if (xenbus_dev_is_online(dev))
+ break;
+
+ case XenbusStateUnknown:
+ device_unregister(&dev->dev);
+ break;
+ default:
+ xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
+ frontend_state);
+ break;
+ }
+}
+
+
+static void scsiback_backend_changed(struct xenbus_watch *watch,
+ const char **vec, unsigned int len)
+{
+ int err;
+ struct backend_info *be =
+ container_of(watch, struct backend_info, backend_watch);
+ struct xenbus_device *dev = be->dev;
+
+ printk("%s SCSI_RING_SIZE_ftb=%ld\n", __FUNCTION__,
+ __RING_SIZE((struct vscsiif_ftb_sring *)0, PAGE_SIZE));
+ printk("%s SCSI_RING_SIZE_btf=%ld\n", __FUNCTION__,
+ __RING_SIZE((struct vscsiif_btf_sring *)0, PAGE_SIZE));
+
+ be->info->host = scsi_host_lookup(be->info->host_no);
+ if (IS_ERR(be->info->host)) {
+ err = PTR_ERR(be->info->host);
+ xenbus_dev_fatal(dev, err, "no lookup scsi host");
+ goto fail;
+ }
+
+ return;
+fail:
+ scsiback_remove(dev);
+}
+
+
+static int scsiback_probe(struct xenbus_device *dev,
+ const struct xenbus_device_id *id)
+{
+ int err;
+ int hostno;
+ struct backend_info *be = kzalloc(sizeof(struct backend_info),
+ GFP_KERNEL);
+
+ DPRINTK("%p %d\n", dev, dev->otherend_id);
+
+ if (!be) {
+ xenbus_dev_fatal(dev, -ENOMEM,
+ "allocating backend structure");
+ return -ENOMEM;
+ }
+ be->dev = dev;
+ dev->dev.driver_data = be;
+
+ be->info = scsiinfo_alloc(dev->otherend_id);
+ if (IS_ERR(be->info)) {
+ err = PTR_ERR(be->info);
+ be->info = NULL;
+ xenbus_dev_fatal(dev, err, "creating scsihost interface");
+ goto fail;
+ }
+
+ be->info->dev = dev;
+ be->info->irq = 0;
+
+ err = xenbus_scanf(XBT_NIL, dev->nodename, "hostno", "%d", &hostno);
+ if (err == -ENOENT ) {
+ printk(KERN_WARNING "scsiback: error xenbus_scanf hostno=%d\n",hostno);
+ goto fail;
+ }
+
+ be->info->host_no = (unsigned short)hostno;
+
+ err = xenbus_watch_path2(dev, dev->nodename,
+ "scsi-host",
+ &be->backend_watch,
+ scsiback_backend_changed);
+ if (err)
+ goto fail;
+
+ err = xenbus_switch_state(dev, XenbusStateInitWait);
+ if (err)
+ goto fail;
+
+ return 0;
+
+fail:
+ printk(KERN_WARNING "scsiback: %s failed\n",__FUNCTION__);
+ scsiback_remove(dev);
+
+ return err;
+}
+
+
+static struct xenbus_device_id scsiback_ids[] = {
+ { "scsihost" },
+ { "" }
+};
+
+static struct xenbus_driver scsiback = {
+ .name = "scsihost",
+ .owner = THIS_MODULE,
+ .ids = scsiback_ids,
+ .probe = scsiback_probe,
+ .remove = scsiback_remove,
+ .otherend_changed = scsiback_frontend_changed
+};
+
+int scsiif_xenbus_init(void)
+{
+ return xenbus_register_backend(&scsiback);
+}
+
+void scsiif_xenbus_unregister(void)
+{
+ xenbus_unregister_driver(&scsiback);
+}
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 3/6] pvSCSI (SCSI pass through) driver
2007-10-25 1:59 ` Jun Kamada
` (2 preceding siblings ...)
2007-10-30 10:39 ` [PATCH 2/6] " Jun Kamada
@ 2007-10-30 10:39 ` Jun Kamada
2007-10-30 10:39 ` [PATCH 4/6] " Jun Kamada
` (2 subsequent siblings)
6 siblings, 0 replies; 33+ messages in thread
From: Jun Kamada @ 2007-10-30 10:39 UTC (permalink / raw)
Cc: kama, xen-devel
[-- Attachment #1: Type: text/plain, Size: 281 bytes --]
This patch is for vscsiif.h.
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
-----
Jun Kamada
[-- Attachment #2: linux_vscsiif.h.patch --]
[-- Type: application/octet-stream, Size: 6553 bytes --]
# HG changeset patch
# User t.horikoshi@jp.fujitsu.com
# Date 1193730258 -32400
# Node ID 7a834d087b6e75d02b85d8b65efc2022b5bb2cb2
# Parent 374aa5b731056b2182ff60d2efa9f3524232d8d8
[LINUX] add vscsiif.h
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
diff -r 374aa5b73105 -r 7a834d087b6e include/xen/interface/io/vscsiif.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/xen/interface/io/vscsiif.h Tue Oct 30 16:44:18 2007 +0900
@@ -0,0 +1,238 @@
+/******************************************************************************
+ * scsiif.h
+ *
+ * Based on the blkif.h code.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Copyright(c) FUJITSU Limited 2007.
+ */
+
+#ifndef __XEN__PUBLIC_IO_SCSI_H__
+#define __XEN__PUBLIC_IO_SCSI_H__
+
+#include "ring.h"
+#include "../grant_table.h"
+
+#ifdef CONFIG_XEN_FC
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+#endif
+
+#define CMND_SCSI 1 /* scsi */
+#define CMND_SCSI_RESET 2 /* scsi */
+
+#ifdef CONFIG_XEN_FC
+#define CMND_GET_HOST_PORT_ID 101 /* ghpi */
+#define CMND_GET_HOST_PORT_TYPE 102 /* ghpt */
+#define CMND_GET_HOST_PORT_STATE 103 /* ghps */
+#define CMND_GET_HOST_ACTIVE_FC4S 104 /* ghaf */
+#define CMND_GET_HOST_SPEED 105 /* ghsp */
+#define CMND_GET_HOST_FABRIC_NAME 106 /* ghfn */
+#define CMND_GET_HOST_STATS 107 /* ghst */
+#define CMND_RESET_HOST_STATS 108 /* rhst */
+#define CMND_ISSUE_HOST_LIP 109 /* ihli */
+#define CMND_GET_STARGET_PORT_ID 121 /* gtpi */
+#define CMND_GET_STARGET_NODE_NAME 122 /* gtnn */
+#define CMND_GET_STARGET_PORT_NAME 123 /* gtpn */
+#define CMND_GET_RPORT_LOSS_TMO 141 /* gplt */
+#define CMND_SET_RPORT_LOSS_TMO 142 /* splt */
+#define CMND_GET_INITIAL_SHOST_ATTRIB 161 /* giha */
+#define CMND_GET_INITIAL_STARGET_ATTRIB 162 /* gita */
+#define CMND_GET_INITIAL_RPORT_ATTRIB 163 /* gipa */
+#define CMND_GET_FUNCTION_TEMPLATE 181 /* gftp */
+#endif
+
+/* ----------------------------------------------------------------------
+ Definition of Ring Structures
+ ---------------------------------------------------------------------- */
+
+#define DEFAULT_CAN_QUEUE 256
+#define VSCSI_MAX_COMMAND_SIZE 16
+#define SG_TABLESIZE 32
+
+#define SCSIIF_REQ_OKAY 0
+#define SCSIIF_BTFRING_BUSY 1
+
+/* Definition of
+ * union vscsiif_ftb_sring_entry,
+ * struct vscsiif_ftb_sring,
+ * struct vscsiif_ftb_front_ring,
+ * struct vscsiif_ftb_back_ring,
+ * vscsiif_ftb_sring_t,
+ * vscsiif_ftb_front_ring_t,
+ * vscsiif_ftb_back_ring_t
+*/
+struct vscsiif_ftb_request {
+ uint32_t rqid;
+ uint32_t cmnd;
+ union {
+ /* SCSI */
+ struct scsiif_ftb_request {
+ uint8_t cmnd[VSCSI_MAX_COMMAND_SIZE];
+ uint8_t cmd_len;
+ uint32_t id, lun, channel;
+ uint16_t sc_data_direction;
+ uint16_t use_sg;
+ uint16_t request_bufflen;
+ int32_t timeout_per_command;
+ struct scsiif_request_segment {
+ grant_ref_t gref;
+ uint32_t offset;
+ uint32_t length;
+ } seg[SG_TABLESIZE];
+ uint32_t padding;
+ } scsi;
+#ifdef CONFIG_XEN_FC
+ /* Get_sTarget_Port_Id */
+ /* Get_sTarget_Node_Name */
+ /* Get_sTarget_Port_Name */
+ struct {
+ u32 channel;
+ u32 id;
+ } gtpi, gtnn, gtpn;
+
+ /* Get_rPort_Loss_Tmo */
+ struct {
+ u64 node_name;
+ u64 port_name;
+ u32 port_id;
+ u32 roles;
+ } gplt;
+
+ /* Set_rPort_Loss_Tmo */
+ struct {
+ u64 node_name;
+ u64 port_name;
+ u32 port_id;
+ u32 roles;
+ u32 timeout;
+ u32 padding;
+ } splt;
+#endif
+ } u;
+};
+
+struct vscsiif_ftb_response {
+ uint16_t status;
+ union {
+ struct scsiif_ftb_response {
+ } scsi;
+ } u;
+};
+
+DEFINE_RING_TYPES(vscsiif_ftb, struct vscsiif_ftb_request, struct vscsiif_ftb_response);
+
+
+#define SCSI_SENSE_BUFFERSIZE 96
+
+/* Definition of
+ * union vscsiif_btf_sring_entry,
+ * struct vscsiif_btf_sring,
+ * struct vscsiif_btf_front_ring,
+ * struct vscsiif_btf_back_ring,
+ * vscsiif_btf_sring_t,
+ * vscsiif_btf_front_ring_t,
+ * vscsiif_btf_back_ring_t
+*/
+struct vscsiif_btf_request {
+ uint32_t rqid;
+ int32_t rslt;
+ union {
+ /* SCSI */
+ struct scsiif_response {
+ uint32_t sense_len;
+ uint8_t sense_buffer[SCSI_SENSE_BUFFERSIZE];
+ } scsi;
+
+#ifdef CONFIG_XEN_FC
+ /* Get_Host_Port_Id */
+ struct {
+ u32 port_id;
+ } ghpi;
+
+ /* Get_Host_Port_Type */
+ struct {
+ enum fc_port_type port_type;
+ } ghpt;
+
+ /* Get_Host_Port_State */
+ struct {
+ enum fc_port_state port_state;
+ } ghps;
+
+ /* Get_Host_Active_Fc4s */
+ struct {
+ u8 active_fc4s[FC_FC4_LIST_SIZE];
+ } ghaf;
+
+ /* Get_Host_SPeed */
+ struct {
+ u32 speed;
+ } ghsp;
+
+ /* Get_Host_Fabric_Name */
+ struct {
+ u64 fabric_name;
+ } ghfn;
+
+ /* Get_Host_STats */
+ struct {
+ struct fc_host_statistics stats;
+ } ghst;
+
+ /* Get_sTarget_Port_Id */
+ struct {
+ u32 port_id;
+ } gtpi;
+
+ /* Get_sTarget_Node_Name */
+ struct {
+ u64 node_name;
+ } gtnn;
+
+ /* Get_sTarget_Port_Name */
+ struct {
+ u64 port_name;
+ } gtpn;
+
+ /* Get_rPort_Loss_Tmo */
+ struct {
+ u32 timeout;
+ } gplt;
+
+ /* Set_rPort_Loss_Tmo */
+ struct {
+ u32 timeout;
+ } splt;
+#endif
+ } u;
+};
+
+struct vscsiif_btf_response {
+ union {
+ struct scsiif_btf_response {
+
+ } scsi;
+ } u;
+};
+
+DEFINE_RING_TYPES(vscsiif_btf, struct vscsiif_btf_request, struct vscsiif_btf_response);
+
+#endif
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 4/6] pvSCSI (SCSI pass through) driver
2007-10-25 1:59 ` Jun Kamada
` (3 preceding siblings ...)
2007-10-30 10:39 ` [PATCH 3/6] " Jun Kamada
@ 2007-10-30 10:39 ` Jun Kamada
2007-10-30 10:39 ` [PATCH 5/6] " Jun Kamada
2007-10-30 10:39 ` [PATCH 6/6] " Jun Kamada
6 siblings, 0 replies; 33+ messages in thread
From: Jun Kamada @ 2007-10-30 10:39 UTC (permalink / raw)
Cc: kama, xen-devel
[-- Attachment #1: Type: text/plain, Size: 331 bytes --]
This patch is for Makefile and Kconfig file for scsifront and scsiback
driver.
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
-----
Jun Kamada
[-- Attachment #2: add_xenscsi_makefile.patch --]
[-- Type: application/octet-stream, Size: 2613 bytes --]
# HG changeset patch
# User t.horikoshi@jp.fujitsu.com
# Date 1193730337 -32400
# Node ID 65a726ce042cb6a39551f0bf9ff220de5e5ddcbc
# Parent 7a834d087b6e75d02b85d8b65efc2022b5bb2cb2
[LINUX]add Makefile xen-scsi driver
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
diff -r 7a834d087b6e -r 65a726ce042c drivers/xen/Kconfig
--- a/drivers/xen/Kconfig Tue Oct 30 16:44:18 2007 +0900
+++ b/drivers/xen/Kconfig Tue Oct 30 16:45:37 2007 +0900
@@ -53,6 +53,29 @@ config XEN_BLKDEV_BACKEND
The block-device backend driver allows the kernel to export its
block devices to other guests via a high-performance shared-memory
interface.
+
+config XEN_SCSI_BACKEND
+ tristate "SCSI backend driver"
+ depends on XEN_BACKEND
+ default n
+ help
+ The SCSI backend driver allows the kernel to export its SCSI HBAs
+ to other guests via a high-performance shared-memory interface.
+
+choice
+ prompt "SCSI Backend Mode"
+ depends on XEN_SCSI_BACKEND
+ default XEN_SCSI_BACKEND_SCSI
+
+config XEN_SCSI_BACKEND_SCSI
+ bool "Not FC"
+
+config XEN_FC
+ bool "FC driver support"
+ ---help---
+ The function of scsi_transport_fc is add.
+
+endchoice
config XEN_BLKDEV_TAP
tristate "Block-device tap backend driver"
@@ -178,6 +201,14 @@ config XEN_BLKDEV_FRONTEND
dedicated device-driver domain, or your master control domain
(domain 0), then you almost certainly want to say Y here.
+config XEN_SCSI_FRONTEND
+ tristate "SCSI frontend driver"
+ depends on XEN && SCSI
+ default n
+ help
+ The SCSI frontend driver allows the kernel to access SCSI HBAs
+ within another guest OS.
+
config XEN_NETDEV_FRONTEND
tristate "Network-device frontend driver"
depends on XEN && NET
diff -r 7a834d087b6e -r 65a726ce042c drivers/xen/Makefile
--- a/drivers/xen/Makefile Tue Oct 30 16:44:18 2007 +0900
+++ b/drivers/xen/Makefile Tue Oct 30 16:45:37 2007 +0900
@@ -8,10 +8,12 @@ obj-y += util.o
obj-y += util.o
obj-$(CONFIG_XEN_BALLOON) += balloon/
obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/
+obj-$(CONFIG_XEN_SCSI_BACKEND) += scsiback/
obj-$(CONFIG_XEN_BLKDEV_TAP) += blktap/
obj-$(CONFIG_XEN_NETDEV_BACKEND) += netback/
obj-$(CONFIG_XEN_TPMDEV_BACKEND) += tpmback/
obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += blkfront/
+obj-$(CONFIG_XEN_SCSI_FRONTEND) += scsifront/
obj-$(CONFIG_XEN_NETDEV_FRONTEND) += netfront/
obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback/
obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront/
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 5/6] pvSCSI (SCSI pass through) driver
2007-10-25 1:59 ` Jun Kamada
` (4 preceding siblings ...)
2007-10-30 10:39 ` [PATCH 4/6] " Jun Kamada
@ 2007-10-30 10:39 ` Jun Kamada
2007-10-30 10:39 ` [PATCH 6/6] " Jun Kamada
6 siblings, 0 replies; 33+ messages in thread
From: Jun Kamada @ 2007-10-30 10:39 UTC (permalink / raw)
Cc: kama, xen-devel
[-- Attachment #1: Type: text/plain, Size: 314 bytes --]
This patch is for installing scsifront driver into pv-driver.
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
-----
Jun Kamada
[-- Attachment #2: pv-on-hvm-add_scsifront.patch --]
[-- Type: application/octet-stream, Size: 1430 bytes --]
# HG changeset patch
# User t.horikoshi@jp.fujitsu.com
# Date 1192703287 -32400
# Node ID 6d463e46778a4a8ad442edef337592dde20ede51
# Parent 18c98c82e60e483bd65f3904a96d2305839a350e
[XEN][PV-ON-HVM] add scsifront driver in PV-on-HVM
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
diff -r 18c98c82e60e -r 6d463e46778a unmodified_drivers/linux-2.6/Makefile
--- a/unmodified_drivers/linux-2.6/Makefile Thu Oct 18 19:23:52 2007 +0900
+++ b/unmodified_drivers/linux-2.6/Makefile Thu Oct 18 19:28:07 2007 +0900
@@ -4,3 +4,4 @@ obj-m += balloon/
obj-m += balloon/
obj-m += blkfront/
obj-m += netfront/
+obj-m += scsifront/
diff -r 18c98c82e60e -r 6d463e46778a unmodified_drivers/linux-2.6/scsifront/Kbuild
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/scsifront/Kbuild Thu Oct 18 19:28:07 2007 +0900
@@ -0,0 +1,5 @@
+include $(M)/overrides.mk
+
+obj-m += xen-scsi.o
+xen-scsi-objs := scsifront.o comfront.o tracefront.o
+
diff -r 18c98c82e60e -r 6d463e46778a unmodified_drivers/linux-2.6/scsifront/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/scsifront/Makefile Thu Oct 18 19:28:07 2007 +0900
@@ -0,0 +1,4 @@
+ifneq ($(KERNELRELEASE),)
+include $(src)/Kbuild
+endif
+
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 6/6] pvSCSI (SCSI pass through) driver
2007-10-25 1:59 ` Jun Kamada
` (5 preceding siblings ...)
2007-10-30 10:39 ` [PATCH 5/6] " Jun Kamada
@ 2007-10-30 10:39 ` Jun Kamada
6 siblings, 0 replies; 33+ messages in thread
From: Jun Kamada @ 2007-10-30 10:39 UTC (permalink / raw)
Cc: kama, xen-devel
[-- Attachment #1: Type: text/plain, Size: 342 bytes --]
This patch is for modifying xend in order to use pvscsi driver.
(attach/detach HBA, etc.)
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
-----
Jun Kamada
[-- Attachment #2: xend_scsihost.patch --]
[-- Type: application/octet-stream, Size: 18184 bytes --]
# HG changeset patch
# User t.horikoshi@jp.fujitsu.com
# Date 1193736851 -32400
# Node ID 980e5be7bcf419d9b7c91b61a8f7798bb10a6692
# Parent b28ae5f00553ea053bd4e4576634d8ea49e77bc3
[XEND] add scsihost interface
Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
Signed-off-by: Akira Hayakawa <hayakawa.akira@jp.fujitsu.com>
diff -r b28ae5f00553 -r 980e5be7bcf4 tools/examples/Makefile
--- a/tools/examples/Makefile Tue Oct 23 09:26:43 2007 +0100
+++ b/tools/examples/Makefile Tue Oct 30 18:34:11 2007 +0900
@@ -25,6 +25,7 @@ XEN_SCRIPTS += network-route vif-route
XEN_SCRIPTS += network-route vif-route
XEN_SCRIPTS += network-nat vif-nat
XEN_SCRIPTS += block
+XEN_SCRIPTS += scsihost
XEN_SCRIPTS += block-enbd block-nbd
XEN_SCRIPTS += blktap
XEN_SCRIPTS += vtpm vtpm-delete
diff -r b28ae5f00553 -r 980e5be7bcf4 tools/examples/scsihost
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/examples/scsihost Tue Oct 30 18:34:11 2007 +0900
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+dir=$(dirname "$0")
+. "$dir/block-common.sh"
+
+log debug "udev event."
+
+case "$command" in
+ add)
+ done=$(xenstore_read_default "$XENBUS_PATH/scsihost" 'MISSING')
+ if [ "$done" != 'MISSING' ]
+ then
+ exit 0
+ fi
+
+ # TODO
+ #xenstore_write "$XENBUS_PATH/scsi" "info"
+ success
+ ;;
+ remove)
+ # TODO
+ ;;
+esac
+
+exit 0
+
diff -r b28ae5f00553 -r 980e5be7bcf4 tools/examples/xen-backend.agent
--- a/tools/examples/xen-backend.agent Tue Oct 23 09:26:43 2007 +0100
+++ b/tools/examples/xen-backend.agent Tue Oct 30 18:34:11 2007 +0900
@@ -12,6 +12,9 @@ case "$XENBUS_TYPE" in
;;
vbd)
/etc/xen/scripts/block "$ACTION"
+ ;;
+ scsihost)
+ /etc/xen/scripts/scsihost "$ACTION"
;;
vtpm)
/etc/xen/scripts/vtpm "$ACTION"
diff -r b28ae5f00553 -r 980e5be7bcf4 tools/examples/xen-backend.rules
--- a/tools/examples/xen-backend.rules Tue Oct 23 09:26:43 2007 +0100
+++ b/tools/examples/xen-backend.rules Tue Oct 30 18:34:11 2007 +0900
@@ -1,5 +1,6 @@ SUBSYSTEM=="xen-backend", KERNEL=="tap*"
SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap $env{ACTION}"
SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block $env{ACTION}"
+SUBSYSTEM=="xen-backend", KERNEL=="scsihost*", RUN+="/etc/xen/scripts/scsihost $env{ACTION}"
SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm $env{ACTION}"
SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script} online"
SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline", RUN+="$env{script} offline"
diff -r b28ae5f00553 -r 980e5be7bcf4 tools/python/xen/xend/XendDevices.py
--- a/tools/python/xen/xend/XendDevices.py Tue Oct 23 09:26:43 2007 +0100
+++ b/tools/python/xen/xend/XendDevices.py Tue Oct 30 18:34:11 2007 +0900
@@ -19,7 +19,7 @@
# A collection of DevControllers
#
-from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif, vfbif
+from xen.xend.server import blkif, scsihostif, netif, tpmif, pciif, iopif, irqif, usbif, vfbif
from xen.xend.server.BlktapController import BlktapController
from xen.xend.server.ConsoleController import ConsoleController
@@ -36,6 +36,7 @@ class XendDevices:
controllers = {
'vbd': blkif.BlkifController,
+ 'scsihost': scsihostif.SCSIHostController,
'vif': netif.NetifController,
'vtpm': tpmif.TPMifController,
'pci': pciif.PciController,
diff -r b28ae5f00553 -r 980e5be7bcf4 tools/python/xen/xend/server/scsihostif.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/server/scsihostif.py Tue Oct 30 18:34:11 2007 +0900
@@ -0,0 +1,75 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#============================================================================
+# Copyright (C) 2007 FUJITSU Limited
+# Based on the blkif.py
+#============================================================================
+
+
+"""Support for SCSI HBAs.
+"""
+
+import re
+import string
+
+from xen.xend import sxp
+from xen.xend.XendError import VmError
+
+from xen.xend.server.DevController import DevController
+
+class SCSIHostController(DevController):
+ """SCSI HBAs.
+ """
+
+ def __init__(self, vm):
+ """Create a SCSI HBA.
+ """
+ DevController.__init__(self, vm)
+
+
+ def getDeviceDetails(self, config):
+ """@see DevController.getDeviceDetails"""
+
+ typ = config.get('type')
+ hostno = config.get('hostno')
+ back = { 'type' : typ,
+ 'hostno' : hostno,
+ }
+ devid = int(hostno)
+
+ uuid = config.get('uuid')
+ if uuid:
+ back['uuid'] = uuid
+
+ front = { 'type' : typ }
+
+ return (devid, back, front)
+
+
+ def getDeviceConfiguration(self, devid):
+ """@see DevController.configuration"""
+
+ result = DevController.getDeviceConfiguration(self, devid)
+
+ devinfo = self.readBackend(devid, 'uuid', 'type', 'hostno')
+ uuid, typ, hostno = devinfo
+
+ if uuid:
+ result['uuid'] = uuid
+ if typ:
+ result['type'] = typ
+ if hostno:
+ result['hostno'] = hostno
+
+ return result
diff -r b28ae5f00553 -r 980e5be7bcf4 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Tue Oct 23 09:26:43 2007 +0100
+++ b/tools/python/xen/xm/create.py Tue Oct 30 18:34:11 2007 +0900
@@ -286,6 +286,12 @@ gopts.var('disk', val='phy:DEV,VDEV,MODE
backend driver domain to use for the disk.
The option may be repeated to add more than one disk.""")
+gopts.var('scsihost', val='TYPE,SCSIHOSTNO',
+ fn=append_value, default=[],
+ use="""Add a SCSI-HBA device to a domain. TYPE is fc or scsi.
+ SCSIHOSTNO is scsi host number that can be seen from /proc/scsi/scsi
+ .""")
+
gopts.var('pci', val='BUS:DEV.FUNC',
fn=append_value, default=[],
use="""Add a PCI device to a domain, using given params (in hex).
@@ -581,6 +587,15 @@ def configure_disks(config_devs, vals):
if backend:
config_vbd.append(['backend', backend])
config_devs.append(['device', config_vbd])
+
+def configure_scsihost(config_devs, vals):
+ """Create the config for a SCSI HBA.
+ """
+ for (type, no) in vals.scsihost:
+ config_scsihost = ['scsihost',
+ ['type', type ],
+ ['hostno', no ] ]
+ config_devs.append(['device', config_scsihost])
def configure_pci(config_devs, vals):
"""Create the config for pci devices.
@@ -789,6 +804,7 @@ def make_config(vals):
config_devs = []
configure_disks(config_devs, vals)
+ configure_scsihost(config_devs, vals)
configure_pci(config_devs, vals)
configure_ioports(config_devs, vals)
configure_irq(config_devs, vals)
@@ -815,6 +831,19 @@ def preprocess_disk(vals):
err('Invalid disk specifier: ' + v)
disk.append(d)
vals.disk = disk
+
+def preprocess_scsihost(vals):
+ if not vals.scsihost: return
+ scsihost = []
+ for v in vals.scsihost:
+ d = v.split(',')
+ n = len(d)
+ if n == 2:
+ pass
+ else:
+ err('Invalid scsi specifier: ' + v)
+ scsihost.append(d)
+ vals.scsihost = scsihost
def preprocess_pci(vals):
if not vals.pci: return
@@ -1013,6 +1042,7 @@ def preprocess_vnc(vals):
def preprocess(vals):
preprocess_disk(vals)
+ preprocess_scsihost(vals)
preprocess_pci(vals)
preprocess_ioports(vals)
preprocess_ip(vals)
diff -r b28ae5f00553 -r 980e5be7bcf4 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Tue Oct 23 09:26:43 2007 +0100
+++ b/tools/python/xen/xm/main.py Tue Oct 30 18:34:11 2007 +0900
@@ -161,6 +161,12 @@ SUBCOMMAND_HELP = {
'Destroy a domain\'s virtual block device.'),
'block-list' : ('<Domain> [--long]',
'List virtual block devices for a domain.'),
+ 'scsihost-attach' : ('<Domain> scsi <SCSIHostno> [BackDomain]',
+ 'Create a new virtual SCSIHost device.'),
+ 'scsihost-detach' : ('<Domain> <SCSIHostno> [-f|--force]',
+ 'Destroy a domain\'s virtual SCSIHost device.'),
+ 'scsihost-list' : ('<Domain> [--long]',
+ 'List virtual SCSIHost devices for a domain.'),
'network-attach': ('<Domain> [type=<type>] [mac=<mac>] [bridge=<bridge>] '
'[ip=<ip>] [script=<script>] [backend=<BackDomain>] '
'[vifname=<name>] [rate=<rate>] [model=<model>]'
@@ -331,6 +337,9 @@ device_commands = [
"block-detach",
"block-list",
"block-configure",
+ "scsihost-attach",
+ "scsihost-detach",
+ "scsihost-list",
"network-attach",
"network-detach",
"network-list",
@@ -2028,6 +2037,32 @@ def xm_block_list(args):
"%(be-path)-30s "
% ni)
+def xm_scsihost_list(args):
+ (use_long, params) = arg_check_for_resource_list(args, "scsihost-list")
+
+ dom = params[0]
+ devs = server.xend.domain.getDeviceSxprs(dom, 'scsihost')
+
+ if use_long:
+ map(PrettyPrint.prettyprint, devs)
+ else:
+ hdr = 0
+ for x in devs:
+ if hdr == 0:
+ print 'shost BE handle state evt-ch ring-ref BE-path'
+ hdr = 1
+ ni = parse_dev_info(x[1])
+ ni['idx'] = int(x[0])
+ print ("%(idx)-3d "
+ "%(backend-id)-3d "
+ "%(handle)-3d "
+ "%(state)-3d "
+ "%(event-ch)-3d "
+ "%(ring-ref)-5d "
+ "%(be-path)-30s "
+ % ni)
+
+
def xm_vtpm_list(args):
(use_long, params) = arg_check_for_resource_list(args, "vtpm-list")
@@ -2129,6 +2164,20 @@ def xm_block_configure(args):
(dom, vbd) = parse_block_configuration(args)
server.xend.domain.device_configure(dom, vbd)
+
+
+def xm_scsihost_attach(args):
+ arg_check(args, 'scsihost-attach', 3, 4)
+
+ dom = args[0]
+
+ scsihost = ['scsihost',
+ ['type', args[1]],
+ ['hostno', args[2]]]
+ if len(args) == 4:
+ scsihost.append(['backend', args[3]])
+
+ server.xend.domain.device_create(dom, scsihost)
def xm_network_attach(args):
@@ -2253,6 +2302,10 @@ def xm_block_detach(args):
detach(args, 'tap')
else:
detach(args, 'vbd')
+
+def xm_scsihost_detach(args):
+ arg_check(args, 'scsihost-detach', 2, 3)
+ detach(args, 'scsihost')
def xm_network_detach(args):
if serverType == SERVER_XEN_API:
@@ -2449,6 +2502,10 @@ commands = {
"block-detach": xm_block_detach,
"block-list": xm_block_list,
"block-configure": xm_block_configure,
+ # scsihost
+ "scsihost-attach": xm_scsihost_attach,
+ "scsihost-detach": xm_scsihost_detach,
+ "scsihost-list": xm_scsihost_list,
# network (AKA vifs)
"network-attach": xm_network_attach,
"network-detach": xm_network_detach,
diff -r b28ae5f00553 -r 980e5be7bcf4 xen/include/public/io/vscsiif.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/public/io/vscsiif.h Tue Oct 30 18:34:11 2007 +0900
@@ -0,0 +1,238 @@
+/******************************************************************************
+ * scsiif.h
+ *
+ * Based on the blkif.h code.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Copyright(c) FUJITSU Limited 2007.
+ */
+
+#ifndef __XEN__PUBLIC_IO_SCSI_H__
+#define __XEN__PUBLIC_IO_SCSI_H__
+
+#include "ring.h"
+#include "../grant_table.h"
+
+#ifdef CONFIG_XEN_FC
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+#endif
+
+#define CMND_SCSI 1 /* scsi */
+#define CMND_SCSI_RESET 2 /* scsi */
+
+#ifdef CONFIG_XEN_FC
+#define CMND_GET_HOST_PORT_ID 101 /* ghpi */
+#define CMND_GET_HOST_PORT_TYPE 102 /* ghpt */
+#define CMND_GET_HOST_PORT_STATE 103 /* ghps */
+#define CMND_GET_HOST_ACTIVE_FC4S 104 /* ghaf */
+#define CMND_GET_HOST_SPEED 105 /* ghsp */
+#define CMND_GET_HOST_FABRIC_NAME 106 /* ghfn */
+#define CMND_GET_HOST_STATS 107 /* ghst */
+#define CMND_RESET_HOST_STATS 108 /* rhst */
+#define CMND_ISSUE_HOST_LIP 109 /* ihli */
+#define CMND_GET_STARGET_PORT_ID 121 /* gtpi */
+#define CMND_GET_STARGET_NODE_NAME 122 /* gtnn */
+#define CMND_GET_STARGET_PORT_NAME 123 /* gtpn */
+#define CMND_GET_RPORT_LOSS_TMO 141 /* gplt */
+#define CMND_SET_RPORT_LOSS_TMO 142 /* splt */
+#define CMND_GET_INITIAL_SHOST_ATTRIB 161 /* giha */
+#define CMND_GET_INITIAL_STARGET_ATTRIB 162 /* gita */
+#define CMND_GET_INITIAL_RPORT_ATTRIB 163 /* gipa */
+#define CMND_GET_FUNCTION_TEMPLATE 181 /* gftp */
+#endif
+
+/* ----------------------------------------------------------------------
+ Definition of Ring Structures
+ ---------------------------------------------------------------------- */
+
+#define DEFAULT_CAN_QUEUE 256
+#define VSCSI_MAX_COMMAND_SIZE 16
+#define SG_TABLESIZE 32
+
+#define SCSIIF_REQ_OKAY 0
+#define SCSIIF_BTFRING_BUSY 1
+
+/* Definition of
+ * union vscsiif_ftb_sring_entry,
+ * struct vscsiif_ftb_sring,
+ * struct vscsiif_ftb_front_ring,
+ * struct vscsiif_ftb_back_ring,
+ * vscsiif_ftb_sring_t,
+ * vscsiif_ftb_front_ring_t,
+ * vscsiif_ftb_back_ring_t
+*/
+struct vscsiif_ftb_request {
+ uint32_t rqid;
+ uint32_t cmnd;
+ union {
+ /* SCSI */
+ struct scsiif_ftb_request {
+ uint8_t cmnd[VSCSI_MAX_COMMAND_SIZE];
+ uint8_t cmd_len;
+ uint32_t id, lun, channel;
+ uint16_t sc_data_direction;
+ uint16_t use_sg;
+ uint16_t request_bufflen;
+ int32_t timeout_per_command;
+ struct scsiif_request_segment {
+ grant_ref_t gref;
+ uint32_t offset;
+ uint32_t length;
+ } seg[SG_TABLESIZE];
+ uint32_t padding;
+ } scsi;
+#ifdef CONFIG_XEN_FC
+ /* Get_sTarget_Port_Id */
+ /* Get_sTarget_Node_Name */
+ /* Get_sTarget_Port_Name */
+ struct {
+ u32 channel;
+ u32 id;
+ } gtpi, gtnn, gtpn;
+
+ /* Get_rPort_Loss_Tmo */
+ struct {
+ u64 node_name;
+ u64 port_name;
+ u32 port_id;
+ u32 roles;
+ } gplt;
+
+ /* Set_rPort_Loss_Tmo */
+ struct {
+ u64 node_name;
+ u64 port_name;
+ u32 port_id;
+ u32 roles;
+ u32 timeout;
+ u32 padding;
+ } splt;
+#endif
+ } u;
+};
+
+struct vscsiif_ftb_response {
+ uint16_t status;
+ union {
+ struct scsiif_ftb_response {
+ } scsi;
+ } u;
+};
+
+DEFINE_RING_TYPES(vscsiif_ftb, struct vscsiif_ftb_request, struct vscsiif_ftb_response);
+
+
+#define SCSI_SENSE_BUFFERSIZE 96
+
+/* Definition of
+ * union vscsiif_btf_sring_entry,
+ * struct vscsiif_btf_sring,
+ * struct vscsiif_btf_front_ring,
+ * struct vscsiif_btf_back_ring,
+ * vscsiif_btf_sring_t,
+ * vscsiif_btf_front_ring_t,
+ * vscsiif_btf_back_ring_t
+*/
+struct vscsiif_btf_request {
+ uint32_t rqid;
+ int32_t rslt;
+ union {
+ /* SCSI */
+ struct scsiif_response {
+ uint32_t sense_len;
+ uint8_t sense_buffer[SCSI_SENSE_BUFFERSIZE];
+ } scsi;
+
+#ifdef CONFIG_XEN_FC
+ /* Get_Host_Port_Id */
+ struct {
+ u32 port_id;
+ } ghpi;
+
+ /* Get_Host_Port_Type */
+ struct {
+ enum fc_port_type port_type;
+ } ghpt;
+
+ /* Get_Host_Port_State */
+ struct {
+ enum fc_port_state port_state;
+ } ghps;
+
+ /* Get_Host_Active_Fc4s */
+ struct {
+ u8 active_fc4s[FC_FC4_LIST_SIZE];
+ } ghaf;
+
+ /* Get_Host_SPeed */
+ struct {
+ u32 speed;
+ } ghsp;
+
+ /* Get_Host_Fabric_Name */
+ struct {
+ u64 fabric_name;
+ } ghfn;
+
+ /* Get_Host_STats */
+ struct {
+ struct fc_host_statistics stats;
+ } ghst;
+
+ /* Get_sTarget_Port_Id */
+ struct {
+ u32 port_id;
+ } gtpi;
+
+ /* Get_sTarget_Node_Name */
+ struct {
+ u64 node_name;
+ } gtnn;
+
+ /* Get_sTarget_Port_Name */
+ struct {
+ u64 port_name;
+ } gtpn;
+
+ /* Get_rPort_Loss_Tmo */
+ struct {
+ u32 timeout;
+ } gplt;
+
+ /* Set_rPort_Loss_Tmo */
+ struct {
+ u32 timeout;
+ } splt;
+#endif
+ } u;
+};
+
+struct vscsiif_btf_response {
+ union {
+ struct scsiif_btf_response {
+
+ } scsi;
+ } u;
+};
+
+DEFINE_RING_TYPES(vscsiif_btf, struct vscsiif_btf_request, struct vscsiif_btf_response);
+
+#endif
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-10-30 10:39 ` [PATCH 0/6] " Jun Kamada
@ 2007-10-30 10:56 ` Keir Fraser
2007-10-31 8:37 ` Jun Kamada
2007-11-01 12:14 ` Stephen C. Tweedie
1 sibling, 1 reply; 33+ messages in thread
From: Keir Fraser @ 2007-10-30 10:56 UTC (permalink / raw)
To: Jun Kamada; +Cc: xen-devel
Vscsiif.h still needs clean up:
1. You cannot have Linux-specific stuff in that header file. It's supposed
to be generic. Get rid of references to CONFIG_XEN_FC.
2. You cannot pollute the global namespace with unqualified names. All your
names, macros, etc should have a vscsiif_ or VSCSIIF_ prefix. Names like
DEFAULT_CAN_QUEUE and SG_TABLESIZE pollute the namespace and it's not
immediately obvious which header they come from (which it would be if they
were prefixed).
3. Do you really mean for vscsiif_btf_response to be empty? And neither
response structure has an identifier to match the request it responds to.
Can requests not be handled out of order by your drivers? That would seem
very odd.
Also CONFIG_XEN_FC is ifdef'ed all over scsifront and scsiback. You'll have
to find some way to clean that up, perhaps by providing null stub
implementations of fc functions in a header file if !CONFIG_XEN_FC.
FIXME comments in the connection setup code, accompanied by hard-coded
constants, don't bode well. Is the connection setup protocol fully baked
yet?
All this, coupled with the fact that you can only export whole HBAs, which
doesn't seem likely to be a very popular usage scenario, makes me think this
driver should wait until after 3.2.0.
--Keir
On 30/10/07 10:39, "Jun Kamada" <kama@jp.fujitsu.com> wrote:
> Keir-san,
>
> I have finished the modification of the driver by option i.).
> The pvSCSI driver can work on heterogeneous (x86_32 and x86_64)
> environment.
>
> I will attach total six patches on following mail.
>
> Best regards,
>
>
> On Thu, 25 Oct 2007 10:59:31 +0900
> Jun Kamada <kama@jp.fujitsu.com> wrote:
>
>> Keir-san,
>>
>> On Wed, 24 Oct 2007 08:42:38 +0100
>> Keir Fraser <Keir.Fraser@cl.cam.ac.uk> wrote:
>>> On 24/10/07 07:22, "Jun Kamada" <kama@jp.fujitsu.com> wrote:
>>>
>>>>> Anyway, the right answer is to ensure that your structures compile the
>>>>> same
>>>>> whether compiled with 32-bit or 64-bit gcc. Check the structure sizes,
>>>>> fields sizes and field offsets.
>>>>
>>>> You showed me two options in previous email; i.) all the shared-memory
>>>> structures defined in vscsiif.h compile identically for 32-bit and
>>>> 64-bit mode, ii.) to detect the frontend's 'bitness' in scsiback and
>>>> optionally do 32-to-64 or 64-to-32 conversion.
>>>>
>>>> I consider that current VBD implementation takes option ii.), however
>>>> you recommended me to take option i.) for pvSCSI driver.
>>>> Is my understanding right?
>>>
>>> Yes. It was an accident we ended up with structures compiling differently on
>>> 32- vs 64-bit. By the time we discovered it was an issue, we couldn't break
>>> backward compatibility.
>>
>> I understood. I'll try to modify the pvSCSI driver by option i.).
>>
>> Best regards,
>>
>> -----
>> Jun Kamada
>>
>>
>>
>> _______________________________________________
>> Xen-devel mailing list
>> Xen-devel@lists.xensource.com
>> http://lists.xensource.com/xen-devel
>
> -----
> Jun Kamada
>
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-10-30 10:56 ` Keir Fraser
@ 2007-10-31 8:37 ` Jun Kamada
2007-10-31 9:10 ` Keir Fraser
0 siblings, 1 reply; 33+ messages in thread
From: Jun Kamada @ 2007-10-31 8:37 UTC (permalink / raw)
To: Keir Fraser; +Cc: kama, xen-devel
Hi Keir-san,
Thank you for your comments.
On Tue, 30 Oct 2007 10:56:57 +0000
Keir Fraser <Keir.Fraser@cl.cam.ac.uk> wrote:
> Vscsiif.h still needs clean up:
> 1. You cannot have Linux-specific stuff in that header file. It's supposed
> to be generic.
I understood. I would like to remove Linux-specific definitions, such
like below.
#include <scsi/scsi_transport.h>
enum fc_port_state
> 2. You cannot pollute the global namespace with unqualified names. All your
> names, macros, etc should have a vscsiif_ or VSCSIIF_ prefix. Names like
> DEFAULT_CAN_QUEUE and SG_TABLESIZE pollute the namespace and it's not
> immediately obvious which header they come from (which it would be if they
> were prefixed).
I would like to add the prefix to all the definitions.
> 3. Do you really mean for vscsiif_btf_response to be empty? And neither
> response structure has an identifier to match the request it responds to.
> Can requests not be handled out of order by your drivers? That would seem
> very odd.
The pvSCSI driver uses two rings for frontend-to-backend (ftb) and
backend-to-frontend (btf) communication. The reason why the
architecture is taken is as follows.
- The ftb_request packet was relatively big, so we could not allocate
enough entries on the ring. It caused a performance problem.
- By dividing into the two rings ("ftb" ring and "btf" ring), and using
original queueing mechanism on both frontend and backend, the entries
on the ring is immediately freed after queued. It contributes a good
performance.
Therefore, the ftb_response and btf_response carries no information.
It is only used as a trigger of freeing the entry on the ring.
We also would like to discuss about design of the ring architecture
described above. Any comment is welcome.
> Also CONFIG_XEN_FC is ifdef'ed all over scsifront and scsiback. You'll have
> to find some way to clean that up, perhaps by providing null stub
> implementations of fc functions in a header file if !CONFIG_XEN_FC.
I think that one of the way to reduce CONFIG_XEN_FC is to ifdef'ing
intialization of FC transport functionality. (However, object modules
still include FC modules.) How do you think about this modification?
Could you tell me more detail about your advice?
Please note why the CONFIG_XEN_FC is needed are,
- Old Linux kernel has different definition of
"struct fc_function_template".
- In order to support the old Linux kernel on HVM guest domain, simple
way is disabling FC functionality.
> FIXME comments in the connection setup code, accompanied by hard-coded
> constants, don't bode well. Is the connection setup protocol fully baked
> yet?
FIXME comment indicates tunable point of the parameter for performance
and so on. I understood the word "FIXME' was not appropriate. I will
remove the word.
> All this, coupled with the fact that you can only export whole HBAs, which
> doesn't seem likely to be a very popular usage scenario, makes me think this
> driver should wait until after 3.2.0.
We consider that SCSI support on guest domain is mandatory for bussiness
use. Using a NPIV technology on host domain, each guest domain can have
own virtual HBA. We have already evaluated on our environment the
conbination of NPIV and pvSCSI work well.
On the other hand, we undestand the usefullness of LUN assignment to
guest domain. We would like to develop it on next step in our current
plan.
Best regards,
-----
Jun Kamada
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-10-31 8:37 ` Jun Kamada
@ 2007-10-31 9:10 ` Keir Fraser
2007-10-31 10:56 ` Jun Kamada
0 siblings, 1 reply; 33+ messages in thread
From: Keir Fraser @ 2007-10-31 9:10 UTC (permalink / raw)
To: Jun Kamada; +Cc: xen-devel
On 31/10/07 08:37, "Jun Kamada" <kama@jp.fujitsu.com> wrote:
>> All this, coupled with the fact that you can only export whole HBAs, which
>> doesn't seem likely to be a very popular usage scenario, makes me think this
>> driver should wait until after 3.2.0.
>
> We consider that SCSI support on guest domain is mandatory for bussiness
> use. Using a NPIV technology on host domain, each guest domain can have
> own virtual HBA. We have already evaluated on our environment the
> conbination of NPIV and pvSCSI work well.
> On the other hand, we undestand the usefullness of LUN assignment to
> guest domain. We would like to develop it on next step in our current
> plan.
Okay, well re-spin the patches and I'll take another look.
-- Keir
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-10-31 9:10 ` Keir Fraser
@ 2007-10-31 10:56 ` Jun Kamada
2007-10-31 11:15 ` Keir Fraser
0 siblings, 1 reply; 33+ messages in thread
From: Jun Kamada @ 2007-10-31 10:56 UTC (permalink / raw)
To: Keir Fraser; +Cc: kama, xen-devel
Keir-san,
On Wed, 31 Oct 2007 09:10:34 +0000
Keir Fraser <Keir.Fraser@cl.cam.ac.uk> wrote:
> On 31/10/07 08:37, "Jun Kamada" <kama@jp.fujitsu.com> wrote:
>
> >> All this, coupled with the fact that you can only export whole HBAs, which
> >> doesn't seem likely to be a very popular usage scenario, makes me think this
> >> driver should wait until after 3.2.0.
> >
> > We consider that SCSI support on guest domain is mandatory for bussiness
> > use. Using a NPIV technology on host domain, each guest domain can have
> > own virtual HBA. We have already evaluated on our environment the
> > conbination of NPIV and pvSCSI work well.
> > On the other hand, we undestand the usefullness of LUN assignment to
> > guest domain. We would like to develop it on next step in our current
> > plan.
>
> Okay, well re-spin the patches and I'll take another look.
Can I ask one question in order to avoid my misunderstanding?
Do you mean that the pvSCSI driver is never commited until it supports
LUN assignment to geust domain, or anything else?
Best regards,
-----
Jun Kamada
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-10-31 10:56 ` Jun Kamada
@ 2007-10-31 11:15 ` Keir Fraser
0 siblings, 0 replies; 33+ messages in thread
From: Keir Fraser @ 2007-10-31 11:15 UTC (permalink / raw)
To: Jun Kamada; +Cc: xen-devel
On 31/10/07 10:56, "Jun Kamada" <kama@jp.fujitsu.com> wrote:
>> Okay, well re-spin the patches and I'll take another look.
>
> Can I ask one question in order to avoid my misunderstanding?
>
> Do you mean that the pvSCSI driver is never commited until it supports
> LUN assignment to geust domain, or anything else?
The virtual HBA usage scenario sounds useful.
-- Keir
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-10-30 10:39 ` [PATCH 0/6] " Jun Kamada
2007-10-30 10:56 ` Keir Fraser
@ 2007-11-01 12:14 ` Stephen C. Tweedie
2007-11-02 0:23 ` James Harper
` (2 more replies)
1 sibling, 3 replies; 33+ messages in thread
From: Stephen C. Tweedie @ 2007-11-01 12:14 UTC (permalink / raw)
To: Jun Kamada; +Cc: Stephen Tweedie, xen-devel@lists.xensource.com
Hi,
On Tue, 2007-10-30 at 19:39 +0900, Jun Kamada wrote:
Is this using the same syntax for HBA reservation that we used to have,
ie. simply enumerated using the scsi host number on the dom0?
If so, that is rather fragile. The scsi host number can change from
kernel to kernel depending on HBA driver probe order and PCI bus
enumeration order. It changes when hardware is rearranged. And how do
we deal with migrate, when we'll need to select a completely different
HBA on a different host?
Selecting the HBA by scsi host number is good enough for a demonstration
that the code works, but I don't think it's going to be robust enough
for production deployment.
Also, has there been any progress towards exposing individual LUNs to
the guest rather than a whole HBA?
Cheers,
Stephen
^ permalink raw reply [flat|nested] 33+ messages in thread
* RE: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-11-01 12:14 ` Stephen C. Tweedie
@ 2007-11-02 0:23 ` James Harper
2007-11-05 3:30 ` Jun Kamada
2007-11-05 2:05 ` Jun Kamada
2007-11-05 3:34 ` Aaron Dailey
2 siblings, 1 reply; 33+ messages in thread
From: James Harper @ 2007-11-02 0:23 UTC (permalink / raw)
To: Stephen C. Tweedie, Jun Kamada; +Cc: xen-devel
> Hi,
>
> On Tue, 2007-10-30 at 19:39 +0900, Jun Kamada wrote:
>
> Is this using the same syntax for HBA reservation that we used to
have,
> ie. simply enumerated using the scsi host number on the dom0?
>
> If so, that is rather fragile. The scsi host number can change from
> kernel to kernel depending on HBA driver probe order and PCI bus
> enumeration order. It changes when hardware is rearranged. And how
do
> we deal with migrate, when we'll need to select a completely different
> HBA on a different host?
>
> Selecting the HBA by scsi host number is good enough for a
demonstration
> that the code works, but I don't think it's going to be robust enough
> for production deployment.
>
> Also, has there been any progress towards exposing individual LUNs to
> the guest rather than a whole HBA?
People keep saying individual LUN... do they actually mean SCSI Target
devices? Splitting up devices on the same HBA should be reasonably
simple, but due to the way the scsi protocol works (AFAIK), splitting up
LUN's on a single SCSI device could be a bit trickier...
Or maybe LUN doesn't mean what I think it means in this case... my
understanding is:
HBA = Host Bus Adapter (eg a PCI SCSI adapter)
SCSI Target Device = one of the physical devices that sits on the SCSI
bus (eg a tape drive or a disk drive)
LUN (Logical Unit Number) = a sub unit of the SCSI Target Device, eg a
single disk drive in a RAID array, a tape device in an multi tape drive
autoloader, a CD ROM in a CDROM tower.
...
James
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-11-01 12:14 ` Stephen C. Tweedie
2007-11-02 0:23 ` James Harper
@ 2007-11-05 2:05 ` Jun Kamada
2007-11-08 21:33 ` Stephen C. Tweedie
2007-11-05 3:34 ` Aaron Dailey
2 siblings, 1 reply; 33+ messages in thread
From: Jun Kamada @ 2007-11-05 2:05 UTC (permalink / raw)
To: Stephen C. Tweedie; +Cc: kama, xen-devel@lists.xensource.com
Hi Stephen-san,
On Thu, 01 Nov 2007 12:14:41 +0000
"Stephen C. Tweedie" <sct@redhat.com> wrote:
> On Tue, 2007-10-30 at 19:39 +0900, Jun Kamada wrote:
>
> Is this using the same syntax for HBA reservation that we used to have,
> ie. simply enumerated using the scsi host number on the dom0?
Yes.
> If so, that is rather fragile. The scsi host number can change from
> kernel to kernel depending on HBA driver probe order and PCI bus
> enumeration order. It changes when hardware is rearranged. And how do
> we deal with migrate, when we'll need to select a completely different
> HBA on a different host?
>
> Selecting the HBA by scsi host number is good enough for a demonstration
> that the code works, but I don't think it's going to be robust enough
> for production deployment.
We also recognize that more sophisticated interface is needed. WWPN can
be used for FC-SCSI, however pure SCSI does not have any unique ID.
Do you have any idea?
> Also, has there been any progress towards exposing individual LUNs to
> the guest rather than a whole HBA?
>
> Cheers,
> Stephen
>
Jun Kamada
Linux Technology Development Div.
Server Systems Unit
Fujitsu Ltd.
kama@jp.fujitsu.com
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-11-02 0:23 ` James Harper
@ 2007-11-05 3:30 ` Jun Kamada
0 siblings, 0 replies; 33+ messages in thread
From: Jun Kamada @ 2007-11-05 3:30 UTC (permalink / raw)
To: James Harper; +Cc: kama, Stephen C. Tweedie, xen-devel
Hi James-san,
On Fri, 2 Nov 2007 11:23:50 +1100
"James Harper" <james.harper@bendigoit.com.au> wrote:
> > Hi,
> >
> > On Tue, 2007-10-30 at 19:39 +0900, Jun Kamada wrote:
> >
> > Is this using the same syntax for HBA reservation that we used to
> have,
> > ie. simply enumerated using the scsi host number on the dom0?
> >
> > If so, that is rather fragile. The scsi host number can change from
> > kernel to kernel depending on HBA driver probe order and PCI bus
> > enumeration order. It changes when hardware is rearranged. And how
> do
> > we deal with migrate, when we'll need to select a completely different
> > HBA on a different host?
> >
> > Selecting the HBA by scsi host number is good enough for a
> demonstration
> > that the code works, but I don't think it's going to be robust enough
> > for production deployment.
> >
> > Also, has there been any progress towards exposing individual LUNs to
> > the guest rather than a whole HBA?
>
> People keep saying individual LUN... do they actually mean SCSI Target
> devices? Splitting up devices on the same HBA should be reasonably
> simple, but due to the way the scsi protocol works (AFAIK), splitting up
> LUN's on a single SCSI device could be a bit trickier...
The reason why we have to support SCSI on guest domain is that we would
like to use commercial appilications.
My understanding is as follows.
1.) There is a vender specific area in SCSI command frame.
2.) There is a case that some data in the area depends on SCSI-ID, and
some storage management software uses tha data. And sometimes the
software requires one-to-one bindings to HBA. (This fuct is not good
for standardization point of view.)
Possible solution may be
a.) Assign a physical HBA for the guest domain the software, described
in 2.), is running. And also multiple guest domains can share one
physical HBA by using NPIV technology in this case.
b.) Assign LUNs for the other guests.
> Or maybe LUN doesn't mean what I think it means in this case... my
> understanding is:
>
> HBA = Host Bus Adapter (eg a PCI SCSI adapter)
> SCSI Target Device = one of the physical devices that sits on the SCSI
> bus (eg a tape drive or a disk drive)
> LUN (Logical Unit Number) = a sub unit of the SCSI Target Device, eg a
> single disk drive in a RAID array, a tape device in an multi tape drive
> autoloader, a CD ROM in a CDROM tower.
My understanding is same as yours.
Best regards,
-----
Jun Kamada
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-11-01 12:14 ` Stephen C. Tweedie
2007-11-02 0:23 ` James Harper
2007-11-05 2:05 ` Jun Kamada
@ 2007-11-05 3:34 ` Aaron Dailey
2 siblings, 0 replies; 33+ messages in thread
From: Aaron Dailey @ 2007-11-05 3:34 UTC (permalink / raw)
To: Stephen C. Tweedie; +Cc: Jun Kamada, xen-devel@lists.xensource.com
Stephen C. Tweedie wrote:
> Hi,
>
> On Tue, 2007-10-30 at 19:39 +0900, Jun Kamada wrote:
>
> Is this using the same syntax for HBA reservation that we used to have,
> ie. simply enumerated using the scsi host number on the dom0?
>
> If so, that is rather fragile. The scsi host number can change from
> kernel to kernel depending on HBA driver probe order and PCI bus
> enumeration order. It changes when hardware is rearranged. And how do
> we deal with migrate, when we'll need to select a completely different
> HBA on a different host?
>
> Selecting the HBA by scsi host number is good enough for a demonstration
> that the code works, but I don't think it's going to be robust enough
> for production deployment.
>
> Also, has there been any progress towards exposing individual LUNs to
> the guest rather than a whole HBA?
>
NPIV can help here for FibreChannel devices. You can create a virtual
NPIV adapter, and export exactly the LUNs/devices you want to that adapter.
It's a different approach then exporting LUNs, but similar result.
> Cheers,
> Stephen
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-11-05 2:05 ` Jun Kamada
@ 2007-11-08 21:33 ` Stephen C. Tweedie
2007-11-12 8:27 ` Jun Kamada
0 siblings, 1 reply; 33+ messages in thread
From: Stephen C. Tweedie @ 2007-11-08 21:33 UTC (permalink / raw)
To: Jun Kamada; +Cc: Stephen Tweedie, xen-devel@lists.xensource.com
Hi,
On Mon, 2007-11-05 at 11:05 +0900, Jun Kamada wrote:
> We also recognize that more sophisticated interface is needed. WWPN can
> be used for FC-SCSI, however pure SCSI does not have any unique ID.
> Do you have any idea?
Well... Linux does try to use address-by-content to some extent, but
that's going to be fragile here, as well. It's complicated even more by
the difficulty of having potential multipath in the mix.
libblkid has some helpful functions for certain cases, but that doesn't
help at all for the bootstrap cases when you're dealing with completely
unformatted disks.
The libvirt folks have been wrestling with some of the same questions
recently, libvirt-devel may have some useful discussion.
--Stephen
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 0/6] pvSCSI (SCSI pass through) driver
2007-11-08 21:33 ` Stephen C. Tweedie
@ 2007-11-12 8:27 ` Jun Kamada
0 siblings, 0 replies; 33+ messages in thread
From: Jun Kamada @ 2007-11-12 8:27 UTC (permalink / raw)
To: Stephen C. Tweedie; +Cc: kama, xen-devel@lists.xensource.com
Hi Stephen-san,
Thank you for your helpful information. I will access the information.
Thanks,
On Thu, 08 Nov 2007 21:33:50 +0000
"Stephen C. Tweedie" <sct@redhat.com> wrote:
> Hi,
>
> On Mon, 2007-11-05 at 11:05 +0900, Jun Kamada wrote:
>
> > We also recognize that more sophisticated interface is needed. WWPN can
> > be used for FC-SCSI, however pure SCSI does not have any unique ID.
> > Do you have any idea?
>
> Well... Linux does try to use address-by-content to some extent, but
> that's going to be fragile here, as well. It's complicated even more by
> the difficulty of having potential multipath in the mix.
>
> libblkid has some helpful functions for certain cases, but that doesn't
> help at all for the bootstrap cases when you're dealing with completely
> unformatted disks.
>
> The libvirt folks have been wrestling with some of the same questions
> recently, libvirt-devel may have some useful discussion.
>
> --Stephen
>
>
Jun Kamada
Linux Technology Development Div.
Server Systems Unit
Fujitsu Ltd.
kama@jp.fujitsu.com
^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2007-11-12 8:27 UTC | newest]
Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-19 5:15 [PATCH 0/5] pvSCSI (SCSI pass through) driver Jun Kamada
2007-10-19 8:38 ` Keir Fraser
2007-10-19 10:20 ` Ian Pratt
2007-10-22 2:39 ` Jun Kamada
2007-10-22 0:07 ` James Harper
2007-10-23 7:41 ` Jun Kamada
2007-10-22 8:58 ` Keir Fraser
2007-10-23 7:09 ` Jun Kamada
2007-10-23 8:50 ` Keir Fraser
2007-10-23 11:35 ` Jun Kamada
2007-10-23 12:39 ` Keir Fraser
2007-10-24 6:22 ` Jun Kamada
2007-10-24 7:42 ` Keir Fraser
2007-10-25 1:59 ` Jun Kamada
2007-10-30 10:39 ` [PATCH 0/6] " Jun Kamada
2007-10-30 10:56 ` Keir Fraser
2007-10-31 8:37 ` Jun Kamada
2007-10-31 9:10 ` Keir Fraser
2007-10-31 10:56 ` Jun Kamada
2007-10-31 11:15 ` Keir Fraser
2007-11-01 12:14 ` Stephen C. Tweedie
2007-11-02 0:23 ` James Harper
2007-11-05 3:30 ` Jun Kamada
2007-11-05 2:05 ` Jun Kamada
2007-11-08 21:33 ` Stephen C. Tweedie
2007-11-12 8:27 ` Jun Kamada
2007-11-05 3:34 ` Aaron Dailey
2007-10-30 10:39 ` [PATCH 1/6] " Jun Kamada
2007-10-30 10:39 ` [PATCH 2/6] " Jun Kamada
2007-10-30 10:39 ` [PATCH 3/6] " Jun Kamada
2007-10-30 10:39 ` [PATCH 4/6] " Jun Kamada
2007-10-30 10:39 ` [PATCH 5/6] " Jun Kamada
2007-10-30 10:39 ` [PATCH 6/6] " Jun Kamada
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.