/home/hillier_g/checkout/most4linux/most-kernel/most-sync-common.h

Go to the documentation of this file.
00001 /*
00002  *  Copyright(c) Siemens AG, Muenchen, Germany, 2005, 2006, 2007
00003  *                           Bernhard Walle <bernhard.walle@gmx.de>
00004  *                           Gernot Hillier <gernot.hillier@siemens.com>
00005  *
00006  * ----------------------------------------------------------------------------
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License version 2 as 
00009  * published by the Free Software Foundation;
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  * ----------------------------------------------------------------------------
00020  */
00021 #ifndef MOST_SYNC_COMMON_H
00022 #define MOST_SYNC_COMMON_H
00023 
00043 #ifdef HAVE_CONFIG_H
00044 #include "config/config.h"
00045 #endif
00046 #include "most-constants.h"
00047 #include "most-base.h"
00048 
00049 struct most_sync_file;
00050 
00051 
00057 static inline void most_sync_set_sbc_reg(struct most_dev *dev)
00058 {
00059     unsigned char buf;
00060 
00061     /* locking is not needed because this register doesn't change very often */
00062     most_readreg8104(dev, &buf, 1, MOST_8104_SBC_REG);
00063     most_changereg(dev, MOST_PCI_SBC_NPOS_REG, buf - 1, 0xf);
00064 }
00065 
00091 #define most_sync_setup_rx_common(param, file, sync_dev, hw_buffer_size,     \
00092                                   sw_buffer_size, error_var,                 \
00093                                   most_sync_file_name)                       \
00094     do {                                                                     \
00095         struct most_sync_file_name  *entry;                                  \
00096         int                         number_quadlets;                         \
00097         unsigned int                dma_size;                                \
00098         int                         reader_count = 0;                        \
00099         unsigned int                max_byte     = 0;                        \
00100         struct list_head            *ptr;                                    \
00101                                                                              \
00102         /* enable the interrupt */                                           \
00103         most_intset(sync_dev->most_dev, IESRX, IESRX, NULL);                 \
00104                                                                              \
00105         /* set the state of this device to running */                        \
00106         file->rx_running = true;                                             \
00107         file->part_rx = param;                                               \
00108                                                                              \
00109         /* get the total number of quadlets */                               \
00110         max_byte = 0;                                                        \
00111         list_for_each(ptr, &sync_dev->file_list) {                           \
00112             entry = list_entry(ptr, struct most_sync_file_name, list);       \
00113                                                                              \
00114             if (entry->rx_running) {                                         \
00115                 unsigned int last_byte;                                      \
00116                                                                              \
00117                 entry->reader_index = reader_count++;                        \
00118                                                                              \
00119                 last_byte = entry->part_rx.count + entry->part_rx.offset - 1;\
00120                 if (last_byte > max_byte) {                                  \
00121                     max_byte = last_byte;                                    \
00122                 }                                                            \
00123             }                                                                \
00124         }                                                                    \
00125         number_quadlets = (max_byte + 3) / 4; /* integer ceil */             \
00126                                                                              \
00127         /* adjust the number of quadlets */                                  \
00128         most_writereg(sync_dev->most_dev, number_quadlets - 1,               \
00129                 MOST_PCI_SRXCA_REG);                                         \
00130         pr_sync_debug(PR "Setting number of qualdets to %d\n",               \
00131                 number_quadlets);                                            \
00132         most_sync_set_sbc_reg(sync_dev->most_dev);                           \
00133                                                                              \
00134         /* set the page size */                                              \
00135         dma_size = number_quadlets * 4 * 2 * hw_buffer_size;                 \
00136                                                                              \
00137         most_writereg(sync_dev->most_dev, dma_size / 2, MOST_PCI_SRXPS_REG); \
00138         pr_sync_debug(PR "Setting receive page size to %d\n",                \
00139                 dma_size/2);                                                 \
00140                                                                              \
00141         /* allocate the DMA buffer if needed */                              \
00142         if (dma_size > sync_dev->hw_receive_buf.size) {                      \
00143             if (sync_dev->hw_receive_buf.size != 0) {                        \
00144                 most_dma_deallocate(sync_dev->most_dev,                      \
00145                         &sync_dev->hw_receive_buf);                          \
00146             }                                                                \
00147                                                                              \
00148             sync_dev->hw_receive_buf.size = dma_size;                        \
00149             error_var = most_dma_allocate(sync_dev->most_dev,                \
00150                     &sync_dev->hw_receive_buf);                              \
00151             if (error_var < 0) {                                             \
00152                 sync_dev->hw_receive_buf.size = 0;                           \
00153                 rtnrt_err(PR "most_dma_allocate failed");                    \
00154                 goto out;                                                    \
00155             }                                                                \
00156         }                                                                    \
00157         pr_sync_debug(PR "Allocated DMA buffer with size %d "                \
00158                 "(Bus: 0x%x)\n", sync_dev->hw_receive_buf.size,              \
00159                 sync_dev->hw_receive_buf.addr_bus);                          \
00160         pr_measure_debug(PR "==> DMA Buffer RX 0x%X-0x%X <==\n",             \
00161                 sync_dev->hw_receive_buf.addr_bus,                           \
00162                 sync_dev->hw_receive_buf.addr_bus +                          \
00163                 sync_dev->hw_receive_buf.size);                              \
00164                                                                              \
00165         memset(sync_dev->hw_receive_buf.addr_virt,                           \
00166                 sync_dev->hw_receive_buf.size, 0);                           \
00167                                                                              \
00168         /* set the hardware start address */                                 \
00169         most_writereg(sync_dev->most_dev, sync_dev->hw_receive_buf.addr_bus, \
00170                      MOST_PCI_SRXSA_REG);                                    \
00171                                                                              \
00172         /* free the old ringbuffer */                                        \
00173         if (sync_dev->sw_receive_buf) {                                      \
00174             rxbuf_free(sync_dev->sw_receive_buf);                            \
00175             sync_dev->sw_receive_buf = NULL;                                 \
00176         }                                                                    \
00177                                                                              \
00178         /* allocate ring buffer */                                           \
00179         sync_dev->sw_receive_buf = rxbuf_alloc(reader_count, sw_buffer_size, \
00180                                                number_quadlets * 4);         \
00181         if (unlikely(!sync_dev->sw_receive_buf)) {                           \
00182             rtnrt_err(PR "Not enough memory available\n");                   \
00183             error_var = -ENOMEM;                                             \
00184             goto out;                                                        \
00185         }                                                                    \
00186                                                                              \
00187         /*                                                                   \
00188          * ensure that no reordering takes place between setting the         \
00189          * start bit and configuration bits                                  \
00190          */                                                                  \
00191         wmb();                                                               \
00192                                                                              \
00193         most_changereg(sync_dev->most_dev, MOST_PCI_SRXCTRL_REG,             \
00194                 SRXST, SRXST);                                               \
00195         atomic_inc(&sync_dev->receiver_count);                               \
00196         break;                                                               \
00197                                                                              \
00198 out:                                                                         \
00199         /* release the lock for the sync device */                           \
00200         file->rx_running = false;                                            \
00201                                                                              \
00202     } while (0)
00203 
00227 #define most_sync_setup_tx_common(param, file, sync_dev, hw_buffer_size,     \
00228                                   sw_buffer_size, error_var,                 \
00229                                   most_sync_file_name)                       \
00230     do {                                                                     \
00231         struct most_sync_file_name *entry;                                   \
00232         int                        number_quadlets;                          \
00233         unsigned int               dma_size;                                 \
00234         int                        writer_count = 0;                         \
00235         unsigned int               max_byte     = 0;                         \
00236         struct list_head           *ptr;                                     \
00237                                                                              \
00238         /* enable the interrupt */                                           \
00239         most_intset(sync_dev->most_dev, IESTX, IESTX, NULL);                 \
00240                                                                              \
00241         /* set the state of this device to running */                        \
00242         file->tx_running = true;                                             \
00243         file->part_tx = param;                                               \
00244                                                                              \
00245         /* get the total number of quadlets */                               \
00246         max_byte = 0;                                                        \
00247         list_for_each(ptr, &sync_dev->file_list) {                           \
00248             entry = list_entry(ptr, struct most_sync_file_name, list);       \
00249                                                                              \
00250             if (entry->tx_running) {                                         \
00251                 unsigned int last_byte;                                      \
00252                                                                              \
00253                 entry->writer_index = writer_count++;                        \
00254                                                                              \
00255                 last_byte = entry->part_tx.count + entry->part_tx.offset - 1;\
00256                 if (last_byte > max_byte) {                                  \
00257                     max_byte = last_byte;                                    \
00258                 }                                                            \
00259             }                                                                \
00260         }                                                                    \
00261         number_quadlets = (max_byte + 3) / 4; /* integer ceil */             \
00262                                                                              \
00263         /* adjust the number of quadlets */                                  \
00264         most_writereg(sync_dev->most_dev, number_quadlets - 1,               \
00265                 MOST_PCI_STXCA_REG);                                         \
00266         pr_sync_debug(PR "Setting number of qualdets to %d\n",               \
00267                 number_quadlets);                                            \
00268         most_sync_set_sbc_reg(sync_dev->most_dev);                           \
00269                                                                              \
00270         /* set the page size */                                              \
00271         dma_size = number_quadlets * 4 * 2 * hw_buffer_size;                 \
00272                                                                              \
00273         most_writereg(sync_dev->most_dev, dma_size / 2, MOST_PCI_STXPS_REG); \
00274         pr_sync_debug(PR "Setting transmit page size to %d\n",               \
00275                 dma_size/2);                                                 \
00276                                                                              \
00277         /* allocate the DMA buffer if needed */                              \
00278         if (dma_size > sync_dev->hw_transmit_buf.size) {                     \
00279             if (sync_dev->hw_transmit_buf.size != 0) {                       \
00280                 most_dma_deallocate(sync_dev->most_dev,                      \
00281                         &sync_dev->hw_transmit_buf);                         \
00282             }                                                                \
00283                                                                              \
00284             sync_dev->hw_transmit_buf.size = dma_size;                       \
00285             error_var = most_dma_allocate(sync_dev->most_dev,                \
00286                     &sync_dev->hw_transmit_buf);                             \
00287             if (error_var < 0) {                                             \
00288                 sync_dev->hw_transmit_buf.size = 0;                          \
00289                 rtnrt_err(PR "most_dma_allocate failed");                    \
00290                 goto out;                                                    \
00291             }                                                                \
00292         }                                                                    \
00293         pr_sync_debug(PR "Allocated DMA buffer with size %d (Bus: 0x%x)\n",  \
00294                 sync_dev->hw_transmit_buf.size,                              \
00295                 sync_dev->hw_receive_buf.addr_bus);                          \
00296         pr_measure_debug(PR "==> DMA Buffer TX 0x%X-0x%X <==\n",             \
00297                 sync_dev->hw_transmit_buf.addr_bus,                          \
00298                 sync_dev->hw_transmit_buf.addr_bus +                         \
00299                 sync_dev->hw_transmit_buf.size);                             \
00300                                                                              \
00301         memset(sync_dev->hw_transmit_buf.addr_virt,                          \
00302                 sync_dev->hw_transmit_buf.size, 0);                          \
00303                                                                              \
00304         /* set the hardware start address */                                 \
00305         most_writereg(sync_dev->most_dev, sync_dev->hw_transmit_buf.addr_bus,\
00306                       MOST_PCI_STXSA_REG);                                   \
00307                                                                              \
00308         /* free the old ringbuffer */                                        \
00309         if (sync_dev->sw_transmit_buf) {                                     \
00310             txbuf_free(sync_dev->sw_transmit_buf);                           \
00311             sync_dev->sw_transmit_buf = NULL;                                \
00312         }                                                                    \
00313                                                                              \
00314         /* allocate ring buffer */                                           \
00315         sync_dev->sw_transmit_buf = txbuf_alloc(writer_count, sw_buffer_size,\
00316                                                 number_quadlets * 4);        \
00317         if (unlikely(!sync_dev->sw_transmit_buf)) {                          \
00318             rtnrt_err(PR "Not enough memory available\n");                   \
00319             error_var = -ENOMEM;                                             \
00320             goto out;                                                        \
00321         }                                                                    \
00322                                                                              \
00323         /*                                                                   \
00324          * ensure that no reordering takes place between setting the         \
00325          * start bit and configuration bits                                  \
00326          */                                                                  \
00327         wmb();                                                               \
00328                                                                              \
00329         most_changereg(sync_dev->most_dev, MOST_PCI_STXCTRL_REG,             \
00330                 STXST, STXST);                                               \
00331         atomic_inc(&sync_dev->transmitter_count);                            \
00332                                                                              \
00333         break;                                                               \
00334                                                                              \
00335 out:                                                                         \
00336         /* release the lock for the sync device */                           \
00337         file->tx_running = false;                                            \
00338                                                                              \
00339     } while (0)
00340 
00349 #define most_sync_stop_rx_common(sync_dev, file)                              \
00350     do {                                                                      \
00351         most_intset(sync_dev->most_dev, 0, IESRX, NULL);                      \
00352         most_changereg(sync_dev->most_dev, MOST_PCI_SRXCTRL_REG, 0, SRXST);   \
00353         most_intclear(sync_dev->most_dev, ISSRX);                             \
00354                                                                               \
00355         file->rx_running = false;                                             \
00356     } while (0)
00357 
00366 #define most_sync_stop_tx_common(sync_dev, file)                              \
00367     do {                                                                      \
00368         most_intset(sync_dev->most_dev, 0, IESTX, NULL);                      \
00369         most_changereg(sync_dev->most_dev, MOST_PCI_STXCTRL_REG, 0, STXST);   \
00370         most_intclear(sync_dev->most_dev, ISSTX);                             \
00371                                                                               \
00372         file->tx_running = false;                                             \
00373     } while (0)
00374 
00384 #define most_sync_last_closed_rx(sync_dev, file, stop_rx)                     \
00385     do {                                                                      \
00386         sync_dev->rx_current_page = 0;                                        \
00387                                                                               \
00388         stop_rx(file);                                                        \
00389         rxbuf_free(sync_dev->sw_receive_buf);                                 \
00390                                                                               \
00391         /* free the DMA buffers */                                            \
00392         if (sync_dev->hw_receive_buf.size != 0) {                             \
00393             most_dma_deallocate(sync_dev->most_dev,                           \
00394                     &sync_dev->hw_receive_buf);                               \
00395         }                                                                     \
00396                                                                               \
00397         /* mark all as deallocated */                                         \
00398         sync_dev->sw_receive_buf = NULL;                                      \
00399         sync_dev->hw_receive_buf.size = 0;                                    \
00400     } while (0)
00401 
00411 #define most_sync_last_closed_tx(sync_dev, file, stop_tx)                     \
00412     do {                                                                      \
00413         sync_dev->tx_current_page = 0;                                        \
00414                                                                               \
00415         stop_tx(file);                                                        \
00416         txbuf_free(sync_dev->sw_transmit_buf);                                \
00417                                                                               \
00418         /* free the DMA buffer */                                             \
00419         if (sync_dev->hw_transmit_buf.size != 0) {                            \
00420             most_dma_deallocate(sync_dev->most_dev,                           \
00421                     &sync_dev->hw_transmit_buf);                              \
00422         }                                                                     \
00423                                                                               \
00424         /* mark as deallocated */                                             \
00425         sync_dev->sw_transmit_buf = NULL;                                     \
00426         sync_dev->hw_transmit_buf.size = 0;                                   \
00427     } while (0)
00428 
00429 
00434 extern long sw_rx_buffer_size;
00435 
00440 extern long sw_tx_buffer_size;
00441 
00446 extern long hw_rx_buffer_size;
00447 
00452 extern long hw_tx_buffer_size;
00453 
00454 #endif /* MOST_SYNC_COMMON_H */
00455 
00456 /* vim: set sw=4 ts=4 et: */

Generated on Fri Mar 9 14:48:58 2007 for MOST Linux Drivers (Linux and RTAI) by  doxygen 1.5.0