Change at driver to understand 'safe' transfers and ioctls; do corresponding
safe copy and safe sys_insw and sys_outsw calls.
This commit is contained in:
		
							parent
							
								
									e929676268
								
							
						
					
					
						commit
						3bd3c2cee1
					
				@ -347,15 +347,15 @@ FORWARD _PROTOTYPE( char *w_name, (void) 				);
 | 
				
			|||||||
FORWARD _PROTOTYPE( int w_specify, (void) 				);
 | 
					FORWARD _PROTOTYPE( int w_specify, (void) 				);
 | 
				
			||||||
FORWARD _PROTOTYPE( int w_io_test, (void) 				);
 | 
					FORWARD _PROTOTYPE( int w_io_test, (void) 				);
 | 
				
			||||||
FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, off_t position,
 | 
					FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, off_t position,
 | 
				
			||||||
					iovec_t *iov, unsigned nr_req) 	);
 | 
									iovec_t *iov, unsigned nr_req, int safe));
 | 
				
			||||||
FORWARD _PROTOTYPE( int com_out, (struct command *cmd) 			);
 | 
					FORWARD _PROTOTYPE( int com_out, (struct command *cmd) 			);
 | 
				
			||||||
FORWARD _PROTOTYPE( int com_out_ext, (struct command *cmd)		);
 | 
					FORWARD _PROTOTYPE( int com_out_ext, (struct command *cmd)		);
 | 
				
			||||||
FORWARD _PROTOTYPE( void setup_dma, (unsigned *sizep, int proc_nr,
 | 
					FORWARD _PROTOTYPE( void setup_dma, (unsigned *sizep, int proc_nr,
 | 
				
			||||||
			iovec_t *iov, int do_write, int *do_copyoutp)	);
 | 
							iovec_t *iov, int do_write, int *do_copyoutp, int safe)	);
 | 
				
			||||||
FORWARD _PROTOTYPE( void w_need_reset, (void) 				);
 | 
					FORWARD _PROTOTYPE( void w_need_reset, (void) 				);
 | 
				
			||||||
FORWARD _PROTOTYPE( void ack_irqs, (unsigned int) 			);
 | 
					FORWARD _PROTOTYPE( void ack_irqs, (unsigned int) 			);
 | 
				
			||||||
FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) );
 | 
					FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) );
 | 
				
			||||||
FORWARD _PROTOTYPE( int w_other, (struct driver *dp, message *m_ptr) 	);
 | 
					FORWARD _PROTOTYPE( int w_other, (struct driver *dp, message *m_ptr, int));
 | 
				
			||||||
FORWARD _PROTOTYPE( int w_hw_int, (struct driver *dp, message *m_ptr) 	);
 | 
					FORWARD _PROTOTYPE( int w_hw_int, (struct driver *dp, message *m_ptr) 	);
 | 
				
			||||||
FORWARD _PROTOTYPE( int com_simple, (struct command *cmd) 		);
 | 
					FORWARD _PROTOTYPE( int com_simple, (struct command *cmd) 		);
 | 
				
			||||||
FORWARD _PROTOTYPE( void w_timeout, (void) 				);
 | 
					FORWARD _PROTOTYPE( void w_timeout, (void) 				);
 | 
				
			||||||
@ -371,7 +371,7 @@ FORWARD _PROTOTYPE( int atapi_intr_wait, (void) 			);
 | 
				
			|||||||
FORWARD _PROTOTYPE( int atapi_open, (void) 				);
 | 
					FORWARD _PROTOTYPE( int atapi_open, (void) 				);
 | 
				
			||||||
FORWARD _PROTOTYPE( void atapi_close, (void) 				);
 | 
					FORWARD _PROTOTYPE( void atapi_close, (void) 				);
 | 
				
			||||||
