Commit 32079c41 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Linus Torvalds

[PATCH] Sun-3/3x updates

General cleanup/updating of purely sun3/3x code (from Sam Creasey)
  - arch/m68k/sun3(x):
      o Cleaned up prom code slightly
      o Added reporting of prom revision in /proc/hardware
      o Removed some warnings
  - Use common idprom code for both Sun-3 and Sun-3x
  - Sun-3x idprom updates
  - drivers/scsi/sun3*: updated scsi drivers to reflect new struct scatterlist.
parent f8bf4922
......@@ -4,9 +4,9 @@
export-objs := sun3_ksyms.o
obj-y := sun3_ksyms.o sun3ints.o sun3dvma.o sbus.o
obj-y := sun3_ksyms.o sun3ints.o sun3dvma.o sbus.o idprom.o
obj-$(CONFIG_SUN3) += config.o idprom.o mmu_emu.o leds.o dvma.o \
obj-$(CONFIG_SUN3) += config.o mmu_emu.o leds.o dvma.o \
intersil.o
include $(TOPDIR)/Rules.make
......@@ -31,8 +31,8 @@ struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = {
{ "Sun 3/60", (SM_SUN3 | SM_3_60) },
{ "Sun 3/E", (SM_SUN3 | SM_3_E) },
/* Now, Sun3x's */
{ "Sun 3/460 Series", (SM_SUN3 | SM_3_460) },
{ "Sun 3/80", (SM_SUN3 | SM_3_80) },
{ "Sun 3/460 Series", (SM_SUN3X | SM_3_460) },
{ "Sun 3/80", (SM_SUN3X | SM_3_80) },
/* Then, Sun4's */
//{ "Sun 4/100 Series", (SM_SUN4 | SM_4_110) },
//{ "Sun 4/200 Series", (SM_SUN4 | SM_4_260) },
......
......@@ -17,22 +17,30 @@
#include <asm/sun3xprom.h>
#include <asm/sun3ints.h>
#include <asm/setup.h>
#include <asm/oplib.h>
#include "time.h"
volatile char *clock_va;
extern volatile unsigned char *sun3_intreg;
extern void sun3_get_model(char *model);
void sun3_leds(unsigned int i)
{
}
/* should probably detect types of these eventually. */
static void sun3x_get_model(char *model)
static int sun3x_get_hardware_list(char *buffer)
{
sprintf(model, "Sun3x");
int len = 0;
len += sprintf(buffer + len, "PROM Revision:\t%s\n",
romvec->pv_monid);
return len;
}
/*
......
......@@ -26,8 +26,6 @@ int (*sun3x_mayget)(void);
int (*sun3x_mayput)(int);
void (*sun3x_prom_reboot)(void);
e_vector sun3x_prom_abort;
struct idprom *idprom;
static struct idprom idprom_buffer;
struct linux_romvec *romvec;
/* prom vector table */
......@@ -107,8 +105,6 @@ static struct console sun3x_debug = {
void sun3x_prom_init(void)
{
/* Read the vector table */
int i;
sun3x_putchar = *(void (**)(int)) (SUN3X_P_PUTCHAR);
sun3x_getchar = *(int (**)(void)) (SUN3X_P_GETCHAR);
......@@ -118,13 +114,11 @@ void sun3x_prom_init(void)
sun3x_prom_abort = *(e_vector *) (SUN3X_P_ABORT);
romvec = (struct linux_romvec *)SUN3X_PROM_BASE;
/* make a copy of the idprom structure */
for(i = 0; i < sizeof(struct idprom); i++)
((unsigned char *)(&idprom_buffer))[i] = ((unsigned char *)SUN3X_IDPROM)[i];
idprom = &idprom_buffer;
idprom_init();
if((idprom->id_machtype & SM_ARCH_MASK) != SM_SUN3X) {
printk("Warning: machine reports strange type %02x\n");
if(!((idprom->id_machtype & SM_ARCH_MASK) == SM_SUN3X)) {
printk("Warning: machine reports strange type %02x\n",
idprom->id_machtype);
printk("Pretending it's a 3/80, but very afraid...\n");
idprom->id_machtype = SM_SUN3X | SM_3_80;
}
......@@ -162,3 +156,19 @@ void prom_halt (void)
{
sun3x_halt();
}
/* Get the idprom and stuff it into buffer 'idbuf'. Returns the
* format type. 'num_bytes' is the number of bytes that your idbuf
* has space for. Returns 0xff on error.
*/
unsigned char
prom_get_idprom(char *idbuf, int num_bytes)
{
int i;
/* make a copy of the idprom structure */
for(i = 0; i < num_bytes; i++)
idbuf[i] = ((char *)SUN3X_IDPROM)[i];
return idbuf[0];
}
......@@ -270,6 +270,9 @@ static Scsi_Host_Template *the_template = NULL;
#define HOSTNO instance->host_no
#define H_NO(cmd) (cmd)->host->host_no
#define SGADDR(buffer) (void *)(((unsigned long)page_address((buffer)->page)) + \
(buffer)->offset)
#ifdef SUPPORT_TAGS
/*
......@@ -476,10 +479,10 @@ static void merge_contiguous_buffers( Scsi_Cmnd *cmd )
for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1;
cmd->SCp.buffers_residual &&
virt_to_phys(cmd->SCp.buffer[1].address) == endaddr; ) {
virt_to_phys(SGADDR(&(cmd->SCp.buffer[1]))) == endaddr; ) {
MER_PRINTK("VTOP(%p) == %08lx -> merging\n",
cmd->SCp.buffer[1].address, endaddr);
SGADDR(&(cmd->SCp.buffer[1])), endaddr);
#if (NDEBUG & NDEBUG_MERGING)
++cnt;
#endif
......@@ -514,12 +517,13 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd)
if (cmd->use_sg) {
cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
cmd->SCp.buffers_residual = cmd->use_sg - 1;
cmd->SCp.ptr = (char *) cmd->SCp.buffer->address;
cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer);
cmd->SCp.this_residual = cmd->SCp.buffer->length;
/* ++roman: Try to merge some scatter-buffers if they are at
* contiguous physical addresses.
*/
merge_contiguous_buffers( cmd );
// merge_contiguous_buffers( cmd );
} else {
cmd->SCp.buffer = NULL;
cmd->SCp.buffers_residual = 0;
......@@ -1211,7 +1215,7 @@ static void NCR5380_dma_complete( struct Scsi_Host *instance )
HOSTNO, NCR5380_read(BUS_AND_STATUS_REG),
NCR5380_read(STATUS_REG));
if((sun3scsi_dma_finish(hostdata->connected->request->cmd))) {
if((sun3scsi_dma_finish(rq_data_dir(hostdata->connected->request)))) {
printk("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n", HOSTNO);
printk("please e-mail sammy@sammy.net with a description of how this\n");
printk("error was produced.\n");
......@@ -2000,7 +2004,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
count = cmd->SCp.buffer->length;
d = cmd->SCp.buffer->address;
d = SGADDR(cmd->SCp.buffer);
} else {
count = cmd->SCp.this_residual;
d = cmd->SCp.ptr;
......@@ -2010,9 +2014,9 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done
!= cmd))
{
if((cmd->request->cmd == 0) || (cmd->request->cmd == 1)) {
if(cmd->request->flags & REQ_CMD) {
sun3scsi_dma_setup(d, count,
cmd->request->cmd);
rq_data_dir(cmd->request));
sun3_dma_setup_done = cmd;
}
}
......@@ -2052,7 +2056,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
++cmd->SCp.buffer;
--cmd->SCp.buffers_residual;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
cmd->SCp.ptr = cmd->SCp.buffer->address;
cmd->SCp.ptr = SGADDR(cmd->SCp.buffer);
/* ++roman: Try to merge some scatter-buffers if
* they are at contiguous physical addresses.
......@@ -2607,24 +2611,22 @@ static void NCR5380_reselect (struct Scsi_Host *instance)
/* engage dma setup for the command we just saw */
{
void *d;
unsigned long count;
unsigned long count;
if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
count = tmp->SCp.buffer->length;
d = tmp->SCp.buffer->address;
} else {
count = tmp->SCp.this_residual;
d = tmp->SCp.ptr;
}
#ifdef REAL_DMA
/* setup this command for dma if not already */
if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done
!= tmp))
{
sun3scsi_dma_setup(d, count,
tmp->request->cmd);
sun3_dma_setup_done = tmp;
}
if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
count = tmp->SCp.buffer->length;
d = SGADDR(tmp->SCp.buffer);
} else {
count = tmp->SCp.this_residual;
d = tmp->SCp.ptr;
}
#ifdef REAL_DMA
/* setup this command for dma if not already */
if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done != tmp))
{
sun3scsi_dma_setup(d, count, rq_data_dir(tmp->request));
sun3_dma_setup_done = tmp;
}
#endif
}
#endif
......
......@@ -343,27 +343,28 @@ static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp)
static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
{
int sz = sp->SCp.buffers_residual;
struct mmu_sglist *sg = (struct mmu_sglist *) sp->SCp.buffer;
struct scatterlist *sg = sp->SCp.buffer;
while (sz >= 0) {
sg[sz].dvma_addr = dvma_map((unsigned long)sg[sz].addr, sg[sz].len);
sz--;
sg[sz].dvma_address = dvma_map((unsigned long)page_address(sg[sz].page) +
sg[sz].offset, sg[sz].length);
sz--;
}
sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dvma_address);
}
static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp)
{
dvma_unmap(sp->SCp.have_data_in);
dvma_unmap((char *)sp->SCp.have_data_in);
}
static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
{
int sz = sp->use_sg - 1;
struct mmu_sglist *sg = (struct mmu_sglist *)sp->buffer;
struct scatterlist *sg = (struct scatterlist *)sp->buffer;
while(sz >= 0) {
dvma_unmap(sg[sz].dvma_addr);
dvma_unmap((char *)sg[sz].dvma_address);
sz--;
}
}
......
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