Commit ec6afd8a authored by Russell King's avatar Russell King

[ARM] Make Acorn SCSI drivers build again.

 Acorn machines will never have "highmem" support, so can
 combine page + offset into the scsi pointer structure for
 now.
parent c0111141
......@@ -157,6 +157,7 @@
#include "../../scsi/constants.h"
#include "acornscsi.h"
#include "msgqueue.h"
#include "scsi.h"
#include <scsi/scsicam.h>
......@@ -902,17 +903,8 @@ void acornscsi_data_updateptr(AS_Host *host, Scsi_Pointer *SCp, unsigned int len
SCp->ptr += length;
SCp->this_residual -= length;
if (!SCp->this_residual) {
if (SCp->buffers_residual) {
SCp->buffer++;
SCp->buffers_residual--;
SCp->ptr = (char *)SCp->buffer->address;
SCp->this_residual = SCp->buffer->length;
} else {
SCp->ptr = NULL;
host->dma.xfer_done = 1;
}
}
if (SCp->this_residual == 0 && next_SCp(SCp) == 0)
host->dma.xfer_done = 1;
}
/*
......@@ -2558,20 +2550,8 @@ int acornscsi_queuecmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCpnt->SCp.phase = (int)acornscsi_datadirection(SCpnt->cmnd[0]);
SCpnt->SCp.sent_command = 0;
SCpnt->SCp.scsi_xferred = 0;
SCpnt->SCp.Status = 0;
SCpnt->SCp.Message = 0;
if (SCpnt->use_sg) {
SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
SCpnt->SCp.ptr = (char *) SCpnt->SCp.buffer->address;
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
} else {
SCpnt->SCp.buffer = NULL;
SCpnt->SCp.buffers_residual = 0;
SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
SCpnt->SCp.this_residual = SCpnt->request_bufflen;
}
init_SCp(SCpnt);
host->stats.queues += 1;
......
......@@ -38,6 +38,7 @@
#include "../../scsi/sd.h"
#include "../../scsi/hosts.h"
#include "fas216.h"
#include "scsi.h"
#include <scsi/scsicam.h>
......@@ -188,15 +189,9 @@ cumanascsi_2_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
if (dmach != NO_DMA &&
(min_type == fasdma_real_all || SCp->this_residual >= 512)) {
int bufs = SCp->buffers_residual;
int pci_dir, dma_dir, alatch_dir;
if (bufs)
memcpy(info->sg + 1, SCp->buffer + 1,
sizeof(struct scatterlist) * bufs);
info->sg[0].address = SCp->ptr;
info->sg[0].page = NULL;
info->sg[0].length = SCp->this_residual;
int bufs, pci_dir, dma_dir, alatch_dir;
bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG);
if (direction == DMA_OUT)
pci_dir = PCI_DMA_TODEVICE,
......
......@@ -44,6 +44,7 @@
#include "../../scsi/sd.h"
#include "../../scsi/hosts.h"
#include "fas216.h"
#include "scsi.h"
#include <scsi/scsicam.h>
......@@ -192,15 +193,9 @@ eesoxscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
if (dmach != NO_DMA &&
(min_type == fasdma_real_all || SCp->this_residual >= 512)) {
int bufs = SCp->buffers_residual;
int pci_dir, dma_dir;
if (bufs)
memcpy(info->sg + 1, SCp->buffer + 1,
sizeof(struct scatterlist) * bufs);
info->sg[0].address = SCp->ptr;
info->sg[0].page = NULL;
info->sg[0].length = SCp->this_residual;
int bufs, pci_dir, dma_dir;
bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG);
if (direction == DMA_OUT)
pci_dir = PCI_DMA_TODEVICE,
......
......@@ -59,6 +59,7 @@
#include "../../scsi/scsi.h"
#include "../../scsi/hosts.h"
#include "fas216.h"
#include "scsi.h"
#define VER_MAJOR 0
#define VER_MINOR 0
......@@ -588,38 +589,32 @@ fas216_handlewide(FAS216_Info *info, char *msg)
static void
fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
{
unsigned char *ptr;
unsigned int residual;
Scsi_Pointer *SCp = &info->scsi.SCp;
fas216_checkmagic(info);
ptr = info->scsi.SCp.ptr;
residual = info->scsi.SCp.this_residual;
info->SCpnt->request_bufflen -= bytes_transferred;
while (residual <= bytes_transferred && bytes_transferred) {
/* We have used up this buffer */
bytes_transferred -= residual;
if (info->scsi.SCp.buffers_residual) {
info->scsi.SCp.buffer++;
info->scsi.SCp.buffers_residual--;
ptr = (unsigned char *)info->scsi.SCp.buffer->address;
residual = info->scsi.SCp.buffer->length;
} else {
ptr = NULL;
residual = 0;
while (bytes_transferred != 0) {
if (SCp->this_residual > bytes_transferred)
break;
/*
* We have used up this buffer. Move on to the
* next buffer.
*/
bytes_transferred -= SCp->this_residual;
if (!next_SCp(&info->scsi.SCp)) {
printk(KERN_WARNING "scsi%d.%c: out of buffers\n",
info->host->host_no, '0' + info->SCpnt->target);
return;
}
}
residual -= bytes_transferred;
ptr += bytes_transferred;
if (residual == 0)
ptr = NULL;
info->scsi.SCp.ptr = ptr;
info->scsi.SCp.this_residual = residual;
SCp->this_residual -= bytes_transferred;
if (SCp->this_residual)
SCp->ptr += bytes_transferred;
else
SCp->ptr = NULL;
}
/* Function: void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
......@@ -631,35 +626,12 @@ fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
static void
fas216_pio(FAS216_Info *info, fasdmadir_t direction)
{
unsigned int residual;
char *ptr;
fas216_checkmagic(info);
residual = info->scsi.SCp.this_residual;
ptr = info->scsi.SCp.ptr;
if (direction == DMA_OUT)
outb(*ptr++, REG_FF(info));
outb(get_next_SCp_byte(&info->scsi.SCp), REG_FF(info));
else
*ptr++ = inb(REG_FF(info));
residual -= 1;
if (residual == 0) {
if (info->scsi.SCp.buffers_residual) {
info->scsi.SCp.buffer++;
info->scsi.SCp.buffers_residual--;
ptr = (unsigned char *)info->scsi.SCp.buffer->address;
residual = info->scsi.SCp.buffer->length;
} else {
ptr = NULL;
residual = 0;
}
}
info->scsi.SCp.ptr = ptr;
info->scsi.SCp.this_residual = residual;
put_next_SCp_byte(&info->scsi.SCp, inb(REG_FF(info)));
}
/* Function: void fas216_starttransfer(FAS216_Info *info,
......@@ -2034,48 +2006,8 @@ int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCpnt->scsi_done = done;
SCpnt->host_scribble = (void *)fas216_std_done;
SCpnt->result = 0;
SCpnt->SCp.Message = 0;
SCpnt->SCp.Status = 0;
if (SCpnt->use_sg) {
unsigned long len = 0;
int buf;
SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
SCpnt->SCp.ptr = (char *) SCpnt->SCp.buffer->address;
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
/*
* Calculate correct buffer length. Some commands
* come in with the wrong request_bufflen.
*/
for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
len += SCpnt->SCp.buffer[buf].length;
if (SCpnt->request_bufflen != len)
printk(KERN_WARNING "scsi%d.%c: bad request buffer "
"length %d, should be %ld\n", info->host->host_no,
'0' + SCpnt->target, SCpnt->request_bufflen, len);
SCpnt->request_bufflen = len;
} else {
SCpnt->SCp.buffer = NULL;
SCpnt->SCp.buffers_residual = 0;
SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
SCpnt->SCp.this_residual = SCpnt->request_bufflen;
}
/*
* If the upper SCSI layers pass a buffer, but zero length,
* we aren't interested in the buffer pointer.
*/
if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
#if 0
printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
"command ", info->host->host_no, '0' + SCpnt->target);
print_command(SCpnt->cmnd);
#endif
SCpnt->SCp.ptr = NULL;
}
init_SCp(SCpnt);
info->stats.queues += 1;
SCpnt->tag = 0;
......
......@@ -41,6 +41,7 @@
#include "../../scsi/sd.h"
#include "../../scsi/hosts.h"
#include "fas216.h"
#include "scsi.h"
#include <scsi/scsicam.h>
......@@ -180,15 +181,9 @@ powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp,
if (dmach != NO_DMA &&
(min_type == fasdma_real_all || SCp->this_residual >= 512)) {
int bufs = SCp->buffers_residual;
int pci_dir, dma_dir;
if (bufs)
memcpy(info->sg + 1, SCp->buffer + 1,
sizeof(struct scatterlist) * bufs);
info->sg[0].address = SCp->ptr;
info->sg[0].page = NULL;
info->sg[0].length = SCp->this_residual;
int bufs, pci_dir, dma_dir;
bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG);
if (direction == DMA_OUT)
pci_dir = PCI_DMA_TODEVICE,
......
/*
* linux/drivers/acorn/scsi/scsi.h
*
* Copyright (C) 2002 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Commonly used scsi driver functions.
*/
#define BELT_AND_BRACES
/*
* The scatter-gather list handling. This contains all
* the yucky stuff that needs to be fixed properly.
*/
static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int max)
{
int bufs = SCp->buffers_residual;
BUG_ON(bufs + 1 > max);
sg->page = virt_to_page(SCp->ptr);
sg->offset = ((unsigned int)SCp->ptr) & ~PAGE_MASK;
sg->length = SCp->this_residual;
if (bufs)
memcpy(sg + 1, SCp->buffer + 1,
sizeof(struct scatterlist) * bufs);
return bufs + 1;
}
static inline int next_SCp(Scsi_Pointer *SCp)
{
int ret = SCp->buffers_residual;
if (ret) {
SCp->buffer++;
SCp->buffers_residual--;
SCp->ptr = (char *)
(page_address(SCp->buffer->page) +
SCp->buffer->offset);
SCp->this_residual = SCp->buffer->length;
} else {
SCp->ptr = NULL;
SCp->this_residual = 0;
}
return ret;
}
static inline unsigned char get_next_SCp_byte(Scsi_Pointer *SCp)
{
char c = SCp->ptr;
SCp->ptr += 1;
SCp->this_residual -= 1;
if (SCp->this_residual == 0)
next_SCp(SCp);
return c;
}
static inline void put_next_SCp_byte(Scsi_Pointer *SCp, unsigned char c)
{
SCp->ptr = c;
SCp->ptr += 1;
SCp->this_residual -= 1;
if (SCp->this_residual == 0)
next_SCp(SCp);
}
static inline void init_SCp(Scsi_Cmnd *SCpnt)
{
SCpnt->SCp.Message = 0;
SCpnt->SCp.Status = 0;
if (SCpnt->use_sg) {
unsigned long len = 0;
int buf;
SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
SCpnt->SCp.ptr = (char *)
(page_address(SCpnt->SCp.buffer->page) +
SCpnt->SCp.buffer->offset);
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
#ifdef BELT_AND_BRACES
/*
* Calculate correct buffer length. Some commands
* come in with the wrong request_bufflen.
*/
for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
len += SCpnt->SCp.buffer[buf].length;
if (SCpnt->request_bufflen != len)
printk(KERN_WARNING "scsi%d.%c: bad request buffer "
"length %d, should be %ld\n", SCpnt->host->host_no,
'0' + SCpnt->target, SCpnt->request_bufflen, len);
SCpnt->request_bufflen = len;
#endif
} else {
SCpnt->SCp.buffer = NULL;
SCpnt->SCp.buffers_residual = 0;
SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
SCpnt->SCp.this_residual = SCpnt->request_bufflen;
}
/*
* If the upper SCSI layers pass a buffer, but zero length,
* we aren't interested in the buffer pointer.
*/
if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
#ifdef BELT_AND_BRACES
printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
"command ", SCpnt->host->host_no, '0' + SCpnt->target);
print_command(SCpnt->cmnd);
#endif
SCpnt->SCp.ptr = NULL;
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment