📄 devsw.c
字号:
* Params: * In/Out: ds State structure with new packet * * Returns: Nothing */static void enqueue_packet(DevSWState *ds){ struct data_packet *dp = &ds->ds_activeread.dc_packet; Packet *packet = ds->ds_nextreadpacket; /* * transfer the length */ packet->pk_length = dp->len; /* * take this packet out of the incoming slot */ ds->ds_nextreadpacket = NULL; /* * try to put it on the correct input queue */ if (illegalDevChanID(dp->type)) { /* this shouldn't happen */ WARN("Illegal type for Rx packet"); DevSW_FreePacket(packet); } else Adp_addToQueue(&ds->ds_readqueue[dp->type], packet);}/* * Function: flush_packet * Purpose: Send a packet to the device driver * * Params: * Input: device The device to be written to * * In/Out: dc Describes the packet to be sent * * Returns: Nothing * * Post-conditions: If the whole packet was accepted by the device * driver, then dc->dc_packet.data will be * set to NULL. */static void flush_packet(const DeviceDescr *device, DriverCall *dc){ if (device->DeviceWrite(dc) > 0) /* * the whole packet was swallowed */ dc->dc_packet.data = NULL;}/**********************************************************************//* * These are the externally visible functions. They are documented in * devsw.h */Packet *DevSW_AllocatePacket(const unsigned int length){ Packet *pk; if ((pk = malloc(sizeof(*pk))) == NULL) { WARN("malloc failure"); return NULL; } if ((pk->pk_buffer = malloc(length+CHAN_HEADER_SIZE)) == NULL) { WARN("malloc failure"); free(pk); return NULL; } return pk;}void DevSW_FreePacket(Packet *pk){ free(pk->pk_buffer); free(pk);}AdpErrs DevSW_Open(DeviceDescr *device, const char *name, const char *arg, const DevChanID type){ DevSWState *ds; /* * is this the very first open call for this driver? */ if ((ds = (DevSWState *)(device->SwitcherState)) == NULL) { /* * yes, it is: initialise state */ if ((ds = malloc(sizeof(*ds))) == NULL) /* give up */ return adp_malloc_failure; (void)memset(ds, 0, sizeof(*ds)); device->SwitcherState = (void *)ds; } /* * check that we haven't already been opened for this type */ if ((ds->ds_opendevchans & (1 << type)) != 0) return adp_device_already_open; /* * if no opens have been done for this device, then do it now */ if (ds->ds_opendevchans == 0) if (device->DeviceOpen(name, arg) < 0) return adp_device_open_failed; /* * open has finished */ ds->ds_opendevchans |= (1 << type); return adp_ok;}AdpErrs DevSW_Match(const DeviceDescr *device, const char *name, const char *arg){ return (device->DeviceMatch(name, arg) == -1) ? adp_failed : adp_ok;}AdpErrs DevSW_Close (DeviceDescr *device, const DevChanID type){ DevSWState *ds = (DevSWState *)(device->SwitcherState); Packet *pk; if ((ds->ds_opendevchans & (1 << type)) == 0) return adp_device_not_open; ds->ds_opendevchans &= ~(1 << type); /* * if this is the last close for this channel, then inform the driver */ if (ds->ds_opendevchans == 0) device->DeviceClose(); /* * release all packets of the appropriate type */ for (pk = Adp_removeFromQueue(&(ds->ds_readqueue[type])); pk != NULL; pk = Adp_removeFromQueue(&(ds->ds_readqueue[type]))) DevSW_FreePacket(pk); /* Free memory */ free ((char *) device->SwitcherState); device->SwitcherState = 0x0; /* that's all */ return adp_ok;}AdpErrs DevSW_Read(const DeviceDescr *device, const DevChanID type, Packet **packet, bool block){ int read_err; DevSWState *ds = device->SwitcherState; /* * To try to get information out of the device driver as * quickly as possible, we try and read more packets, even * if a completed packet is already available. */ /* * have we got a packet currently pending? */ if (ds->ds_nextreadpacket == NULL) /* * no - set things up */ if (initialise_read(ds) < 0) { /* * we failed to initialise the next packet, but can * still return a packet that has already arrived. */ *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]); return adp_ok; } read_err = device->DeviceRead(&ds->ds_activeread, block); switch (read_err) { case 1: /* * driver has pulled in a complete packet, queue it up */#ifdef RET_DEBUG printf("got a complete packet\n");#endif if (angelDebugLogEnable) dumpPacket(angelDebugLogFile,"rx:",&ds->ds_activeread.dc_packet); enqueue_packet(ds); *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]); return adp_ok; case 0: /* * OK, return the head of the read queue for the given type */ /* enqueue_packet(ds); */ *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]); return adp_ok; case -1:#ifdef RET_DEBUG printf("got a bad packet\n");#endif /* bad packet */ *packet = NULL; return adp_bad_packet; default: panic("DevSW_Read: bad read status %d", read_err); } return 0; /* get rid of a potential compiler warning */}AdpErrs DevSW_FlushPendingWrite(const DeviceDescr *device){ struct DriverCall *dc; struct data_packet *dp; dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite; dp = &dc->dc_packet; /* * try to flush any packet that is still being written */ if (dp->data != NULL) { flush_packet(device, dc); /* see if it has gone */ if (dp->data != NULL) return adp_write_busy; else return adp_ok; } else return adp_ok;}AdpErrs DevSW_Write(const DeviceDescr *device, Packet *packet, DevChanID type){ struct DriverCall *dc; struct data_packet *dp; dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite; dp = &dc->dc_packet; if (illegalDevChanID(type)) return adp_illegal_args; /* * try to flush any packet that is still being written */ if (DevSW_FlushPendingWrite(device) != adp_ok) return adp_write_busy; /* * we can take this packet - set things up, then try to get rid of it */ initialise_write(dc, packet, type); if (angelDebugLogEnable) dumpPacket(angelDebugLogFile,"tx:",&dc->dc_packet); flush_packet(device, dc); return adp_ok;}AdpErrs DevSW_Ioctl(const DeviceDescr *device, const int opcode, void *args){ return (device->DeviceIoctl(opcode, args) < 0) ? adp_failed : adp_ok;}bool DevSW_WriteFinished(const DeviceDescr *device){ struct DriverCall *dc; struct data_packet *dp; dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite; dp = &dc->dc_packet; return (dp == NULL || dp->data == NULL);}/* EOF devsw.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -