aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2008-02-19 13:49:40 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-07 13:15:38 -0400
commit45e6cdf41437c72ed79cee64dc69e7f740511e50 (patch)
tree80814e8e3e58ddfe9e27e9674f256a67cdef0fb5
parent7e23ea488488400127a2da19c0d89f1723117504 (diff)
[SCSI] libsas: Provide a transport-level facility to request SAS addrs
Provide a facility to use the request_firmware() interface to get a SAS address from userspace. This can be used by SAS LLDDs that cannot obtain the address from the host adapter. Signed-off-by: Darrick J. Wong <djwong@us.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c41
-rw-r--r--include/scsi/libsas.h2
2 files changed, 43 insertions, 0 deletions
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 1f8241563c6c..601ec5b6a7f6 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -24,6 +24,8 @@
24 */ 24 */
25 25
26#include <linux/kthread.h> 26#include <linux/kthread.h>
27#include <linux/firmware.h>
28#include <linux/ctype.h>
27 29
28#include "sas_internal.h" 30#include "sas_internal.h"
29 31
@@ -1064,6 +1066,45 @@ void sas_target_destroy(struct scsi_target *starget)
1064 return; 1066 return;
1065} 1067}
1066 1068
1069static void sas_parse_addr(u8 *sas_addr, const char *p)
1070{
1071 int i;
1072 for (i = 0; i < SAS_ADDR_SIZE; i++) {
1073 u8 h, l;
1074 if (!*p)
1075 break;
1076 h = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10;
1077 p++;
1078 l = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10;
1079 p++;
1080 sas_addr[i] = (h<<4) | l;
1081 }
1082}
1083
1084#define SAS_STRING_ADDR_SIZE 16
1085
1086int sas_request_addr(struct Scsi_Host *shost, u8 *addr)
1087{
1088 int res;
1089 const struct firmware *fw;
1090
1091 res = request_firmware(&fw, "sas_addr", &shost->shost_gendev);
1092 if (res)
1093 return res;
1094
1095 if (fw->size < SAS_STRING_ADDR_SIZE) {
1096 res = -ENODEV;
1097 goto out;
1098 }
1099
1100 sas_parse_addr(addr, fw->data);
1101
1102out:
1103 release_firmware(fw);
1104 return res;
1105}
1106EXPORT_SYMBOL_GPL(sas_request_addr);
1107
1067EXPORT_SYMBOL_GPL(sas_queuecommand); 1108EXPORT_SYMBOL_GPL(sas_queuecommand);
1068EXPORT_SYMBOL_GPL(sas_target_alloc); 1109EXPORT_SYMBOL_GPL(sas_target_alloc);
1069EXPORT_SYMBOL_GPL(sas_slave_configure); 1110EXPORT_SYMBOL_GPL(sas_slave_configure);
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 39e1cac24bb7..98724ba65a79 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -677,4 +677,6 @@ extern void sas_ssp_task_response(struct device *dev, struct sas_task *task,
677 struct ssp_response_iu *iu); 677 struct ssp_response_iu *iu);
678struct sas_phy *sas_find_local_phy(struct domain_device *dev); 678struct sas_phy *sas_find_local_phy(struct domain_device *dev);
679 679
680int sas_request_addr(struct Scsi_Host *shost, u8 *addr);
681
680#endif /* _SASLIB_H_ */ 682#endif /* _SASLIB_H_ */