diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2007-07-08 23:52:08 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-07-18 12:18:20 -0400 |
commit | ba1fc175cc6c0af7e78241e50160344f0f198282 (patch) | |
tree | 019c21e5c4658c50b08e28d2077b37242a1d22db | |
parent | 7aa68e80bd481faae1234bc2a7e4bcc9348f98b4 (diff) |
[SCSI] libsas: add SAS management protocol handler
This patch adds support for SAS Management Protocol (SMP) passthrough
support via bsg. aic94xx can use this.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/libsas/sas_expander.c | 48 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_init.c | 1 | ||||
-rw-r--r-- | include/scsi/libsas.h | 2 |
3 files changed, 51 insertions, 0 deletions
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 969fd3eb494a..a81195354b9c 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -23,6 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/scatterlist.h> | 25 | #include <linux/scatterlist.h> |
26 | #include <linux/blkdev.h> | ||
26 | 27 | ||
27 | #include "sas_internal.h" | 28 | #include "sas_internal.h" |
28 | 29 | ||
@@ -1972,3 +1973,50 @@ out: | |||
1972 | return res; | 1973 | return res; |
1973 | } | 1974 | } |
1974 | #endif | 1975 | #endif |
1976 | |||
1977 | int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | ||
1978 | struct request *req) | ||
1979 | { | ||
1980 | struct domain_device *dev; | ||
1981 | int ret, type = rphy->identify.device_type; | ||
1982 | struct request *rsp = req->next_rq; | ||
1983 | |||
1984 | if (!rsp) { | ||
1985 | printk("%s: space for a smp response is missing\n", | ||
1986 | __FUNCTION__); | ||
1987 | return -EINVAL; | ||
1988 | } | ||
1989 | |||
1990 | /* seems aic94xx doesn't support */ | ||
1991 | if (!rphy) { | ||
1992 | printk("%s: can we send a smp request to a host?\n", | ||
1993 | __FUNCTION__); | ||
1994 | return -EINVAL; | ||
1995 | } | ||
1996 | |||
1997 | if (type != SAS_EDGE_EXPANDER_DEVICE && | ||
1998 | type != SAS_FANOUT_EXPANDER_DEVICE) { | ||
1999 | printk("%s: can we send a smp request to a device?\n", | ||
2000 | __FUNCTION__); | ||
2001 | return -EINVAL; | ||
2002 | } | ||
2003 | |||
2004 | dev = sas_find_dev_by_rphy(rphy); | ||
2005 | if (!dev) { | ||
2006 | printk("%s: fail to find a domain_device?\n", __FUNCTION__); | ||
2007 | return -EINVAL; | ||
2008 | } | ||
2009 | |||
2010 | /* do we need to support multiple segments? */ | ||
2011 | if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { | ||
2012 | printk("%s: multiple segments req %u %u, rsp %u %u\n", | ||
2013 | __FUNCTION__, req->bio->bi_vcnt, req->data_len, | ||
2014 | rsp->bio->bi_vcnt, rsp->data_len); | ||
2015 | return -EINVAL; | ||
2016 | } | ||
2017 | |||
2018 | ret = smp_execute_task(dev, bio_data(req->bio), req->data_len, | ||
2019 | bio_data(rsp->bio), rsp->data_len); | ||
2020 | |||
2021 | return ret; | ||
2022 | } | ||
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 965698c8b7bf..98360272f40a 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c | |||
@@ -259,6 +259,7 @@ static struct sas_function_template sft = { | |||
259 | .phy_reset = sas_phy_reset, | 259 | .phy_reset = sas_phy_reset, |
260 | .set_phy_speed = sas_set_phy_speed, | 260 | .set_phy_speed = sas_set_phy_speed, |
261 | .get_linkerrors = sas_get_linkerrors, | 261 | .get_linkerrors = sas_get_linkerrors, |
262 | .smp_handler = sas_smp_handler, | ||
262 | }; | 263 | }; |
263 | 264 | ||
264 | struct scsi_transport_template * | 265 | struct scsi_transport_template * |
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 9275a46bf2e3..df36461fe881 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h | |||
@@ -674,4 +674,6 @@ extern void sas_target_destroy(struct scsi_target *); | |||
674 | extern int sas_slave_alloc(struct scsi_device *); | 674 | extern int sas_slave_alloc(struct scsi_device *); |
675 | extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg); | 675 | extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg); |
676 | 676 | ||
677 | extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | ||
678 | struct request *req); | ||
677 | #endif /* _SASLIB_H_ */ | 679 | #endif /* _SASLIB_H_ */ |