xref: /linux/drivers/scsi/bnx2i/bnx2i_sysfs.c (revision 0a386beb7ebdcc475a57327d4ab1eb6fa6a7c678)
1f39a7757SVikas Chaudhary /* bnx2i_sysfs.c: QLogic NetXtreme II iSCSI driver.
2cf4e6363SMichael Chan  *
30b3bf387SEddie Wai  * Copyright (c) 2004 - 2013 Broadcom Corporation
4f39a7757SVikas Chaudhary  * Copyright (c) 2014, QLogic Corporation
5cf4e6363SMichael Chan  *
6cf4e6363SMichael Chan  * This program is free software; you can redistribute it and/or modify
7cf4e6363SMichael Chan  * it under the terms of the GNU General Public License as published by
8cf4e6363SMichael Chan  * the Free Software Foundation.
9cf4e6363SMichael Chan  *
10cf4e6363SMichael Chan  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
11f39a7757SVikas Chaudhary  * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com)
12f39a7757SVikas Chaudhary  * Maintained by: QLogic-Storage-Upstream@qlogic.com
13cf4e6363SMichael Chan  */
14cf4e6363SMichael Chan 
15cf4e6363SMichael Chan #include "bnx2i.h"
16cf4e6363SMichael Chan 
17cf4e6363SMichael Chan /**
18cf4e6363SMichael Chan  * bnx2i_dev_to_hba - maps dev pointer to adapter struct
19cf4e6363SMichael Chan  * @dev:	device pointer
20cf4e6363SMichael Chan  *
21cf4e6363SMichael Chan  * Map device to hba structure
22cf4e6363SMichael Chan  */
23cf4e6363SMichael Chan static inline struct bnx2i_hba *bnx2i_dev_to_hba(struct device *dev)
24cf4e6363SMichael Chan {
25cf4e6363SMichael Chan 	struct Scsi_Host *shost = class_to_shost(dev);
26cf4e6363SMichael Chan 	return iscsi_host_priv(shost);
27cf4e6363SMichael Chan }
28cf4e6363SMichael Chan 
29cf4e6363SMichael Chan 
30cf4e6363SMichael Chan /**
31cf4e6363SMichael Chan  * bnx2i_show_sq_info - return(s currently configured send queue (SQ) size
32cf4e6363SMichael Chan  * @dev:	device pointer
332ad6e0c3SLee Jones  * @attr:	device attribute (unused)
34cf4e6363SMichael Chan  * @buf:	buffer to return current SQ size parameter
35cf4e6363SMichael Chan  *
36cf4e6363SMichael Chan  * Returns current SQ size parameter, this paramater determines the number
37cf4e6363SMichael Chan  * outstanding iSCSI commands supported on a connection
38cf4e6363SMichael Chan  */
39cf4e6363SMichael Chan static ssize_t bnx2i_show_sq_info(struct device *dev,
40cf4e6363SMichael Chan 				  struct device_attribute *attr, char *buf)
41cf4e6363SMichael Chan {
42cf4e6363SMichael Chan 	struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev);
43cf4e6363SMichael Chan 
44cf4e6363SMichael Chan 	return sprintf(buf, "0x%x\n", hba->max_sqes);
45cf4e6363SMichael Chan }
46cf4e6363SMichael Chan 
47cf4e6363SMichael Chan 
48cf4e6363SMichael Chan /**
49cf4e6363SMichael Chan  * bnx2i_set_sq_info - update send queue (SQ) size parameter
50cf4e6363SMichael Chan  * @dev:	device pointer
512ad6e0c3SLee Jones  * @attr:	device attribute (unused)
52cf4e6363SMichael Chan  * @buf:	buffer to return current SQ size parameter
53cf4e6363SMichael Chan  * @count:	parameter buffer size
54cf4e6363SMichael Chan  *
55cf4e6363SMichael Chan  * Interface for user to change shared queue size allocated for each conn
56cf4e6363SMichael Chan  * Must be within SQ limits and a power of 2. For the latter this is needed
57cf4e6363SMichael Chan  * because of how libiscsi preallocates tasks.
58cf4e6363SMichael Chan  */
59cf4e6363SMichael Chan static ssize_t bnx2i_set_sq_info(struct device *dev,
60cf4e6363SMichael Chan 				 struct device_attribute *attr,
61cf4e6363SMichael Chan 				 const char *buf, size_t count)
62cf4e6363SMichael Chan {
63cf4e6363SMichael Chan 	struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev);
64cf4e6363SMichael Chan 	u32 val;
65cf4e6363SMichael Chan 	int max_sq_size;
66cf4e6363SMichael Chan 
67cf4e6363SMichael Chan 	if (hba->ofld_conns_active)
68cf4e6363SMichael Chan 		goto skip_config;
69cf4e6363SMichael Chan 
70cf4e6363SMichael Chan 	if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type))
71cf4e6363SMichael Chan 		max_sq_size = BNX2I_5770X_SQ_WQES_MAX;
72cf4e6363SMichael Chan 	else
73cf4e6363SMichael Chan 		max_sq_size = BNX2I_570X_SQ_WQES_MAX;
74cf4e6363SMichael Chan 
75cf4e6363SMichael Chan 	if (sscanf(buf, " 0x%x ", &val) > 0) {
76cf4e6363SMichael Chan 		if ((val >= BNX2I_SQ_WQES_MIN) && (val <= max_sq_size) &&
77cf4e6363SMichael Chan 		    (is_power_of_2(val)))
78cf4e6363SMichael Chan 			hba->max_sqes = val;
79cf4e6363SMichael Chan 	}
80cf4e6363SMichael Chan 
81cf4e6363SMichael Chan 	return count;
82cf4e6363SMichael Chan 
83cf4e6363SMichael Chan skip_config:
84cf4e6363SMichael Chan 	printk(KERN_ERR "bnx2i: device busy, cannot change SQ size\n");
85cf4e6363SMichael Chan 	return 0;
86cf4e6363SMichael Chan }
87cf4e6363SMichael Chan 
88cf4e6363SMichael Chan 
89cf4e6363SMichael Chan /**
90cf4e6363SMichael Chan  * bnx2i_show_ccell_info - returns command cell (HQ) size
91cf4e6363SMichael Chan  * @dev:	device pointer
922ad6e0c3SLee Jones  * @attr:	device attribute (unused)
93cf4e6363SMichael Chan  * @buf:	buffer to return current SQ size parameter
94cf4e6363SMichael Chan  *
95cf4e6363SMichael Chan  * returns per-connection TCP history queue size parameter
96cf4e6363SMichael Chan  */
97cf4e6363SMichael Chan static ssize_t bnx2i_show_ccell_info(struct device *dev,
98cf4e6363SMichael Chan 				     struct device_attribute *attr, char *buf)
99cf4e6363SMichael Chan {
100cf4e6363SMichael Chan 	struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev);
101cf4e6363SMichael Chan 
102cf4e6363SMichael Chan 	return sprintf(buf, "0x%x\n", hba->num_ccell);
103cf4e6363SMichael Chan }
104cf4e6363SMichael Chan 
105cf4e6363SMichael Chan 
106cf4e6363SMichael Chan /**
107*0a386bebSLee Jones  * bnx2i_set_ccell_info - set command cell (HQ) size
108cf4e6363SMichael Chan  * @dev:	device pointer
1092ad6e0c3SLee Jones  * @attr:	device attribute (unused)
110cf4e6363SMichael Chan  * @buf:	buffer to return current SQ size parameter
111cf4e6363SMichael Chan  * @count:	parameter buffer size
112cf4e6363SMichael Chan  *
113cf4e6363SMichael Chan  * updates per-connection TCP history queue size parameter
114cf4e6363SMichael Chan  */
115cf4e6363SMichael Chan static ssize_t bnx2i_set_ccell_info(struct device *dev,
116cf4e6363SMichael Chan 				    struct device_attribute *attr,
117cf4e6363SMichael Chan 				    const char *buf, size_t count)
118cf4e6363SMichael Chan {
119cf4e6363SMichael Chan 	u32 val;
120cf4e6363SMichael Chan 	struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev);
121cf4e6363SMichael Chan 
122cf4e6363SMichael Chan 	if (hba->ofld_conns_active)
123cf4e6363SMichael Chan 		goto skip_config;
124cf4e6363SMichael Chan 
125cf4e6363SMichael Chan 	if (sscanf(buf, " 0x%x ", &val) > 0) {
126cf4e6363SMichael Chan 		if ((val >= BNX2I_CCELLS_MIN) &&
127cf4e6363SMichael Chan 		    (val <= BNX2I_CCELLS_MAX)) {
128cf4e6363SMichael Chan 			hba->num_ccell = val;
129cf4e6363SMichael Chan 		}
130cf4e6363SMichael Chan 	}
131cf4e6363SMichael Chan 
132cf4e6363SMichael Chan 	return count;
133cf4e6363SMichael Chan 
134cf4e6363SMichael Chan skip_config:
135cf4e6363SMichael Chan 	printk(KERN_ERR "bnx2i: device busy, cannot change CCELL size\n");
136cf4e6363SMichael Chan 	return 0;
137cf4e6363SMichael Chan }
138cf4e6363SMichael Chan 
139cf4e6363SMichael Chan 
140cf4e6363SMichael Chan static DEVICE_ATTR(sq_size, S_IRUGO | S_IWUSR,
141cf4e6363SMichael Chan 		   bnx2i_show_sq_info, bnx2i_set_sq_info);
142cf4e6363SMichael Chan static DEVICE_ATTR(num_ccell, S_IRUGO | S_IWUSR,
143cf4e6363SMichael Chan 		   bnx2i_show_ccell_info, bnx2i_set_ccell_info);
144cf4e6363SMichael Chan 
145cf4e6363SMichael Chan struct device_attribute *bnx2i_dev_attributes[] = {
146cf4e6363SMichael Chan 	&dev_attr_sq_size,
147cf4e6363SMichael Chan 	&dev_attr_num_ccell,
148cf4e6363SMichael Chan 	NULL
149cf4e6363SMichael Chan };
150