Skip to content

Commit ed04b36

Browse files
donbolllguohan
authored andcommitted
Update to optoe driver to improve EOF handling (sonic-net#44)
Added patch: 'driver-support-optoe-EOF_fix.patch' to patch directory Added the patch to 'series Signed-off-by: Don Bollinger
1 parent 3525f35 commit ed04b36

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed
+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
From 556c452dcf5706a951ef490327b74bd27a411693 Mon Sep 17 00:00:00 2001
2+
From: Don Bollinger <[email protected]>
3+
Date: Fri, 9 Mar 2018 18:22:33 -0800
4+
Subject: [PATCH] drivers/misc/eeprom: Improve EOF handling
5+
6+
Change -ENXIO error to return zero, which user space sees as EOF
7+
Detect SFP devices with only one I2C address (DAC devices)
8+
Correctly handle partial read, returning actual bytes transferred
9+
10+
Signed-off-by: Don Bollinger
11+
---
12+
drivers/misc/eeprom/optoe.c | 52 +++++++++++++++++++++++++++++++--------------
13+
1 file changed, 36 insertions(+), 16 deletions(-)
14+
15+
diff --git a/drivers/misc/eeprom/optoe.c b/drivers/misc/eeprom/optoe.c
16+
index 7425bf6..b3064f0 100644
17+
--- a/drivers/misc/eeprom/optoe.c
18+
+++ b/drivers/misc/eeprom/optoe.c
19+
@@ -158,6 +158,7 @@ struct optoe_platform_data {
20+
*/
21+
#define TWO_ADDR_EEPROM_SIZE ((3 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE)
22+
#define TWO_ADDR_EEPROM_UNPAGED_SIZE (4 * OPTOE_PAGE_SIZE)
23+
+#define TWO_ADDR_NO_0X51_SIZE (2 * OPTOE_PAGE_SIZE)
24+
25+
/* a few constants to find our way around the EEPROM */
26+
#define OPTOE_PAGE_SELECT_REG 0x7F
27+
@@ -165,9 +166,12 @@ struct optoe_platform_data {
28+
#define ONE_ADDR_NOT_PAGEABLE (1<<2)
29+
#define TWO_ADDR_PAGEABLE_REG 0x40
30+
#define TWO_ADDR_PAGEABLE (1<<4)
31+
+#define TWO_ADDR_0X51_REG 92
32+
+#define TWO_ADDR_0X51_SUPP (1<<6)
33+
#define OPTOE_ID_REG 0
34+
#define OPTOE_READ_OP 0
35+
#define OPTOE_WRITE_OP 1
36+
+#define OPTOE_EOF 0 /* used for access beyond end of device */
37+
38+
struct optoe_data {
39+
struct optoe_platform_data chip;
40+
@@ -564,7 +568,7 @@ static ssize_t optoe_eeprom_update_client(struct optoe_data *optoe,
41+
* Returns updated len for this access:
42+
* - entire access is legal, original len is returned.
43+
* - access begins legal but is too long, len is truncated to fit.
44+
- * - initial offset exceeds supported pages, return -EINVAL
45+
+ * - initial offset exceeds supported pages, return OPTOE_EOF (zero)
46+
*/
47+
static ssize_t optoe_page_legal(struct optoe_data *optoe,
48+
loff_t off, size_t len)
49+
@@ -578,12 +582,12 @@ static ssize_t optoe_page_legal(struct optoe_data *optoe,
50+
return -EINVAL;
51+
if (optoe->dev_class == TWO_ADDR) {
52+
/* SFP case */
53+
- /* if no pages needed, we're good */
54+
- if ((off + len) <= TWO_ADDR_EEPROM_UNPAGED_SIZE)
55+
+ /* if only using addr 0x50 (first 256 bytes) we're good */
56+
+ if ((off + len) <= TWO_ADDR_NO_0X51_SIZE)
57+
return len;
58+
/* if offset exceeds possible pages, we're not good */
59+
if (off >= TWO_ADDR_EEPROM_SIZE)
60+
- return -EINVAL;
61+
+ return OPTOE_EOF;
62+
/* in between, are pages supported? */
63+
status = optoe_eeprom_read(optoe, client, &regval,
64+
TWO_ADDR_PAGEABLE_REG, 1);
65+
@@ -595,8 +599,23 @@ static ssize_t optoe_page_legal(struct optoe_data *optoe,
66+
} else {
67+
/* pages not supported, trim len to unpaged size */
68+
if (off >= TWO_ADDR_EEPROM_UNPAGED_SIZE)
69+
- return -EINVAL;
70+
- maxlen = TWO_ADDR_EEPROM_UNPAGED_SIZE - off;
71+
+ return OPTOE_EOF;
72+
+
73+
+ /* will be accessing addr 0x51, is that supported? */
74+
+ /* byte 92, bit 6 implies DDM support, 0x51 support */
75+
+ status = optoe_eeprom_read(optoe, client, &regval,
76+
+ TWO_ADDR_0X51_REG, 1);
77+
+ if (status < 0)
78+
+ return status;
79+
+ if (regval & TWO_ADDR_0X51_SUPP) {
80+
+ /* addr 0x51 is OK */
81+
+ maxlen = TWO_ADDR_EEPROM_UNPAGED_SIZE - off;
82+
+ } else {
83+
+ /* addr 0x51 NOT supported, trim to 256 max */
84+
+ if (off >= TWO_ADDR_NO_0X51_SIZE)
85+
+ return OPTOE_EOF;
86+
+ maxlen = TWO_ADDR_NO_0X51_SIZE - off;
87+
+ }
88+
}
89+
len = (len > maxlen) ? maxlen : len;
90+
dev_dbg(&client->dev,
91+
@@ -609,7 +628,7 @@ static ssize_t optoe_page_legal(struct optoe_data *optoe,
92+
return len;
93+
/* if offset exceeds possible pages, we're not good */
94+
if (off >= ONE_ADDR_EEPROM_SIZE)
95+
- return -EINVAL;
96+
+ return OPTOE_EOF;
97+
/* in between, are pages supported? */
98+
status = optoe_eeprom_read(optoe, client, &regval,
99+
ONE_ADDR_PAGEABLE_REG, 1);
100+
@@ -618,7 +637,7 @@ static ssize_t optoe_page_legal(struct optoe_data *optoe,
101+
if (regval & ONE_ADDR_NOT_PAGEABLE) {
102+
/* pages not supported, trim len to unpaged size */
103+
if (off >= ONE_ADDR_EEPROM_UNPAGED_SIZE)
104+
- return -EINVAL;
105+
+ return OPTOE_EOF;
106+
maxlen = ONE_ADDR_EEPROM_UNPAGED_SIZE - off;
107+
} else {
108+
/* Pages supported, trim len to the end of pages */
109+
@@ -659,8 +678,10 @@ static ssize_t optoe_read_write(struct optoe_data *optoe,
110+
* Confirm this access fits within the device suppored addr range
111+
*/
112+
status = optoe_page_legal(optoe, off, len);
113+
- if (status < 0)
114+
- goto err;
115+
+ if ((status == OPTOE_EOF) || (status < 0)) {
116+
+ mutex_unlock(&optoe->lock);
117+
+ return status;
118+
+ }
119+
len = status;
120+
121+
/*
122+
@@ -720,7 +741,11 @@ static ssize_t optoe_read_write(struct optoe_data *optoe,
123+
dev_dbg(&client->dev,
124+
"o_u_c: chunk %d c_offset %lld c_len %ld failed %d!\n",
125+
chunk, chunk_offset, (long int) chunk_len, status);
126+
- goto err;
127+
+ if (status > 0)
128+
+ retval += status;
129+
+ if (retval == 0)
130+
+ retval = status;
131+
+ break;
132+
}
133+
buf += status;
134+
pending_len -= status;
135+
@@ -729,11 +754,6 @@ static ssize_t optoe_read_write(struct optoe_data *optoe,
136+
mutex_unlock(&optoe->lock);
137+
138+
return retval;
139+
-
140+
-err:
141+
- mutex_unlock(&optoe->lock);
142+
-
143+
- return status;
144+
}
145+
146+
static ssize_t optoe_bin_read(struct file *filp, struct kobject *kobj,
147+
--
148+
2.11.0
149+

patch/series

+1
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ driver-support-tun-config-carrier-enable.patch
3333
driver-i2c-bus-ismt-i801-support-intel-denverton.patch
3434
driver-hwmon-max31790.patch
3535
driver-support-optoe.patch
36+
driver-support-optoe-EOF_fix.patch

0 commit comments

Comments
 (0)