⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpcsend.c

📁 PNX系列设备驱动 PNX系列设备驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
                goto standard_RESULT_BUFF_DEF;


        case HostCall_OPENDIR:

                XFER_DATA(
                    (Pointer)command->parameters.opendir_args.path,
                      strlen(command->parameters.opendir_args.path) + 1
                );
                goto standard_RESULT_BUFF_DEF;

           /* -------------------------------------------- */

        case HostCall_READDIR:
                shadow_command=
                      RESULT_BUFF_DEF(
                          command,
                          sizeof(struct _TCS_DIR),
                          (Address)&command->parameters.readdir_args.retval,
                          True
                      );
                break;

           /* -------------------------------------------- */
#ifndef SERIAL_RPC

        case HostCall_SELECT:
           if (command->parameters.select_args.read != NULL)
              XFER_DATA
              (
                 command->parameters.select_args.read,
                 sizeof *command->parameters.select_args.read
              );

           if (command->parameters.select_args.write != NULL)
              XFER_DATA
              (
                 command->parameters.select_args.write,
                 sizeof *command->parameters.select_args.write
              );

           if (command->parameters.select_args.except != NULL)
              XFER_DATA
              (
                 command->parameters.select_args.except,
                 sizeof *command->parameters.select_args.except
              );

           if (command->parameters.select_args.timeout != NULL)
              XFER_DATA
              (
                 command->parameters.select_args.timeout,
                 sizeof *command->parameters.select_args.timeout
              );

           /*Invent a buffer big enough to hold all the data. We'll munge lots
              of pointers back later.*/
           shadow_command =
                 RESULT_BUFF_DEF
                 (
                    command,
                    sizeof *command->parameters.select_args.retbuf,
                    (Address) &command->parameters.select_args.retbuf,
                    True
                 );
        break;

        case HostCall_GETHOSTBYADDR_R:
           XFER_DATA
           (
              command->parameters.gethostbyaddr_r_args.addr,
              command->parameters.gethostbyaddr_r_args.length
           );

           /*Invent a buffer big enough to hold all the data. We'll munge lots
              of pointers back later.*/
           shadow_command =
                 RESULT_BUFF_DEF
                 (
                    command,
                    LOFFSETOF_VAR (*command->parameters.gethostbyaddr_r_args.retbuf,
                          buffer) + command->parameters.gethostbyaddr_r_args.buflen,
                    (Address) &command->parameters.gethostbyaddr_r_args.retbuf,
                    True
                 );
        break;

        case HostCall_GETHOSTBYNAME_R:
           XFER_DATA
           (
              command->parameters.gethostbyname_r_args.name,
              strlen (command->parameters.gethostbyname_r_args.name) + 1
           );

           /*Invent a buffer big enough to hold all the data. We'll munge lots
              of pointers back later.*/
           shadow_command =
                 RESULT_BUFF_DEF
                 (
                    command,
                    LOFFSETOF_VAR (*command->parameters.gethostbyname_r_args.retbuf,
                          buffer) +
                          command->parameters.gethostbyname_r_args.buflen,
                    (Address) &command->parameters.gethostbyname_r_args.retbuf,
                    True
                 );
        break;

        case HostCall_GETHOSTNAME:
           shadow_command =
                 RESULT_BUFF_DEF
                 (
                    command,
                    command->parameters.gethostname_args.namelen,
                    (Address) &command->parameters.gethostname_args.name,
                    True
                 );
        break;

        case HostCall_GETPROTOBYNAME:
           XFER_DATA
           (
              command->parameters.getprotobyname_args.name,
              strlen (command->parameters.getprotobyname_args.name) + 1
           );

           shadow_command =
                 RESULT_BUFF_DEF
                 (
                    command,
                    sizeof *command->parameters.getprotobyname_args.retval,
                    (Address) &command->parameters.getprotobyname_args.retval,
                    True
                 );
        break;

        case HostCall_GETSOCKNAME:
           XFER_DATA
           (
              command->parameters.getsockname_args.namelen,
              sizeof *command->parameters.getsockname_args.namelen
           );

           shadow_command =
                 RESULT_BUFF_DEF
                 (
                    command,
                    sizeof *command->parameters.getsockname_args.name,
                    (Address) &command->parameters.getsockname_args.name,
                    True
                 );
        break;

        case HostCall_IOCTLSOCKET:
           switch (command->parameters.ioctlsocket_args.cmd)
           {
              case TCS_FIONBIO:
                 XFER_DATA
                 (
                    command->parameters.ioctlsocket_args.arg,
                    sizeof (int)
                 );
              goto standard_RESULT_BUFF_DEF;

              case TCS_FIONREAD:
                 shadow_command =
                       RESULT_BUFF_DEF
                       (
                          command,
                          sizeof (int),
                          (Address) &command->parameters.ioctlsocket_args.arg,
                          True
                       );
              break;

              default:
                 assert (0);
              break;
           }
        break;

        case HostCall_SETSOCKOPT:
           XFER_DATA
           (
              command->parameters.setsockopt_args.optval,
              command->parameters.setsockopt_args.optlen
           );
        goto standard_RESULT_BUFF_DEF;
#endif /* SERIAL_RPC */
           /* -------------------------------------------- */

        case HostCall_READ:

#ifdef SERIAL_RPC
                    shadow_command=
                          RESULT_BUFF_DEF(
                              command,
                              command->parameters.read_args.nbyte,
                              (Address)&command->parameters.read_args.buf,
                              False
                          );
                    break; /* ------- EXIT ------->>> */
#else
               /*
                * Reading file buffers has a special treatment for large
                * buffers to avoid the necessity of target copying of the
                * obtained data; small buffers (i.e. smaller than a hardcoded
                * threshold) will be obtained in copying mode, by letting
                * function `RESULT_BUFF_DEF` allocate a cache- aligned buffer
                * whose contents is to be copied to the user buffer after
                * completion.
                * Large buffers, in contrary, are split into three parts:
                * a (possibly empty) header which occupies a strict fragment
                * of a chache page, a similar trailer, and the main body
                * which then fully occupies an integral amount of cache pages.
                * For each of these parts (when not empty) a separate host
                * read request will be given.
                * For the trailer and the header we cannot do better than
                * read them in copying mode; however, the host can be given
                * direct access to the body, which prevents the need for
                * copying to the user buffer by the TM-1.
                * The three- phase reading is performed by a state machine,
                * in which the state is maintained in the original command
                * buffer, and which is further animated by the termination
                * handler (see above). The state consists of the local
                * function codes READ_PHASE_<i>, which are not visible at
                * the host, the value of 'command->parameters.read_args.nbyte',
                * which is accumulated by the termination handler, and the
                * start and size of the remaining buffer to be read.
                */

                if (command->parameters.read_args.nbyte < READ_DMA_THRESHOLD) {
                    shadow_command=
                          RESULT_BUFF_DEF(
                              command,
                              command->parameters.read_args.nbyte,
                              (Address)&command->parameters.read_args.buf,
                              True
                          );
                    break; /* ------- EXIT ------->>> */
                }

               /*
                * READ_PHASE_1: the first part of the read buffer,
                *               up to the next cache boundary will
                *               be obtained in copying mode.
                */

                command->parameters.read_args.retval= 0;

		next_chunk_start= (Address)TM1_DCACHE_PAGE_ALIGN 
					 (command->parameters.read_args.buf);
		chunk_len= (Address)next_chunk_start - (Address) command->parameters.read_args.buf;

                if (chunk_len > 0) {

                    command->code = HostCall_READ;
                    nbyte         = chunk_len;
                    LSWAP( nbyte, command->parameters.read_args.nbyte,  Int32 )

                    shadow_command=
                          RESULT_BUFF_DEF(
                              command,
                              chunk_len,
                              (Address)&command->parameters.read_args.buf,
                              True
                          );

                    /* *DON'T* touch shadow_command here;
                     * it should remain cache- flushed
                     */
                    LSWAP( nbyte, command->parameters.read_args.nbyte,  Int32 )

                    command->code= READ_PHASE_1;

                    break; /* ------- EXIT ------->>> */
                }


        case READ_PHASE_1:

               /*
                * READ_PHASE_2: the 'middle' part of the read buffer,
                *               which is the largest chunk occupying
                *               entire cache pages, will be read in
                *               dma mode (by this we mean that the host
                *               writes directly in the user- allocated
                *               buffer). We do a copyback, to preserve all
                *               data which is not touched by the read.
                */

                next_chunk_start= TM1_DCACHE_PAGE_TRUNC(
                                      (char *) command->parameters.read_args.buf
                                      + command->parameters.read_args.nbyte
                                  );
		chunk_len= (Address) next_chunk_start - (Address) command->parameters.read_args.buf;

                if (chunk_len > 0) {

                    command->code = HostCall_READ;
                    nbyte         = chunk_len;
                    LSWAP( nbyte, command->parameters.read_args.nbyte,  Int32 )

                    _cache_copyback (
                          command->parameters.read_args.buf,
                          chunk_len
                    );

                    shadow_command=
                          RESULT_BUFF_DEF(
                              command,
                              0, Null,
                              False
                          );

                    /* *DON'T* touch shadow_command here;
                     * it should remain cache- flushed
                     */
                    LSWAP( nbyte, command->parameters.read_args.nbyte,  Int32 )

                    command->code= READ_PHASE_2;

                    break; /* ------- EXIT ------->>> */
                }


        case READ_PHASE_2:

               /*
                * READ_PHASE_3: the last part of the read buffer,
                *               will again be obtained in copying mode.
                */
                chunk_len= command->parameters.read_args.nbyte;

                if (chunk_len > 0) {
                    command->code= HostCall_READ;

                    shadow_command=
                          RESULT_BUFF_DEF(
                              command,
                              command->parameters.read_args.nbyte,
                              (Address)&command->parameters.read_args.buf,
                              True
                          );

                    /* *DON'T* touch shadow_command here;
                     * it should remain cache- flushed
                     */

                    command->code= READ_PHASE_3;

                    break; /* ------- EXIT ------->>> */
                }

                shadow_command               = Null;
                command->status              = HostCall_DONE;
                command->termination_handler = Null;

        break;
#endif /* SERIAL_RPC */

        default:
                shadow_command  = Null;
                command->status = HostCall_ERROR;
        break;
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -