Commit d132e137 authored by Paul Mackerras's avatar Paul Mackerras Committed by Linus Torvalds

[PATCH] update MESH scsi driver

This patch updates the `mesh' scsi driver used on older powermacs to
correspond with recent changes in the scsi subsystem (things like
using cmd->device->id instead of cmd->target).
parent 1e06dcf9
...@@ -80,7 +80,7 @@ static unsigned char use_active_neg = 0; /* bit mask for SEQ_ACTIVE_NEG if used ...@@ -80,7 +80,7 @@ static unsigned char use_active_neg = 0; /* bit mask for SEQ_ACTIVE_NEG if used
#define ALLOW_SYNC(tgt) ((sync_targets >> (tgt)) & 1) #define ALLOW_SYNC(tgt) ((sync_targets >> (tgt)) & 1)
#define ALLOW_RESEL(tgt) ((resel_targets >> (tgt)) & 1) #define ALLOW_RESEL(tgt) ((resel_targets >> (tgt)) & 1)
#define ALLOW_DEBUG(tgt) ((debug_targets >> (tgt)) & 1) #define ALLOW_DEBUG(tgt) ((debug_targets >> (tgt)) & 1)
#define DEBUG_TARGET(cmd) ((cmd) && ALLOW_DEBUG((cmd)->target)) #define DEBUG_TARGET(cmd) ((cmd) && ALLOW_DEBUG((cmd)->device->id))
#undef MESH_DBG #undef MESH_DBG
#define N_DBG_LOG 50 #define N_DBG_LOG 50
...@@ -465,7 +465,7 @@ mesh_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) ...@@ -465,7 +465,7 @@ mesh_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
cmd->scsi_done = done; cmd->scsi_done = done;
cmd->host_scribble = NULL; cmd->host_scribble = NULL;
ms = (struct mesh_state *) cmd->host->hostdata; ms = (struct mesh_state *) cmd->device->host->hostdata;
if (ms->request_q == NULL) if (ms->request_q == NULL)
ms->request_q = cmd; ms->request_q = cmd;
...@@ -486,15 +486,12 @@ mesh_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) ...@@ -486,15 +486,12 @@ mesh_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
int int
mesh_abort(Scsi_Cmnd *cmd) mesh_abort(Scsi_Cmnd *cmd)
{ {
struct mesh_state *ms = (struct mesh_state *) cmd->host->hostdata; struct mesh_state *ms = (struct mesh_state *) cmd->device->host->hostdata;
unsigned long flags;
printk(KERN_DEBUG "mesh_abort(%p)\n", cmd); printk(KERN_DEBUG "mesh_abort(%p)\n", cmd);
spin_lock_irqsave(ms->host->host_lock, flags);
mesh_dump_regs(ms); mesh_dump_regs(ms);
dumplog(ms, cmd->target); dumplog(ms, cmd->device->id);
dumpslog(ms); dumpslog(ms);
spin_unlock_irqrestore(ms->host->host_lock, flags);
return SCSI_ABORT_SNOOZE; return SCSI_ABORT_SNOOZE;
} }
...@@ -540,7 +537,7 @@ mesh_dump_regs(struct mesh_state *ms) ...@@ -540,7 +537,7 @@ mesh_dump_regs(struct mesh_state *ms)
int int
mesh_host_reset(Scsi_Cmnd *cmd) mesh_host_reset(Scsi_Cmnd *cmd)
{ {
struct mesh_state *ms = (struct mesh_state *) cmd->host->hostdata; struct mesh_state *ms = (struct mesh_state *) cmd->device->host->hostdata;
volatile struct mesh_regs *mr = ms->mesh; volatile struct mesh_regs *mr = ms->mesh;
volatile struct dbdma_regs *md = ms->dma; volatile struct dbdma_regs *md = ms->dma;
...@@ -661,7 +658,7 @@ mesh_start(struct mesh_state *ms) ...@@ -661,7 +658,7 @@ mesh_start(struct mesh_state *ms)
for (cmd = ms->request_q; ; cmd = (Scsi_Cmnd *) cmd->host_scribble) { for (cmd = ms->request_q; ; cmd = (Scsi_Cmnd *) cmd->host_scribble) {
if (cmd == NULL) if (cmd == NULL)
return; return;
if (ms->tgts[cmd->target].current_req == NULL) if (ms->tgts[cmd->device->id].current_req == NULL)
break; break;
prev = cmd; prev = cmd;
} }
...@@ -681,17 +678,18 @@ static void ...@@ -681,17 +678,18 @@ static void
mesh_start_cmd(struct mesh_state *ms, Scsi_Cmnd *cmd) mesh_start_cmd(struct mesh_state *ms, Scsi_Cmnd *cmd)
{ {
volatile struct mesh_regs *mr = ms->mesh; volatile struct mesh_regs *mr = ms->mesh;
int t; int t, id;
id = cmd->device->id;
ms->current_req = cmd; ms->current_req = cmd;
ms->tgts[cmd->target].data_goes_out = data_goes_out(cmd); ms->tgts[id].data_goes_out = data_goes_out(cmd);
ms->tgts[cmd->target].current_req = cmd; ms->tgts[id].current_req = cmd;
#if 1 #if 1
if (DEBUG_TARGET(cmd)) { if (DEBUG_TARGET(cmd)) {
int i; int i;
printk(KERN_DEBUG "mesh_start: %p ser=%lu tgt=%d cmd=", printk(KERN_DEBUG "mesh_start: %p ser=%lu tgt=%d cmd=",
cmd, cmd->serial_number, cmd->target); cmd, cmd->serial_number, id);
for (i = 0; i < cmd->cmd_len; ++i) for (i = 0; i < cmd->cmd_len; ++i)
printk(" %x", cmd->cmnd[i]); printk(" %x", cmd->cmnd[i]);
printk(" use_sg=%d buffer=%p bufflen=%u\n", printk(" use_sg=%d buffer=%p bufflen=%u\n",
...@@ -708,12 +706,12 @@ mesh_start_cmd(struct mesh_state *ms, Scsi_Cmnd *cmd) ...@@ -708,12 +706,12 @@ mesh_start_cmd(struct mesh_state *ms, Scsi_Cmnd *cmd)
ms->n_msgout = 0; ms->n_msgout = 0;
ms->last_n_msgout = 0; ms->last_n_msgout = 0;
ms->expect_reply = 0; ms->expect_reply = 0;
ms->conn_tgt = cmd->target; ms->conn_tgt = id;
ms->tgts[cmd->target].saved_ptr = 0; ms->tgts[id].saved_ptr = 0;
ms->stat = DID_OK; ms->stat = DID_OK;
ms->aborting = 0; ms->aborting = 0;
#ifdef MESH_DBG #ifdef MESH_DBG
ms->tgts[cmd->target].n_log = 0; ms->tgts[id].n_log = 0;
dlog(ms, "start cmd=%x", (int) cmd); dlog(ms, "start cmd=%x", (int) cmd);
#endif #endif
...@@ -1160,7 +1158,7 @@ cmd_complete(struct mesh_state *ms) ...@@ -1160,7 +1158,7 @@ cmd_complete(struct mesh_state *ms)
case selecting: case selecting:
dlog(ms, "Selecting phase at command completion",0); dlog(ms, "Selecting phase at command completion",0);
ms->msgout[0] = IDENTIFY(ALLOW_RESEL(ms->conn_tgt), ms->msgout[0] = IDENTIFY(ALLOW_RESEL(ms->conn_tgt),
(cmd? cmd->lun: 0)); (cmd? cmd->device->lun: 0));
ms->n_msgout = 1; ms->n_msgout = 1;
ms->expect_reply = 0; ms->expect_reply = 0;
if (ms->aborting) { if (ms->aborting) {
...@@ -1331,7 +1329,7 @@ reselected(struct mesh_state *ms) ...@@ -1331,7 +1329,7 @@ reselected(struct mesh_state *ms)
if (ms->request_q == NULL) if (ms->request_q == NULL)
ms->request_qtail = cmd; ms->request_qtail = cmd;
ms->request_q = cmd; ms->request_q = cmd;
tp = &ms->tgts[cmd->target]; tp = &ms->tgts[cmd->device->id];
tp->current_req = NULL; tp->current_req = NULL;
} }
break; break;
...@@ -1714,10 +1712,10 @@ handle_msgin(struct mesh_state *ms) ...@@ -1714,10 +1712,10 @@ handle_msgin(struct mesh_state *ms)
if (cmd == NULL) { if (cmd == NULL) {
do_abort(ms); do_abort(ms);
ms->msgphase = msg_out; ms->msgphase = msg_out;
} else if (code != cmd->lun + IDENTIFY_BASE) { } else if (code != cmd->device->lun + IDENTIFY_BASE) {
printk(KERN_WARNING "mesh: lun mismatch " printk(KERN_WARNING "mesh: lun mismatch "
"(%d != %d) on reselection from " "(%d != %d) on reselection from "
"target %d\n", i, cmd->lun, "target %d\n", i, cmd->device->lun,
ms->conn_tgt); ms->conn_tgt);
} }
break; break;
...@@ -1902,12 +1900,19 @@ halt_dma(struct mesh_state *ms) ...@@ -1902,12 +1900,19 @@ halt_dma(struct mesh_state *ms)
/* /*
* Work out whether we expect data to go out from the host adaptor or into it. * Work out whether we expect data to go out from the host adaptor or into it.
* (If this information is available from somewhere else in the scsi
* code, somebody please let me know :-)
*/ */
static int static int
data_goes_out(Scsi_Cmnd *cmd) data_goes_out(Scsi_Cmnd *cmd)
{ {
switch (cmd->sc_data_direction) {
case SCSI_DATA_WRITE:
return 1;
case SCSI_DATA_READ:
return 0;
}
/* for SCSI_DATA_UNKNOWN or SCSI_DATA_NONE, fall back on the
old method for now... */
switch (cmd->cmnd[0]) { switch (cmd->cmnd[0]) {
case CHANGE_DEFINITION: case CHANGE_DEFINITION:
case COMPARE: case COMPARE:
...@@ -2036,6 +2041,22 @@ static void dumpslog(struct mesh_state *ms) ...@@ -2036,6 +2041,22 @@ static void dumpslog(struct mesh_state *ms)
} }
#endif /* MESH_DBG */ #endif /* MESH_DBG */
static Scsi_Host_Template driver_template = SCSI_MESH; static Scsi_Host_Template driver_template = {
.proc_name = "mesh",
.name = "MESH",
.detect = mesh_detect,
.release = mesh_release,
.command = NULL,
.queuecommand = mesh_queue,
.eh_abort_handler = mesh_abort,
.eh_device_reset_handler = NULL,
.eh_bus_reset_handler = NULL,
.eh_host_reset_handler = mesh_host_reset,
.can_queue = 20,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
};
#include "scsi_module.c" #include "scsi_module.c"
...@@ -7,30 +7,6 @@ ...@@ -7,30 +7,6 @@
#ifndef _MESH_H #ifndef _MESH_H
#define _MESH_H #define _MESH_H
int mesh_detect(Scsi_Host_Template *);
int mesh_release(struct Scsi_Host *);
int mesh_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int mesh_abort(Scsi_Cmnd *);
int mesh_host_reset(Scsi_Cmnd *);
#define SCSI_MESH { \
.proc_name = "mesh", \
.name = "MESH", \
.detect = mesh_detect, \
.release = mesh_release, \
.command = NULL, \
.queuecommand = mesh_queue, \
.eh_abort_handler = mesh_abort, \
.eh_device_reset_handler = NULL, \
.eh_bus_reset_handler = NULL, \
.eh_host_reset_handler = mesh_host_reset, \
.can_queue = 20, \
.this_id = 7, \
.sg_tablesize = SG_ALL, \
.cmd_per_lun = 2, \
.use_clustering = DISABLE_CLUSTERING, \
}
/* /*
* Registers in the MESH controller. * Registers in the MESH controller.
*/ */
......
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