aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Taprogge <jens.taprogge@taprogge.org>2012-09-12 08:55:26 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-12 12:54:15 -0400
commit70a32811e5d1c3a48d99088065ef74367221cde3 (patch)
tree51afeee436d785374ef7f6478ae3475b5177ea3f
parentaf2140ce288fcb12a3c30a69b6ba93fd64d0a861 (diff)
Staging: ipack/devices/ipoctal: split ipoctal_channel from ipoctal.
By moving everything channel related into a separate struct we will be able to clean up a lot of code. In the end tty->driver_data will no longer need to point to ipoctal but instead can point to the respective channel. Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org> Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/ipack/devices/ipoctal.c286
1 files changed, 150 insertions, 136 deletions
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c
index 35513d9e013a..9ab0e8082565 100644
--- a/drivers/staging/ipack/devices/ipoctal.c
+++ b/drivers/staging/ipack/devices/ipoctal.c
@@ -30,22 +30,26 @@
30 30
31static const struct tty_operations ipoctal_fops; 31static const struct tty_operations ipoctal_fops;
32 32
33struct ipoctal_channel {
34 struct ipoctal_stats stats;
35 unsigned int nb_bytes;
36 unsigned int count_wr;
37 wait_queue_head_t queue;
38 spinlock_t lock;
39 unsigned int pointer_read;
40 unsigned int pointer_write;
41 atomic_t open;
42 struct tty_port tty_port;
43 union scc2698_channel __iomem *regs;
44 union scc2698_block __iomem *block_regs;
45};
46
33struct ipoctal { 47struct ipoctal {
34 struct list_head list; 48 struct list_head list;
35 struct ipack_device *dev; 49 struct ipack_device *dev;
36 unsigned int board_id; 50 unsigned int board_id;
37 union scc2698_channel __iomem *chan_regs; 51 struct ipoctal_channel channel[NR_CHANNELS];
38 union scc2698_block __iomem *block_regs;
39 struct ipoctal_stats chan_stats[NR_CHANNELS];
40 unsigned int nb_bytes[NR_CHANNELS];
41 unsigned int count_wr[NR_CHANNELS];
42 wait_queue_head_t queue[NR_CHANNELS];
43 spinlock_t lock[NR_CHANNELS];
44 unsigned int pointer_read[NR_CHANNELS];
45 unsigned int pointer_write[NR_CHANNELS];
46 atomic_t open[NR_CHANNELS];
47 unsigned char write; 52 unsigned char write;
48 struct tty_port tty_port[NR_CHANNELS];
49 struct tty_driver *tty_drv; 53 struct tty_driver *tty_drv;
50}; 54};
51 55
@@ -87,7 +91,7 @@ static struct ipoctal *ipoctal_find_board(struct tty_struct *tty)
87static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) 91static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
88{ 92{
89 struct ipoctal *ipoctal; 93 struct ipoctal *ipoctal;
90 int channel = tty->index; 94 struct ipoctal_channel *channel;
91 95
92 ipoctal = ipoctal_find_board(tty); 96 ipoctal = ipoctal_find_board(tty);
93 97
@@ -96,17 +100,18 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
96 tty->driver->major); 100 tty->driver->major);
97 return -ENODEV; 101 return -ENODEV;
98 } 102 }
103 channel = &ipoctal->channel[tty->index];
99 104
100 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, 105 ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
101 CR_ENABLE_RX); 106 CR_ENABLE_RX);
102 return 0; 107 return 0;
103} 108}
104 109
105static int ipoctal_open(struct tty_struct *tty, struct file *file) 110static int ipoctal_open(struct tty_struct *tty, struct file *file)
106{ 111{
107 int channel = tty->index;
108 int res; 112 int res;
109 struct ipoctal *ipoctal; 113 struct ipoctal *ipoctal;
114 struct ipoctal_channel *channel;
110 115
111 ipoctal = ipoctal_find_board(tty); 116 ipoctal = ipoctal_find_board(tty);
112 117
@@ -115,17 +120,18 @@ static int ipoctal_open(struct tty_struct *tty, struct file *file)
115 tty->driver->major); 120 tty->driver->major);
116 return -ENODEV; 121 return -ENODEV;
117 } 122 }
123 channel = &ipoctal->channel[tty->index];
118 124
119 if (atomic_read(&ipoctal->open[channel])) 125 if (atomic_read(&channel->open))
120 return -EBUSY; 126 return -EBUSY;
121 127
122 tty->driver_data = ipoctal; 128 tty->driver_data = ipoctal;
123 129
124 res = tty_port_open(&ipoctal->tty_port[channel], tty, file); 130 res = tty_port_open(&channel->tty_port, tty, file);
125 if (res) 131 if (res)
126 return res; 132 return res;
127 133
128 atomic_inc(&ipoctal->open[channel]); 134 atomic_inc(&channel->open);
129 return 0; 135 return 0;
130} 136}
131 137
@@ -141,26 +147,27 @@ static void ipoctal_reset_stats(struct ipoctal_stats *stats)
141 147
142static void ipoctal_free_channel(struct tty_struct *tty) 148static void ipoctal_free_channel(struct tty_struct *tty)
143{ 149{
144 int channel = tty->index;
145 struct ipoctal *ipoctal = tty->driver_data; 150 struct ipoctal *ipoctal = tty->driver_data;
151 struct ipoctal_channel *channel;
146 152
147 if (ipoctal == NULL) 153 if (ipoctal == NULL)
148 return; 154 return;
155 channel = &ipoctal->channel[tty->index];
149 156
150 ipoctal_reset_stats(&ipoctal->chan_stats[channel]); 157 ipoctal_reset_stats(&channel->stats);
151 ipoctal->pointer_read[channel] = 0; 158 channel->pointer_read = 0;
152 ipoctal->pointer_write[channel] = 0; 159 channel->pointer_write = 0;
153 ipoctal->nb_bytes[channel] = 0; 160 channel->nb_bytes = 0;
154} 161}
155 162
156static void ipoctal_close(struct tty_struct *tty, struct file *filp) 163static void ipoctal_close(struct tty_struct *tty, struct file *filp)
157{ 164{
158 int channel = tty->index;
159 struct ipoctal *ipoctal = tty->driver_data; 165 struct ipoctal *ipoctal = tty->driver_data;
166 struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
160 167
161 tty_port_close(&ipoctal->tty_port[channel], tty, filp); 168 tty_port_close(&channel->tty_port, tty, filp);
162 169
163 if (atomic_dec_and_test(&ipoctal->open[channel])) 170 if (atomic_dec_and_test(&channel->open))
164 ipoctal_free_channel(tty); 171 ipoctal_free_channel(tty);
165} 172}
166 173
@@ -168,24 +175,23 @@ static int ipoctal_get_icount(struct tty_struct *tty,
168 struct serial_icounter_struct *icount) 175 struct serial_icounter_struct *icount)
169{ 176{
170 struct ipoctal *ipoctal = tty->driver_data; 177 struct ipoctal *ipoctal = tty->driver_data;
171 int channel = tty->index; 178 struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
172 179
173 icount->cts = 0; 180 icount->cts = 0;
174 icount->dsr = 0; 181 icount->dsr = 0;
175 icount->rng = 0; 182 icount->rng = 0;
176 icount->dcd = 0; 183 icount->dcd = 0;
177 icount->rx = ipoctal->chan_stats[channel].rx; 184 icount->rx = channel->stats.rx;
178 icount->tx = ipoctal->chan_stats[channel].tx; 185 icount->tx = channel->stats.tx;
179 icount->frame = ipoctal->chan_stats[channel].framing_err; 186 icount->frame = channel->stats.framing_err;
180 icount->parity = ipoctal->chan_stats[channel].parity_err; 187 icount->parity = channel->stats.parity_err;
181 icount->brk = ipoctal->chan_stats[channel].rcv_break; 188 icount->brk = channel->stats.rcv_break;
182 return 0; 189 return 0;
183} 190}
184 191
185static int ipoctal_irq_handler(void *arg) 192static int ipoctal_irq_handler(void *arg)
186{ 193{
187 unsigned int channel; 194 unsigned int ichannel;
188 unsigned int block;
189 unsigned char isr; 195 unsigned char isr;
190 unsigned char sr; 196 unsigned char sr;
191 unsigned char isr_tx_rdy, isr_rx_rdy; 197 unsigned char isr_tx_rdy, isr_rx_rdy;
@@ -193,14 +199,16 @@ static int ipoctal_irq_handler(void *arg)
193 unsigned char flag; 199 unsigned char flag;
194 struct tty_struct *tty; 200 struct tty_struct *tty;
195 struct ipoctal *ipoctal = (struct ipoctal *) arg; 201 struct ipoctal *ipoctal = (struct ipoctal *) arg;
202 struct ipoctal_channel *channel;
196 203
197 /* Check all channels */ 204 /* Check all channels */
198 for (channel = 0; channel < NR_CHANNELS; channel++) { 205 for (ichannel = 0; ichannel < NR_CHANNELS; ichannel++) {
206 channel = &ipoctal->channel[ichannel];
199 /* If there is no client, skip the check */ 207 /* If there is no client, skip the check */
200 if (!atomic_read(&ipoctal->open[channel])) 208 if (!atomic_read(&channel->open))
201 continue; 209 continue;
202 210
203 tty = tty_port_tty_get(&ipoctal->tty_port[channel]); 211 tty = tty_port_tty_get(&channel->tty_port);
204 if (!tty) 212 if (!tty)
205 continue; 213 continue;
206 214
@@ -208,13 +216,12 @@ static int ipoctal_irq_handler(void *arg)
208 * The HW is organized in pair of channels. 216 * The HW is organized in pair of channels.
209 * See which register we need to read from 217 * See which register we need to read from
210 */ 218 */
211 block = channel / 2;
212 isr = ipoctal_read_io_reg(ipoctal, 219 isr = ipoctal_read_io_reg(ipoctal,
213 &ipoctal->block_regs[block].r.isr); 220 &channel->block_regs->r.isr);
214 sr = ipoctal_read_io_reg(ipoctal, 221 sr = ipoctal_read_io_reg(ipoctal,
215 &ipoctal->chan_regs[channel].r.sr); 222 &channel->regs->r.sr);
216 223
217 if ((channel % 2) == 1) { 224 if ((ichannel % 2) == 1) {
218 isr_tx_rdy = isr & ISR_TxRDY_B; 225 isr_tx_rdy = isr & ISR_TxRDY_B;
219 isr_rx_rdy = isr & ISR_RxRDY_FFULL_B; 226 isr_rx_rdy = isr & ISR_RxRDY_FFULL_B;
220 } else { 227 } else {
@@ -227,47 +234,47 @@ static int ipoctal_irq_handler(void *arg)
227 */ 234 */
228 if ((ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) && 235 if ((ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) &&
229 (sr & SR_TX_EMPTY) && 236 (sr & SR_TX_EMPTY) &&
230 (ipoctal->nb_bytes[channel] == 0)) { 237 (channel->nb_bytes == 0)) {
231 ipoctal_write_io_reg(ipoctal, 238 ipoctal_write_io_reg(ipoctal,
232 &ipoctal->chan_regs[channel].w.cr, 239 &channel->regs->w.cr,
233 CR_DISABLE_TX); 240 CR_DISABLE_TX);
234 ipoctal_write_cr_cmd(ipoctal, 241 ipoctal_write_cr_cmd(ipoctal,
235 &ipoctal->chan_regs[channel].w.cr, 242 &channel->regs->w.cr,
236 CR_CMD_NEGATE_RTSN); 243 CR_CMD_NEGATE_RTSN);
237 ipoctal_write_io_reg(ipoctal, 244 ipoctal_write_io_reg(ipoctal,
238 &ipoctal->chan_regs[channel].w.cr, 245 &channel->regs->w.cr,
239 CR_ENABLE_RX); 246 CR_ENABLE_RX);
240 ipoctal->write = 1; 247 ipoctal->write = 1;
241 wake_up_interruptible(&ipoctal->queue[channel]); 248 wake_up_interruptible(&channel->queue);
242 } 249 }
243 250
244 /* RX data */ 251 /* RX data */
245 if (isr_rx_rdy && (sr & SR_RX_READY)) { 252 if (isr_rx_rdy && (sr & SR_RX_READY)) {
246 value = ipoctal_read_io_reg(ipoctal, 253 value = ipoctal_read_io_reg(ipoctal,
247 &ipoctal->chan_regs[channel].r.rhr); 254 &channel->regs->r.rhr);
248 flag = TTY_NORMAL; 255 flag = TTY_NORMAL;
249 256
250 /* Error: count statistics */ 257 /* Error: count statistics */
251 if (sr & SR_ERROR) { 258 if (sr & SR_ERROR) {
252 ipoctal_write_cr_cmd(ipoctal, 259 ipoctal_write_cr_cmd(ipoctal,
253 &ipoctal->chan_regs[channel].w.cr, 260 &channel->regs->w.cr,
254 CR_CMD_RESET_ERR_STATUS); 261 CR_CMD_RESET_ERR_STATUS);
255 262
256 if (sr & SR_OVERRUN_ERROR) { 263 if (sr & SR_OVERRUN_ERROR) {
257 ipoctal->chan_stats[channel].overrun_err++; 264 channel->stats.overrun_err++;
258 /* Overrun doesn't affect the current character*/ 265 /* Overrun doesn't affect the current character*/
259 tty_insert_flip_char(tty, 0, TTY_OVERRUN); 266 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
260 } 267 }
261 if (sr & SR_PARITY_ERROR) { 268 if (sr & SR_PARITY_ERROR) {
262 ipoctal->chan_stats[channel].parity_err++; 269 channel->stats.parity_err++;
263 flag = TTY_PARITY; 270 flag = TTY_PARITY;
264 } 271 }
265 if (sr & SR_FRAMING_ERROR) { 272 if (sr & SR_FRAMING_ERROR) {
266 ipoctal->chan_stats[channel].framing_err++; 273 channel->stats.framing_err++;
267 flag = TTY_FRAME; 274 flag = TTY_FRAME;
268 } 275 }
269 if (sr & SR_RECEIVED_BREAK) { 276 if (sr & SR_RECEIVED_BREAK) {
270 ipoctal->chan_stats[channel].rcv_break++; 277 channel->stats.rcv_break++;
271 flag = TTY_BREAK; 278 flag = TTY_BREAK;
272 } 279 }
273 } 280 }
@@ -277,30 +284,29 @@ static int ipoctal_irq_handler(void *arg)
277 284
278 /* TX of each character */ 285 /* TX of each character */
279 if (isr_tx_rdy && (sr & SR_TX_READY)) { 286 if (isr_tx_rdy && (sr & SR_TX_READY)) {
280 unsigned int *pointer_write = 287 unsigned int *pointer_write = &channel->pointer_write;
281 &ipoctal->pointer_write[channel];
282 288
283 if (ipoctal->nb_bytes[channel] <= 0) { 289 if (channel->nb_bytes <= 0) {
284 ipoctal->nb_bytes[channel] = 0; 290 channel->nb_bytes = 0;
285 continue; 291 continue;
286 } 292 }
287 293
288 value = ipoctal->tty_port[channel].xmit_buf[*pointer_write]; 294 value = channel->tty_port.xmit_buf[*pointer_write];
289 ipoctal_write_io_reg(ipoctal, 295 ipoctal_write_io_reg(ipoctal,
290 &ipoctal->chan_regs[channel].w.thr, 296 &channel->regs->w.thr,
291 value); 297 value);
292 ipoctal->chan_stats[channel].tx++; 298 channel->stats.tx++;
293 ipoctal->count_wr[channel]++; 299 channel->count_wr++;
294 (*pointer_write)++; 300 (*pointer_write)++;
295 *pointer_write = *pointer_write % PAGE_SIZE; 301 *pointer_write = *pointer_write % PAGE_SIZE;
296 ipoctal->nb_bytes[channel]--; 302 channel->nb_bytes--;
297 303
298 if ((ipoctal->nb_bytes[channel] == 0) && 304 if ((channel->nb_bytes == 0) &&
299 (waitqueue_active(&ipoctal->queue[channel]))) { 305 (waitqueue_active(&channel->queue))) {
300 306
301 if (ipoctal->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) { 307 if (ipoctal->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) {
302 ipoctal->write = 1; 308 ipoctal->write = 1;
303 wake_up_interruptible(&ipoctal->queue[channel]); 309 wake_up_interruptible(&channel->queue);
304 } 310 }
305 } 311 }
306 } 312 }
@@ -348,6 +354,9 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
348 struct tty_driver *tty; 354 struct tty_driver *tty;
349 char name[20]; 355 char name[20];
350 unsigned char board_id; 356 unsigned char board_id;
357 struct ipoctal_channel *channel;
358 union scc2698_channel __iomem *chan_regs;
359 union scc2698_block __iomem *block_regs;
351 360
352 res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, 361 res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0,
353 IPACK_ID_SPACE); 362 IPACK_ID_SPACE);
@@ -385,41 +394,45 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
385 } 394 }
386 395
387 /* Save the virtual address to access the registers easily */ 396 /* Save the virtual address to access the registers easily */
388 ipoctal->chan_regs = 397 chan_regs =
389 (union scc2698_channel __iomem *) ipoctal->dev->io_space.address; 398 (union scc2698_channel __iomem *) ipoctal->dev->io_space.address;
390 ipoctal->block_regs = 399 block_regs =
391 (union scc2698_block __iomem *) ipoctal->dev->io_space.address; 400 (union scc2698_block __iomem *) ipoctal->dev->io_space.address;
392 401
393 /* Disable RX and TX before touching anything */ 402 /* Disable RX and TX before touching anything */
394 for (i = 0; i < NR_CHANNELS ; i++) { 403 for (i = 0; i < NR_CHANNELS ; i++) {
395 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].w.cr, 404 struct ipoctal_channel *channel = &ipoctal->channel[i];
405 channel->regs = chan_regs + i;
406 channel->block_regs = block_regs + (i >> 1);
407
408 ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
396 CR_DISABLE_RX | CR_DISABLE_TX); 409 CR_DISABLE_RX | CR_DISABLE_TX);
397 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].w.cr, 410 ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
398 CR_CMD_RESET_RX); 411 CR_CMD_RESET_RX);
399 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[i].w.cr, 412 ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
400 CR_CMD_RESET_TX); 413 CR_CMD_RESET_TX);
401 ipoctal_write_io_reg(ipoctal, 414 ipoctal_write_io_reg(ipoctal,
402 &ipoctal->chan_regs[i].w.mr, 415 &channel->regs->w.mr,
403 MR1_CHRL_8_BITS | MR1_ERROR_CHAR | 416 MR1_CHRL_8_BITS | MR1_ERROR_CHAR |
404 MR1_RxINT_RxRDY); /* mr1 */ 417 MR1_RxINT_RxRDY); /* mr1 */
405 ipoctal_write_io_reg(ipoctal, 418 ipoctal_write_io_reg(ipoctal,
406 &ipoctal->chan_regs[i].w.mr, 419 &channel->regs->w.mr,
407 0); /* mr2 */ 420 0); /* mr2 */
408 ipoctal_write_io_reg(ipoctal, 421 ipoctal_write_io_reg(ipoctal,
409 &ipoctal->chan_regs[i].w.csr, 422 &channel->regs->w.csr,
410 TX_CLK_9600 | RX_CLK_9600); 423 TX_CLK_9600 | RX_CLK_9600);
411 } 424 }
412 425
413 for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) { 426 for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) {
414 ipoctal_write_io_reg(ipoctal, 427 ipoctal_write_io_reg(ipoctal,
415 &ipoctal->block_regs[i].w.acr, 428 &block_regs[i].w.acr,
416 ACR_BRG_SET2); 429 ACR_BRG_SET2);
417 ipoctal_write_io_reg(ipoctal, 430 ipoctal_write_io_reg(ipoctal,
418 &ipoctal->block_regs[i].w.opcr, 431 &block_regs[i].w.opcr,
419 OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | 432 OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN |
420 OPCR_MPOb_RTSN); 433 OPCR_MPOb_RTSN);
421 ipoctal_write_io_reg(ipoctal, 434 ipoctal_write_io_reg(ipoctal,
422 &ipoctal->block_regs[i].w.imr, 435 &block_regs[i].w.imr,
423 IMR_TxRDY_A | IMR_RxRDY_FFULL_A | 436 IMR_TxRDY_A | IMR_RxRDY_FFULL_A |
424 IMR_DELTA_BREAK_A | IMR_TxRDY_B | 437 IMR_DELTA_BREAK_A | IMR_TxRDY_B |
425 IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B); 438 IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B);
@@ -472,25 +485,26 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
472 ipoctal->tty_drv = tty; 485 ipoctal->tty_drv = tty;
473 486
474 for (i = 0; i < NR_CHANNELS; i++) { 487 for (i = 0; i < NR_CHANNELS; i++) {
475 tty_port_init(&ipoctal->tty_port[i]); 488 channel = &ipoctal->channel[i];
476 tty_port_alloc_xmit_buf(&ipoctal->tty_port[i]); 489 tty_port_init(&channel->tty_port);
477 ipoctal->tty_port[i].ops = &ipoctal_tty_port_ops; 490 tty_port_alloc_xmit_buf(&channel->tty_port);
478 491 channel->tty_port.ops = &ipoctal_tty_port_ops;
479 ipoctal_reset_stats(&ipoctal->chan_stats[i]); 492
480 ipoctal->nb_bytes[i] = 0; 493 ipoctal_reset_stats(&channel->stats);
481 init_waitqueue_head(&ipoctal->queue[i]); 494 channel->nb_bytes = 0;
482 495 init_waitqueue_head(&channel->queue);
483 spin_lock_init(&ipoctal->lock[i]); 496
484 ipoctal->pointer_read[i] = 0; 497 spin_lock_init(&channel->lock);
485 ipoctal->pointer_write[i] = 0; 498 channel->pointer_read = 0;
486 ipoctal->nb_bytes[i] = 0; 499 channel->pointer_write = 0;
500 channel->nb_bytes = 0;
487 tty_register_device(tty, i, NULL); 501 tty_register_device(tty, i, NULL);
488 502
489 /* 503 /*
490 * Enable again the RX. TX will be enabled when 504 * Enable again the RX. TX will be enabled when
491 * there is something to send 505 * there is something to send
492 */ 506 */
493 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].w.cr, 507 ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
494 CR_ENABLE_RX); 508 CR_ENABLE_RX);
495 } 509 }
496 510
@@ -505,23 +519,22 @@ out_unregister_id_space:
505 return res; 519 return res;
506} 520}
507 521
508static inline int ipoctal_copy_write_buffer(struct ipoctal *ipoctal, 522static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
509 unsigned int channel,
510 const unsigned char *buf, 523 const unsigned char *buf,
511 int count) 524 int count)
512{ 525{
513 unsigned long flags; 526 unsigned long flags;
514 int i; 527 int i;
515 unsigned int *pointer_read = &ipoctal->pointer_read[channel]; 528 unsigned int *pointer_read = &channel->pointer_read;
516 529
517 /* Copy the bytes from the user buffer to the internal one */ 530 /* Copy the bytes from the user buffer to the internal one */
518 for (i = 0; i < count; i++) { 531 for (i = 0; i < count; i++) {
519 if (i <= (PAGE_SIZE - ipoctal->nb_bytes[channel])) { 532 if (i <= (PAGE_SIZE - channel->nb_bytes)) {
520 spin_lock_irqsave(&ipoctal->lock[channel], flags); 533 spin_lock_irqsave(&channel->lock, flags);
521 ipoctal->tty_port[channel].xmit_buf[*pointer_read] = buf[i]; 534 channel->tty_port.xmit_buf[*pointer_read] = buf[i];
522 *pointer_read = (*pointer_read + 1) % PAGE_SIZE; 535 *pointer_read = (*pointer_read + 1) % PAGE_SIZE;
523 ipoctal->nb_bytes[channel]++; 536 channel->nb_bytes++;
524 spin_unlock_irqrestore(&ipoctal->lock[channel], flags); 537 spin_unlock_irqrestore(&channel->lock, flags);
525 } else { 538 } else {
526 break; 539 break;
527 } 540 }
@@ -529,21 +542,22 @@ static inline int ipoctal_copy_write_buffer(struct ipoctal *ipoctal,
529 return i; 542 return i;
530} 543}
531 544
532static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel, 545static int ipoctal_write(struct ipoctal *ipoctal, unsigned int ichannel,
533 const unsigned char *buf, int count) 546 const unsigned char *buf, int count)
534{ 547{
535 ipoctal->nb_bytes[channel] = 0; 548 struct ipoctal_channel *channel = &ipoctal->channel[ichannel];
536 ipoctal->count_wr[channel] = 0; 549 channel->nb_bytes = 0;
550 channel->count_wr = 0;
537 551
538 ipoctal_copy_write_buffer(ipoctal, channel, buf, count); 552 ipoctal_copy_write_buffer(channel, buf, count);
539 553
540 /* As the IP-OCTAL 485 only supports half duplex, do it manually */ 554 /* As the IP-OCTAL 485 only supports half duplex, do it manually */
541 if (ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { 555 if (ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
542 ipoctal_write_io_reg(ipoctal, 556 ipoctal_write_io_reg(ipoctal,
543 &ipoctal->chan_regs[channel].w.cr, 557 &channel->regs->w.cr,
544 CR_DISABLE_RX); 558 CR_DISABLE_RX);
545 ipoctal_write_cr_cmd(ipoctal, 559 ipoctal_write_cr_cmd(ipoctal,
546 &ipoctal->chan_regs[channel].w.cr, 560 &channel->regs->w.cr,
547 CR_CMD_ASSERT_RTSN); 561 CR_CMD_ASSERT_RTSN);
548 } 562 }
549 563
@@ -552,40 +566,39 @@ static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel,
552 * operations 566 * operations
553 */ 567 */
554 ipoctal_write_io_reg(ipoctal, 568 ipoctal_write_io_reg(ipoctal,
555 &ipoctal->chan_regs[channel].w.cr, 569 &channel->regs->w.cr,
556 CR_ENABLE_TX); 570 CR_ENABLE_TX);
557 wait_event_interruptible(ipoctal->queue[channel], ipoctal->write); 571 wait_event_interruptible(channel->queue, ipoctal->write);
558 ipoctal_write_io_reg(ipoctal, 572 ipoctal_write_io_reg(ipoctal,
559 &ipoctal->chan_regs[channel].w.cr, 573 &channel->regs->w.cr,
560 CR_DISABLE_TX); 574 CR_DISABLE_TX);
561 575
562 ipoctal->write = 0; 576 ipoctal->write = 0;
563 return ipoctal->count_wr[channel]; 577 return channel->count_wr;
564} 578}
565 579
566static int ipoctal_write_tty(struct tty_struct *tty, 580static int ipoctal_write_tty(struct tty_struct *tty,
567 const unsigned char *buf, int count) 581 const unsigned char *buf, int count)
568{ 582{
569 unsigned int channel = tty->index;
570 struct ipoctal *ipoctal = tty->driver_data; 583 struct ipoctal *ipoctal = tty->driver_data;
571 584
572 return ipoctal_write(ipoctal, channel, buf, count); 585 return ipoctal_write(ipoctal, tty->index, buf, count);
573} 586}
574 587
575static int ipoctal_write_room(struct tty_struct *tty) 588static int ipoctal_write_room(struct tty_struct *tty)
576{ 589{
577 int channel = tty->index;
578 struct ipoctal *ipoctal = tty->driver_data; 590 struct ipoctal *ipoctal = tty->driver_data;
591 struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
579 592
580 return PAGE_SIZE - ipoctal->nb_bytes[channel]; 593 return PAGE_SIZE - channel->nb_bytes;
581} 594}
582 595
583static int ipoctal_chars_in_buffer(struct tty_struct *tty) 596static int ipoctal_chars_in_buffer(struct tty_struct *tty)
584{ 597{
585 int channel = tty->index;
586 struct ipoctal *ipoctal = tty->driver_data; 598 struct ipoctal *ipoctal = tty->driver_data;
599 struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
587 600
588 return ipoctal->nb_bytes[channel]; 601 return channel->nb_bytes;
589} 602}
590 603
591static void ipoctal_set_termios(struct tty_struct *tty, 604static void ipoctal_set_termios(struct tty_struct *tty,
@@ -595,22 +608,22 @@ static void ipoctal_set_termios(struct tty_struct *tty,
595 unsigned char mr1 = 0; 608 unsigned char mr1 = 0;
596 unsigned char mr2 = 0; 609 unsigned char mr2 = 0;
597 unsigned char csr = 0; 610 unsigned char csr = 0;
598 unsigned int channel = tty->index;
599 struct ipoctal *ipoctal = tty->driver_data; 611 struct ipoctal *ipoctal = tty->driver_data;
612 struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
600 speed_t baud; 613 speed_t baud;
601 614
602 cflag = tty->termios->c_cflag; 615 cflag = tty->termios->c_cflag;
603 616
604 /* Disable and reset everything before change the setup */ 617 /* Disable and reset everything before change the setup */
605 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, 618 ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
606 CR_DISABLE_RX | CR_DISABLE_TX); 619 CR_DISABLE_RX | CR_DISABLE_TX);
607 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, 620 ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
608 CR_CMD_RESET_RX); 621 CR_CMD_RESET_RX);
609 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, 622 ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
610 CR_CMD_RESET_TX); 623 CR_CMD_RESET_TX);
611 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, 624 ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
612 CR_CMD_RESET_ERR_STATUS); 625 CR_CMD_RESET_ERR_STATUS);
613 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, 626 ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
614 CR_CMD_RESET_MR); 627 CR_CMD_RESET_MR);
615 628
616 /* Set Bits per chars */ 629 /* Set Bits per chars */
@@ -724,45 +737,45 @@ static void ipoctal_set_termios(struct tty_struct *tty,
724 mr1 |= MR1_RxINT_RxRDY; 737 mr1 |= MR1_RxINT_RxRDY;
725 738
726 /* Write the control registers */ 739 /* Write the control registers */
727 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.mr, mr1); 740 ipoctal_write_io_reg(ipoctal, &channel->regs->w.mr, mr1);
728 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.mr, mr2); 741 ipoctal_write_io_reg(ipoctal, &channel->regs->w.mr, mr2);
729 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.csr, csr); 742 ipoctal_write_io_reg(ipoctal, &channel->regs->w.csr, csr);
730 743
731 /* Enable again the RX */ 744 /* Enable again the RX */
732 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, 745 ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
733 CR_ENABLE_RX); 746 CR_ENABLE_RX);
734} 747}
735 748
736static void ipoctal_hangup(struct tty_struct *tty) 749static void ipoctal_hangup(struct tty_struct *tty)
737{ 750{
738 unsigned long flags; 751 unsigned long flags;
739 int channel = tty->index;
740 struct ipoctal *ipoctal = tty->driver_data; 752 struct ipoctal *ipoctal = tty->driver_data;
753 struct ipoctal_channel *channel = &ipoctal->channel[tty->index];
741 754
742 if (ipoctal == NULL) 755 if (ipoctal == NULL)
743 return; 756 return;
744 757
745 spin_lock_irqsave(&ipoctal->lock[channel], flags); 758 spin_lock_irqsave(&channel->lock, flags);
746 ipoctal->nb_bytes[channel] = 0; 759 channel->nb_bytes = 0;
747 ipoctal->pointer_read[channel] = 0; 760 channel->pointer_read = 0;
748 ipoctal->pointer_write[channel] = 0; 761 channel->pointer_write = 0;
749 spin_unlock_irqrestore(&ipoctal->lock[channel], flags); 762 spin_unlock_irqrestore(&channel->lock, flags);
750 763
751 tty_port_hangup(&ipoctal->tty_port[channel]); 764 tty_port_hangup(&channel->tty_port);
752 765
753 ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].w.cr, 766 ipoctal_write_io_reg(ipoctal, &channel->regs->w.cr,
754 CR_DISABLE_RX | CR_DISABLE_TX); 767 CR_DISABLE_RX | CR_DISABLE_TX);
755 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, 768 ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
756 CR_CMD_RESET_RX); 769 CR_CMD_RESET_RX);
757 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, 770 ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
758 CR_CMD_RESET_TX); 771 CR_CMD_RESET_TX);
759 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, 772 ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
760 CR_CMD_RESET_ERR_STATUS); 773 CR_CMD_RESET_ERR_STATUS);
761 ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].w.cr, 774 ipoctal_write_cr_cmd(ipoctal, &channel->regs->w.cr,
762 CR_CMD_RESET_MR); 775 CR_CMD_RESET_MR);
763 776
764 clear_bit(ASYNCB_INITIALIZED, &ipoctal->tty_port[channel].flags); 777 clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags);
765 wake_up_interruptible(&ipoctal->tty_port[channel].open_wait); 778 wake_up_interruptible(&channel->tty_port.open_wait);
766} 779}
767 780
768static const struct tty_operations ipoctal_fops = { 781static const struct tty_operations ipoctal_fops = {
@@ -806,8 +819,9 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
806 ipoctal->dev->bus->ops->free_irq(ipoctal->dev); 819 ipoctal->dev->bus->ops->free_irq(ipoctal->dev);
807 820
808 for (i = 0; i < NR_CHANNELS; i++) { 821 for (i = 0; i < NR_CHANNELS; i++) {
822 struct ipoctal_channel *channel = &ipoctal->channel[i];
809 tty_unregister_device(ipoctal->tty_drv, i); 823 tty_unregister_device(ipoctal->tty_drv, i);
810 tty_port_free_xmit_buf(&ipoctal->tty_port[i]); 824 tty_port_free_xmit_buf(&channel->tty_port);
811 } 825 }
812 826
813 tty_unregister_driver(ipoctal->tty_drv); 827 tty_unregister_driver(ipoctal->tty_drv);