8
#include <libpsio/psio.h>
9
#include <libpsio/psio.hpp>
13
void PSIO::rw(unsigned int unit, char *buffer, psio_address address, ULI size,
20
ULI this_page, this_page_max, this_page_total;
21
unsigned int first_vol, this_vol, numvols;
22
ULI bytes_left, num_full_pages;
25
this_unit = &(psio_unit[unit]);
26
numvols = this_unit->numvols;
28
offset = address.offset;
30
/* Seek all volumes to correct starting positions */
31
first_vol = page % numvols;
32
errcod = psio_volseek(&(this_unit->vol[first_vol]), page, offset, numvols);
34
psio_error(unit, PSIO_ERROR_LSEEK);
35
for (i=1, this_page=page+1; i < numvols; i++, this_page++) {
36
this_vol = this_page % numvols;
37
errcod = psio_volseek(&(this_unit->vol[this_vol]), this_page, (ULI) 0,
40
psio_error(unit, PSIO_ERROR_LSEEK);
43
/* Number of bytes left on the first page */
44
this_page_max = PSIO_PAGELEN - offset;
46
/* If we have enough room on this page, use it */
47
if (size <= this_page_max)
48
this_page_total = size;
50
this_page_total = this_page_max;
54
errcod_uli =:: write(this_unit->vol[first_vol].stream, &(buffer[buf_offset]),
56
if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_WRITE);
59
errcod_uli = ::read(this_unit->vol[first_vol].stream, &(buffer[buf_offset]),
61
if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_READ);
64
/* Total number of bytes remaining to be read/written */
65
bytes_left = size - this_page_total;
67
/* Read/Write all the full pages */
68
num_full_pages = bytes_left/PSIO_PAGELEN;
69
buf_offset += this_page_total;
70
for(i=0,this_page=page+1; i < num_full_pages; i++,this_page++) {
71
this_vol = this_page % numvols;
72
this_page_total = PSIO_PAGELEN;
74
errcod_uli = ::write(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
76
if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_WRITE);
79
errcod_uli = ::read(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
81
if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_READ);
83
buf_offset += this_page_total;
86
/* Read/Write the final partial page */
87
bytes_left -= num_full_pages * PSIO_PAGELEN;
88
this_vol = this_page % numvols;
91
errcod_uli = ::write(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
93
if(errcod_uli != bytes_left) psio_error(unit,PSIO_ERROR_WRITE);
96
errcod_uli = ::read(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
98
if(errcod_uli != bytes_left) psio_error(unit,PSIO_ERROR_READ);
105
** PSIO_RW(): Central function for all reads and writes on a PSIO unit.
107
** \params unit = The PSI unit number.
108
** \params buffer = The buffer containing the bytes for the read/write event.
109
** \params address = the PSIO global address for the start of the read/write.
110
** \params size = The number of bytes to read/write.
111
** \params = Indicates if the call is to read (0) or write (0) the input data.
115
int psio_rw(unsigned int unit, char *buffer, psio_address address, ULI size,
117
_default_psio_lib_->rw(unit, buffer, address, size, wrt);