FORWARD _PROTOTYPE( int atapi_transfer, (int proc_nr, int opcode,
 | 
					FORWARD _PROTOTYPE( int atapi_transfer, (int proc_nr, int opcode,
 | 
				
			||||||
			off_t position, iovec_t *iov, unsigned nr_req) 	);
 | 
							off_t position, iovec_t *iov, unsigned nr_req, int safe));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Entry points to this driver. */
 | 
					/* Entry points to this driver. */
 | 
				
			||||||
@ -1045,7 +1045,7 @@ PRIVATE int w_io_test(void)
 | 
				
			|||||||
 	if (w_prepare(w_drive * DEV_PER_DRIVE) == NIL_DEV)
 | 
					 	if (w_prepare(w_drive * DEV_PER_DRIVE) == NIL_DEV)
 | 
				
			||||||
 		panic(w_name(), "Couldn't switch devices", NO_NUM);
 | 
					 		panic(w_name(), "Couldn't switch devices", NO_NUM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r = w_transfer(SELF, DEV_GATHER, 0, &iov, 1);
 | 
						r = w_transfer(SELF, DEV_GATHER, 0, &iov, 1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Switch back. */
 | 
						/* Switch back. */
 | 
				
			||||||
 	if (w_prepare(save_dev) == NIL_DEV)
 | 
					 	if (w_prepare(save_dev) == NIL_DEV)
 | 
				
			||||||
@ -1185,12 +1185,13 @@ PRIVATE int do_transfer(struct wini *wn, unsigned int precomp,
 | 
				
			|||||||
/*===========================================================================*
 | 
					/*===========================================================================*
 | 
				
			||||||
 *				w_transfer				     *
 | 
					 *				w_transfer				     *
 | 
				
			||||||
 *===========================================================================*/
 | 
					 *===========================================================================*/
 | 
				
			||||||
PRIVATE int w_transfer(proc_nr, opcode, position, iov, nr_req)
 | 
					PRIVATE int w_transfer(proc_nr, opcode, position, iov, nr_req, safe)
 | 
				
			||||||
int proc_nr;			/* process doing the request */
 | 
					int proc_nr;			/* process doing the request */
 | 
				
			||||||
int opcode;			/* DEV_GATHER or DEV_SCATTER */
 | 
					int opcode;			/* DEV_GATHER or DEV_SCATTER */
 | 
				
			||||||
off_t position;			/* offset on device to read or write */
 | 
					off_t position;			/* offset on device to read or write */
 | 
				
			||||||
iovec_t *iov;			/* pointer to read or write request vector */
 | 
					iovec_t *iov;			/* pointer to read or write request vector */
 | 
				
			||||||
unsigned nr_req;		/* length of request vector */
 | 
					unsigned nr_req;		/* length of request vector */
 | 
				
			||||||
 | 
					int safe;			/* iov contains addresses (0) or grants? */
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  struct wini *wn = w_wn;
 | 
					  struct wini *wn = w_wn;
 | 
				
			||||||
  iovec_t *iop, *iov_end = iov + nr_req;
 | 
					  iovec_t *iop, *iov_end = iov + nr_req;
 | 
				
			||||||
@ -1199,15 +1200,14 @@ unsigned nr_req;		/* length of request vector */
 | 
				
			|||||||
  unsigned long dv_size = cv64ul(w_dv->dv_size);
 | 
					  unsigned long dv_size = cv64ul(w_dv->dv_size);
 | 
				
			||||||
  unsigned cylinder, head, sector, nbytes;
 | 
					  unsigned cylinder, head, sector, nbytes;
 | 
				
			||||||
  unsigned dma_buf_offset;
 | 
					  unsigned dma_buf_offset;
 | 
				
			||||||
 | 
					  size_t addr_offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if ENABLE_ATAPI
 | 
					#if ENABLE_ATAPI
 | 
				
			||||||
  if (w_wn->state & ATAPI) {
 | 
					  if (w_wn->state & ATAPI) {
 | 
				
			||||||
	return atapi_transfer(proc_nr, opcode, position, iov, nr_req);
 | 
						return atapi_transfer(proc_nr, opcode, position, iov, nr_req, safe);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Check disk address. */
 | 
					  /* Check disk address. */
 | 
				
			||||||
  if ((position & SECTOR_MASK) != 0) return(EINVAL);
 | 
					  if ((position & SECTOR_MASK) != 0) return(EINVAL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1237,7 +1237,7 @@ unsigned nr_req;		/* length of request vector */
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (do_dma)
 | 
						if (do_dma)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		setup_dma(&nbytes, proc_nr, iov, do_write, &do_copyout);
 | 
							setup_dma(&nbytes, proc_nr, iov, do_write, &do_copyout, safe);
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
		printf("nbytes = %d\n", nbytes);
 | 
							printf("nbytes = %d\n", nbytes);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -1314,9 +1314,16 @@ unsigned nr_req;		/* length of request vector */
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			if (do_copyout)
 | 
								if (do_copyout)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				s= sys_vircopy(SELF, D,
 | 
									if(safe) {
 | 
				
			||||||
 | 
									   s= sys_safecopyto(proc_nr, iov->iov_addr,
 | 
				
			||||||
 | 
										addr_offset,
 | 
				
			||||||
 | 
										(vir_bytes)dma_buf+dma_buf_offset, n, D);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
									   s= sys_vircopy(SELF, D,
 | 
				
			||||||
					(vir_bytes)dma_buf+dma_buf_offset, 
 | 
										(vir_bytes)dma_buf+dma_buf_offset, 
 | 
				
			||||||
					proc_nr, D, iov->iov_addr, n);
 | 
										proc_nr, D,
 | 
				
			||||||
 | 
										iov->iov_addr + addr_offset, n);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				if (s != OK)
 | 
									if (s != OK)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					panic(w_name(),
 | 
										panic(w_name(),
 | 
				
			||||||
@ -1328,9 +1335,9 @@ unsigned nr_req;		/* length of request vector */
 | 
				
			|||||||
			/* Book the bytes successfully transferred. */
 | 
								/* Book the bytes successfully transferred. */
 | 
				
			||||||
			nbytes -= n;
 | 
								nbytes -= n;
 | 
				
			||||||
			position += n;
 | 
								position += n;
 | 
				
			||||||
			iov->iov_addr += n;
 | 
								if ((iov->iov_size -= n) == 0) {
 | 
				
			||||||
			if ((iov->iov_size -= n) == 0)
 | 
									iov++; nr_req--; addr_offset = 0;
 | 
				
			||||||
				{ iov++; nr_req--; }
 | 
								}
 | 
				
			||||||
			dma_buf_offset += n;
 | 
								dma_buf_offset += n;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -1367,18 +1374,33 @@ unsigned nr_req;		/* length of request vector */
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		/* Copy bytes to or from the device's buffer. */
 | 
							/* Copy bytes to or from the device's buffer. */
 | 
				
			||||||
		if (opcode == DEV_GATHER) {
 | 
							if (opcode == DEV_GATHER) {
 | 
				
			||||||
			if ((s=sys_insw(wn->base_cmd + REG_DATA, proc_nr, 
 | 
							   if(safe) {
 | 
				
			||||||
				(void *) iov->iov_addr, SECTOR_SIZE)) != OK)
 | 
								s=sys_safe_insw(wn->base_cmd + REG_DATA, proc_nr, 
 | 
				
			||||||
			{
 | 
									(void *) (iov->iov_addr), addr_offset,
 | 
				
			||||||
				panic(w_name(),"Call to sys_insw() failed", s);
 | 
										SECTOR_SIZE);
 | 
				
			||||||
			}
 | 
							   } else {
 | 
				
			||||||
 | 
								s=sys_insw(wn->base_cmd + REG_DATA, proc_nr, 
 | 
				
			||||||
 | 
									(void *) (iov->iov_addr + addr_offset),
 | 
				
			||||||
 | 
										SECTOR_SIZE);
 | 
				
			||||||
 | 
							   }
 | 
				
			||||||
 | 
							   if(s != OK) {
 | 
				
			||||||
 | 
								panic(w_name(),"Call to sys_insw() failed", s);
 | 
				
			||||||
 | 
							   }
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if ((s=sys_outsw(wn->base_cmd + REG_DATA, proc_nr,
 | 
							   if(safe) {
 | 
				
			||||||
				(void *) iov->iov_addr, SECTOR_SIZE)) != OK)
 | 
								s=sys_safe_outsw(wn->base_cmd + REG_DATA, proc_nr,
 | 
				
			||||||
			{
 | 
									(void *) (iov->iov_addr), addr_offset,
 | 
				
			||||||
				panic(w_name(),"Call to sys_outsw() failed",
 | 
									SECTOR_SIZE);
 | 
				
			||||||
					s);
 | 
							   } else {
 | 
				
			||||||
			}
 | 
								s=sys_outsw(wn->base_cmd + REG_DATA, proc_nr,
 | 
				
			||||||
 | 
									(void *) (iov->iov_addr + addr_offset),
 | 
				
			||||||
 | 
									SECTOR_SIZE);
 | 
				
			||||||
 | 
							   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							   if(s != OK) {
 | 
				
			||||||
 | 
							  	panic(w_name(),"Call to sys_outsw() failed",
 | 
				
			||||||
 | 
								  	s);
 | 
				
			||||||
 | 
							   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Data sent, wait for an interrupt. */
 | 
								/* Data sent, wait for an interrupt. */
 | 
				
			||||||
			if ((r = at_intr_wait()) != OK) break;
 | 
								if ((r = at_intr_wait()) != OK) break;
 | 
				
			||||||
@ -1387,8 +1409,12 @@ unsigned nr_req;		/* length of request vector */
 | 
				
			|||||||
		/* Book the bytes successfully transferred. */
 | 
							/* Book the bytes successfully transferred. */
 | 
				
			||||||
		nbytes -= SECTOR_SIZE;
 | 
							nbytes -= SECTOR_SIZE;
 | 
				
			||||||
		position += SECTOR_SIZE;
 | 
							position += SECTOR_SIZE;
 | 
				
			||||||
		iov->iov_addr += SECTOR_SIZE;
 | 
							addr_offset += SECTOR_SIZE;
 | 
				
			||||||
		if ((iov->iov_size -= SECTOR_SIZE) == 0) { iov++; nr_req--; }
 | 
							if ((iov->iov_size -= SECTOR_SIZE) == 0) {
 | 
				
			||||||
 | 
								iov++;
 | 
				
			||||||
 | 
								nr_req--;
 | 
				
			||||||
 | 
								addr_offset = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Any errors? */
 | 
						/* Any errors? */
 | 
				
			||||||
@ -1518,12 +1544,13 @@ struct command *cmd;		/* Command block */
 | 
				
			|||||||
/*===========================================================================*
 | 
					/*===========================================================================*
 | 
				
			||||||
 *				setup_dma				     *
 | 
					 *				setup_dma				     *
 | 
				
			||||||
 *===========================================================================*/
 | 
					 *===========================================================================*/
 | 
				
			||||||
PRIVATE void setup_dma(sizep, proc_nr, iov, do_write, do_copyoutp)
 | 
					PRIVATE void setup_dma(sizep, proc_nr, iov, do_write, do_copyoutp, safe)
 | 
				
			||||||
unsigned *sizep;
 | 
					unsigned *sizep;
 | 
				
			||||||
int proc_nr;
 | 
					int proc_nr;
 | 
				
			||||||
iovec_t *iov;
 | 
					iovec_t *iov;
 | 
				
			||||||
int do_write;
 | 
					int do_write;
 | 
				
			||||||
int *do_copyoutp;
 | 
					int *do_copyoutp;
 | 
				
			||||||
 | 
					int safe;
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	phys_bytes phys, user_phys;
 | 
						phys_bytes phys, user_phys;
 | 
				
			||||||
	unsigned n, offset, size;
 | 
						unsigned n, offset, size;
 | 
				
			||||||
@ -1555,7 +1582,12 @@ int *do_copyoutp;
 | 
				
			|||||||
			n= size;
 | 
								n= size;
 | 
				
			||||||
		if (n == 0 || (n & 1))
 | 
							if (n == 0 || (n & 1))
 | 
				
			||||||
			panic("at_wini", "bad size in iov", iov[i].iov_size);
 | 
								panic("at_wini", "bad size in iov", iov[i].iov_size);
 | 
				
			||||||
		r= sys_umap(proc_nr, D, iov[i].iov_addr+offset, n, &user_phys);
 | 
							if(safe) {
 | 
				
			||||||
 | 
							 r= sys_umap(proc_nr, GRANT_SEG, iov[i].iov_addr, n,&user_phys);
 | 
				
			||||||
 | 
							 user_phys += offset;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
							 r= sys_umap(proc_nr, D, iov[i].iov_addr+offset, n, &user_phys);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if (r != 0)
 | 
							if (r != 0)
 | 
				
			||||||
			panic("at_wini", "can't map user buffer", r);
 | 
								panic("at_wini", "can't map user buffer", r);
 | 
				
			||||||
		if (user_phys & 1)
 | 
							if (user_phys & 1)
 | 
				
			||||||
@ -1635,9 +1667,14 @@ int *do_copyoutp;
 | 
				
			|||||||
				if (n > iov->iov_size)
 | 
									if (n > iov->iov_size)
 | 
				
			||||||
					n= iov->iov_size;
 | 
										n= iov->iov_size;
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
				r= sys_vircopy(proc_nr, D, iov->iov_addr,
 | 
									if(safe) {
 | 
				
			||||||
 | 
									  r= sys_safecopyfrom(proc_nr, iov->iov_addr,
 | 
				
			||||||
 | 
										0, (vir_bytes)dma_buf+offset, n, D);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
									  r= sys_vircopy(proc_nr, D, iov->iov_addr,
 | 
				
			||||||
					SELF, D, (vir_bytes)dma_buf+offset, 
 | 
										SELF, D, (vir_bytes)dma_buf+offset, 
 | 
				
			||||||
					n);
 | 
										n);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				if (r != OK)
 | 
									if (r != OK)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					panic(w_name(),
 | 
										panic(w_name(),
 | 
				
			||||||
@ -2069,12 +2106,13 @@ void sense_request(void)
 | 
				
			|||||||
/*===========================================================================*
 | 
					/*===========================================================================*
 | 
				
			||||||
 *				atapi_transfer				     *
 | 
					 *				atapi_transfer				     *
 | 
				
			||||||
 *===========================================================================*/
 | 
					 *===========================================================================*/
 | 
				
			||||||
PRIVATE int atapi_transfer(proc_nr, opcode, position, iov, nr_req)
 | 
					PRIVATE int atapi_transfer(proc_nr, opcode, position, iov, nr_req, safe)
 | 
				
			||||||
int proc_nr;			/* process doing the request */
 | 
					int proc_nr;			/* process doing the request */
 | 
				
			||||||
int opcode;			/* DEV_GATHER or DEV_SCATTER */
 | 
					int opcode;			/* DEV_GATHER or DEV_SCATTER */
 | 
				
			||||||
off_t position;			/* offset on device to read or write */
 | 
					off_t position;			/* offset on device to read or write */
 | 
				
			||||||
iovec_t *iov;			/* pointer to read or write request vector */
 | 
					iovec_t *iov;			/* pointer to read or write request vector */
 | 
				
			||||||
unsigned nr_req;		/* length of request vector */
 | 
					unsigned nr_req;		/* length of request vector */
 | 
				
			||||||
 | 
					int safe;			/* use safecopies? */
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  struct wini *wn = w_wn;
 | 
					  struct wini *wn = w_wn;
 | 
				
			||||||
  iovec_t *iop, *iov_end = iov + nr_req;
 | 
					  iovec_t *iop, *iov_end = iov + nr_req;
 | 
				
			||||||
@ -2084,6 +2122,7 @@ unsigned nr_req;		/* length of request vector */
 | 
				
			|||||||
  unsigned long dv_size = cv64ul(w_dv->dv_size);
 | 
					  unsigned long dv_size = cv64ul(w_dv->dv_size);
 | 
				
			||||||
  unsigned nbytes, nblocks, count, before, chunk;
 | 
					  unsigned nbytes, nblocks, count, before, chunk;
 | 
				
			||||||
  static u8_t packet[ATAPI_PACKETSIZE];
 | 
					  static u8_t packet[ATAPI_PACKETSIZE];
 | 
				
			||||||
 | 
					  size_t addr_offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  errors = fresh = 0;
 | 
					  errors = fresh = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2161,17 +2200,25 @@ unsigned nr_req;		/* length of request vector */
 | 
				
			|||||||
			chunk = nbytes;
 | 
								chunk = nbytes;
 | 
				
			||||||
			if (chunk > count) chunk = count;
 | 
								if (chunk > count) chunk = count;
 | 
				
			||||||
			if (chunk > iov->iov_size) chunk = iov->iov_size;
 | 
								if (chunk > iov->iov_size) chunk = iov->iov_size;
 | 
				
			||||||
	if ((s=sys_insw(wn->base_cmd + REG_DATA, proc_nr, (void *) iov->iov_addr, chunk)) != OK)
 | 
								if(safe) {
 | 
				
			||||||
		panic(w_name(),"Call to sys_insw() failed", s);
 | 
									s=sys_safe_insw(wn->base_cmd + REG_DATA, proc_nr,
 | 
				
			||||||
 | 
										(void *) iov->iov_addr, addr_offset, chunk);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									s=sys_insw(wn->base_cmd + REG_DATA, proc_nr,
 | 
				
			||||||
 | 
										(void *) (iov->iov_addr + addr_offset), chunk);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (s != OK)
 | 
				
			||||||
 | 
									panic(w_name(),"Call to sys_insw() failed", s);
 | 
				
			||||||
			position += chunk;
 | 
								position += chunk;
 | 
				
			||||||
			nbytes -= chunk;
 | 
								nbytes -= chunk;
 | 
				
			||||||
			count -= chunk;
 | 
								count -= chunk;
 | 
				
			||||||
			iov->iov_addr += chunk;
 | 
								addr_offset += chunk;
 | 
				
			||||||
			fresh = 0;
 | 
								fresh = 0;
 | 
				
			||||||
			if ((iov->iov_size -= chunk) == 0) {
 | 
								if ((iov->iov_size -= chunk) == 0) {
 | 
				
			||||||
				iov++;
 | 
									iov++;
 | 
				
			||||||
				nr_req--;
 | 
									nr_req--;
 | 
				
			||||||
				fresh = 1;	/* new element is optional */
 | 
									fresh = 1;	/* new element is optional */
 | 
				
			||||||
 | 
									addr_offset = 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2273,20 +2320,28 @@ unsigned cnt;
 | 
				
			|||||||
/*===========================================================================*
 | 
					/*===========================================================================*
 | 
				
			||||||
 *				w_other					     *
 | 
					 *				w_other					     *
 | 
				
			||||||
 *===========================================================================*/
 | 
					 *===========================================================================*/
 | 
				
			||||||
PRIVATE int w_other(dr, m)
 | 
					PRIVATE int w_other(dr, m, safe)
 | 
				
			||||||
struct driver *dr;
 | 
					struct driver *dr;
 | 
				
			||||||
message *m;
 | 
					message *m;
 | 
				
			||||||
 | 
					int safe;
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int r, timeout, prev;
 | 
						int r, timeout, prev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (m->m_type != DEV_IOCTL ) {
 | 
						if (m->m_type != DEV_IOCTL && m->m_type != DEV_IOCTL_S ) {
 | 
				
			||||||
		return EINVAL;
 | 
							return EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (m->REQUEST == DIOCTIMEOUT) {
 | 
						if (m->REQUEST == DIOCTIMEOUT) {
 | 
				
			||||||
		if ((r=sys_datacopy(m->IO_ENDPT, (vir_bytes)m->ADDRESS,
 | 
							if(safe) {
 | 
				
			||||||
			SELF, (vir_bytes)&timeout, sizeof(timeout))) != OK)
 | 
							  r= sys_safecopyfrom(m->IO_ENDPT, (vir_bytes) m->IO_GRANT,
 | 
				
			||||||
			return r;
 | 
								0, (vir_bytes)&timeout, sizeof(timeout), D);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
							  r= sys_datacopy(m->IO_ENDPT, (vir_bytes)m->ADDRESS,
 | 
				
			||||||
 | 
								SELF, (vir_bytes)&timeout, sizeof(timeout));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(r != OK)
 | 
				
			||||||
 | 
							    return r;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
		if (timeout == 0) {
 | 
							if (timeout == 0) {
 | 
				
			||||||
			/* Restore defaults. */
 | 
								/* Restore defaults. */
 | 
				
			||||||
@ -2311,8 +2366,17 @@ message *m;
 | 
				
			|||||||
					timeout_ticks = timeout;
 | 
										timeout_ticks = timeout;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
			if ((r=sys_datacopy(SELF, (vir_bytes)&prev, 
 | 
								if(safe) {
 | 
				
			||||||
				m->IO_ENDPT, (vir_bytes)m->ADDRESS, sizeof(prev))) != OK)
 | 
							  	   r= sys_safecopyto(m->IO_ENDPT,
 | 
				
			||||||
 | 
									(vir_bytes) m->IO_GRANT,
 | 
				
			||||||
 | 
									0, (vir_bytes)&prev, sizeof(prev), D);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
								   r=sys_datacopy(SELF, (vir_bytes)&prev, 
 | 
				
			||||||
 | 
									m->IO_ENDPT, (vir_bytes)m->ADDRESS,
 | 
				
			||||||
 | 
									sizeof(prev));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if(r != OK)
 | 
				
			||||||
				return r;
 | 
									return r;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
@ -2321,9 +2385,17 @@ message *m;
 | 
				
			|||||||
		int count;
 | 
							int count;
 | 
				
			||||||
		if (w_prepare(m->DEVICE) == NIL_DEV) return ENXIO;
 | 
							if (w_prepare(m->DEVICE) == NIL_DEV) return ENXIO;
 | 
				
			||||||
		count = w_wn->open_ct;
 | 
							count = w_wn->open_ct;
 | 
				
			||||||
		if ((r=sys_datacopy(SELF, (vir_bytes)&count, 
 | 
							if(safe) {
 | 
				
			||||||
			m->IO_ENDPT, (vir_bytes)m->ADDRESS, sizeof(count))) != OK)
 | 
							    r= sys_safecopyto(m->IO_ENDPT, (vir_bytes) m->IO_GRANT,
 | 
				
			||||||
 | 
								0, (vir_bytes)&count, sizeof(count), D);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
							    r=sys_datacopy(SELF, (vir_bytes)&count, 
 | 
				
			||||||
 | 
								m->IO_ENDPT, (vir_bytes)m->ADDRESS, sizeof(count));
 | 
				
			||||||
 | 
							} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(r != OK)
 | 
				
			||||||
			return r;
 | 
								return r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return OK;
 | 
							return OK;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return EINVAL;
 | 
						return EINVAL;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user