int pingpang_buffer_read(struct modem_buffer *buffer,char *data,int size) { int read_len = 0; int data_size = 0; int i; int read_point= buffer->buffer[0].read_point; if (buffer->type==BUF_RECV) { do{ if (buffer->buffer[0].write_point != buffer->buffer[0].read_point) break; down(&buffer->buf_read_sem); }while(1); data_size = buffer_data_size(&buffer->buffer[0]); if(data_size==0) return 0; if(data_size < size){ read_len = data_size; } else { read_len = size; } for (i=0;i<read_len;i++) { data[i]= buffer->buffer[0].addr[read_point++]; if(read_point >= buffer->buffer[0].size) read_point = 0; } dloader_record_timestamp(0x30000000|buffer->buffer[0].read_point); dloader_record_timestamp(0x40000000|read_point); buffer->buffer[0].read_point = read_point; up(&buffer->buf_read_sem); return read_len; } return 0; }
int save_to_receive_buffer(struct modem_buffer *buffer,char *data,int size) { int free_space = 0; int data_size = 0; int i; int write_point= buffer->buffer[0].write_point; if (buffer->type==BUF_RECV) { do{ data_size = buffer_data_size(&buffer->buffer[0]); free_space = buffer->buffer[0].size-1-data_size; if (free_space >= size) break; down(&buffer->buf_read_sem); }while(1); for(i=0;i<size;i++){ buffer->buffer[0].addr[write_point++]=data[i]; if(write_point >= buffer->buffer[0].size) write_point = 0; } buffer->buffer[0].write_point = write_point; up(&buffer->buf_read_sem); return size; } return 0; }
int pingpang_buffer_write(struct modem_buffer *buffer,char *data,int size) { int index = 0; int data_size; int free_space; int write_point; int save_flag = 0; int i; unsigned long flags; enum BUF_status_t status; if(buffer->type == BUF_SEND){ if (size >= buffer->buffer[0].size) return 0; do{ index = buffer->save_index; for(i=0;i<2;i++){ local_irq_save(flags); status = buffer->buffer[index].status; if ((status != BUF_STATUS_SENT) && (status != BUF_STATUS_FULL) && (status != BUF_STATUS_WRITTEN)) { buffer->buffer[index].status = BUF_STATUS_WRITTEN; local_irq_restore(flags); data_size = buffer_data_size(&buffer->buffer[index]); free_space = buffer->buffer[index].size -1 - data_size; if(free_space < size){ buffer->buffer[index].status = BUF_STATUS_FULL; if(buffer->trans_index == 0xFF) buffer->trans_index = index; index = 1 - index; buffer->save_index = index; } else { write_point = buffer->buffer[index].write_point; for(i=0;i<size;i++){ buffer->buffer[index].addr[write_point++]=data[i]; if(write_point >= buffer->buffer[index].size) write_point = 0; } dloader_record_timestamp(0x10000000|(index<<24)|buffer->buffer[index].write_point); dloader_record_timestamp(0x20000000|(index<<24)|write_point); buffer->buffer[index].write_point = write_point; buffer->buffer[index].status = BUF_STATUS_NOEMPTY; buffer->buffer[index].status = BUF_STATUS_FULL; if(buffer->trans_index == 0xFF) buffer->trans_index = index; save_flag = 1; } } else { local_irq_restore(flags); index = 1 - index; } } if(save_flag==0) down(&buffer->buf_write_sem); }while(save_flag == 0); } return size; }
int pingpang_buffer_read(struct modem_buffer *buffer,char __user *data,int size) { int read_len = 0; int data_size = 0; int i; int read_point= buffer->buffer[0].read_point; if (buffer->type==BUF_RECV) { do{ if (buffer->buffer[0].write_point != buffer->buffer[0].read_point) break; down(&buffer->buf_read_sem); }while(1); data_size = buffer_data_size(&buffer->buffer[0]); if(data_size==0) return 0; if(data_size < size){ read_len = data_size; } else { read_len = size; } if(copy_to_user(data,&buffer->buffer[0].addr[read_point],read_len)){ printk("copy_to_user(%d,%d,%d) failed\n",read_len,size,data_size); up(&buffer->buf_read_sem); return -EFAULT; } buffer->buffer[0].read_point = 0; buffer->buffer[0].write_point = 0; up(&buffer->buf_read_sem); return read_len; } return 0; }