All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.