diff options
Diffstat (limited to 'drivers/misc/mei/interface.c')
-rw-r--r-- | drivers/misc/mei/interface.c | 85 |
1 files changed, 32 insertions, 53 deletions
diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 428d21e36416..509c3957ff45 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c | |||
@@ -58,16 +58,18 @@ void mei_disable_interrupts(struct mei_device *dev) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | /** | 60 | /** |
61 | * _host_get_filled_slots - gets number of device filled buffer slots | 61 | * mei_hbuf_filled_slots - gets number of device filled buffer slots |
62 | * | 62 | * |
63 | * @device: the device structure | 63 | * @device: the device structure |
64 | * | 64 | * |
65 | * returns number of filled slots | 65 | * returns number of filled slots |
66 | */ | 66 | */ |
67 | static unsigned char _host_get_filled_slots(const struct mei_device *dev) | 67 | static unsigned char mei_hbuf_filled_slots(struct mei_device *dev) |
68 | { | 68 | { |
69 | char read_ptr, write_ptr; | 69 | char read_ptr, write_ptr; |
70 | 70 | ||
71 | dev->host_hw_state = mei_hcsr_read(dev); | ||
72 | |||
71 | read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8); | 73 | read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8); |
72 | write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16); | 74 | write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16); |
73 | 75 | ||
@@ -75,43 +77,33 @@ static unsigned char _host_get_filled_slots(const struct mei_device *dev) | |||
75 | } | 77 | } |
76 | 78 | ||
77 | /** | 79 | /** |
78 | * mei_host_buffer_is_empty - checks if host buffer is empty. | 80 | * mei_hbuf_is_empty - checks if host buffer is empty. |
79 | * | 81 | * |
80 | * @dev: the device structure | 82 | * @dev: the device structure |
81 | * | 83 | * |
82 | * returns 1 if empty, 0 - otherwise. | 84 | * returns true if empty, false - otherwise. |
83 | */ | 85 | */ |
84 | int mei_host_buffer_is_empty(struct mei_device *dev) | 86 | bool mei_hbuf_is_empty(struct mei_device *dev) |
85 | { | 87 | { |
86 | unsigned char filled_slots; | 88 | return mei_hbuf_filled_slots(dev) == 0; |
87 | |||
88 | dev->host_hw_state = mei_hcsr_read(dev); | ||
89 | filled_slots = _host_get_filled_slots(dev); | ||
90 | |||
91 | if (filled_slots == 0) | ||
92 | return 1; | ||
93 | |||
94 | return 0; | ||
95 | } | 89 | } |
96 | 90 | ||
97 | /** | 91 | /** |
98 | * mei_count_empty_write_slots - counts write empty slots. | 92 | * mei_hbuf_empty_slots - counts write empty slots. |
99 | * | 93 | * |
100 | * @dev: the device structure | 94 | * @dev: the device structure |
101 | * | 95 | * |
102 | * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count | 96 | * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count |
103 | */ | 97 | */ |
104 | int mei_count_empty_write_slots(struct mei_device *dev) | 98 | int mei_hbuf_empty_slots(struct mei_device *dev) |
105 | { | 99 | { |
106 | unsigned char buffer_depth, filled_slots, empty_slots; | 100 | unsigned char filled_slots, empty_slots; |
107 | 101 | ||
108 | dev->host_hw_state = mei_hcsr_read(dev); | 102 | filled_slots = mei_hbuf_filled_slots(dev); |
109 | buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); | 103 | empty_slots = dev->hbuf_depth - filled_slots; |
110 | filled_slots = _host_get_filled_slots(dev); | ||
111 | empty_slots = buffer_depth - filled_slots; | ||
112 | 104 | ||
113 | /* check for overflow */ | 105 | /* check for overflow */ |
114 | if (filled_slots > buffer_depth) | 106 | if (filled_slots > dev->hbuf_depth) |
115 | return -EOVERFLOW; | 107 | return -EOVERFLOW; |
116 | 108 | ||
117 | return empty_slots; | 109 | return empty_slots; |
@@ -127,52 +119,39 @@ int mei_count_empty_write_slots(struct mei_device *dev) | |||
127 | * | 119 | * |
128 | * This function returns -EIO if write has failed | 120 | * This function returns -EIO if write has failed |
129 | */ | 121 | */ |
130 | int mei_write_message(struct mei_device *dev, | 122 | int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, |
131 | struct mei_msg_hdr *header, | 123 | unsigned char *buf, unsigned long length) |
132 | unsigned char *write_buffer, | ||
133 | unsigned long write_length) | ||
134 | { | 124 | { |
135 | u32 temp_msg = 0; | 125 | unsigned long rem, dw_cnt; |
136 | unsigned long bytes_written = 0; | 126 | u32 *reg_buf = (u32 *)buf; |
137 | unsigned char buffer_depth, filled_slots, empty_slots; | 127 | int i; |
138 | unsigned long dw_to_write; | 128 | int empty_slots; |
139 | |||
140 | dev->host_hw_state = mei_hcsr_read(dev); | ||
141 | 129 | ||
142 | dev_dbg(&dev->pdev->dev, | ||
143 | "host_hw_state = 0x%08x.\n", | ||
144 | dev->host_hw_state); | ||
145 | 130 | ||
146 | dev_dbg(&dev->pdev->dev, | 131 | dev_dbg(&dev->pdev->dev, |
147 | "mei_write_message header=%08x.\n", | 132 | "mei_write_message header=%08x.\n", |
148 | *((u32 *) header)); | 133 | *((u32 *) header)); |
149 | 134 | ||
150 | buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); | 135 | empty_slots = mei_hbuf_empty_slots(dev); |
151 | filled_slots = _host_get_filled_slots(dev); | 136 | dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); |
152 | empty_slots = buffer_depth - filled_slots; | ||
153 | dev_dbg(&dev->pdev->dev, | ||
154 | "filled = %hu, empty = %hu.\n", | ||
155 | filled_slots, empty_slots); | ||
156 | |||
157 | dw_to_write = ((write_length + 3) / 4); | ||
158 | 137 | ||
159 | if (dw_to_write > empty_slots) | 138 | dw_cnt = mei_data2slots(length); |
139 | if (empty_slots < 0 || dw_cnt > empty_slots) | ||
160 | return -EIO; | 140 | return -EIO; |
161 | 141 | ||
162 | mei_reg_write(dev, H_CB_WW, *((u32 *) header)); | 142 | mei_reg_write(dev, H_CB_WW, *((u32 *) header)); |
163 | 143 | ||
164 | while (write_length >= 4) { | 144 | for (i = 0; i < length / 4; i++) |
165 | mei_reg_write(dev, H_CB_WW, | 145 | mei_reg_write(dev, H_CB_WW, reg_buf[i]); |
166 | *(u32 *) (write_buffer + bytes_written)); | ||
167 | bytes_written += 4; | ||
168 | write_length -= 4; | ||
169 | } | ||
170 | 146 | ||
171 | if (write_length > 0) { | 147 | rem = length & 0x3; |
172 | memcpy(&temp_msg, &write_buffer[bytes_written], write_length); | 148 | if (rem > 0) { |
173 | mei_reg_write(dev, H_CB_WW, temp_msg); | 149 | u32 reg = 0; |
150 | memcpy(®, &buf[length - rem], rem); | ||
151 | mei_reg_write(dev, H_CB_WW, reg); | ||
174 | } | 152 | } |
175 | 153 | ||
154 | dev->host_hw_state = mei_hcsr_read(dev); | ||
176 | dev->host_hw_state |= H_IG; | 155 | dev->host_hw_state |= H_IG; |
177 | mei_hcsr_set(dev); | 156 | mei_hcsr_set(dev); |
178 | dev->me_hw_state = mei_mecsr_read(dev); | 157 | dev->me_hw_state = mei_mecsr_read(dev); |