aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/mesh.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mesh.c')
-rw-r--r--drivers/scsi/mesh.c106
1 files changed, 52 insertions, 54 deletions
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index d6d2125f904..e8a04ae3276 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -18,13 +18,11 @@
* - retry arbitration if lost (unless higher levels do this for us)
* - power down the chip when no device is detected
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
@@ -35,7 +33,6 @@
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/prom.h>
-#include <asm/system.h>
#include <asm/irq.h>
#include <asm/hydra.h>
#include <asm/processor.h>
@@ -186,7 +183,7 @@ struct mesh_state {
* Driver is too messy, we need a few prototypes...
*/
static void mesh_done(struct mesh_state *ms, int start_next);
-static void mesh_interrupt(int irq, void *dev_id, struct pt_regs *ptregs);
+static void mesh_interrupt(struct mesh_state *ms);
static void cmd_complete(struct mesh_state *ms);
static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd);
static void halt_dma(struct mesh_state *ms);
@@ -417,12 +414,11 @@ static void mesh_start_cmd(struct mesh_state *ms, struct scsi_cmnd *cmd)
#if 1
if (DEBUG_TARGET(cmd)) {
int i;
- printk(KERN_DEBUG "mesh_start: %p ser=%lu tgt=%d cmd=",
- cmd, cmd->serial_number, id);
+ printk(KERN_DEBUG "mesh_start: %p tgt=%d cmd=", cmd, id);
for (i = 0; i < cmd->cmd_len; ++i)
printk(" %x", cmd->cmnd[i]);
printk(" use_sg=%d buffer=%p bufflen=%u\n",
- cmd->use_sg, cmd->request_buffer, cmd->request_bufflen);
+ scsi_sg_count(cmd), scsi_sglist(cmd), scsi_bufflen(cmd));
}
#endif
if (ms->dma_started)
@@ -467,7 +463,7 @@ static void mesh_start_cmd(struct mesh_state *ms, struct scsi_cmnd *cmd)
dlog(ms, "intr b4 arb, intr/exc/err/fc=%.8x",
MKWORD(mr->interrupt, mr->exception,
mr->error, mr->fifo_count));
- mesh_interrupt(0, (void *)ms, NULL);
+ mesh_interrupt(ms);
if (ms->phase != arbitrating)
return;
}
@@ -505,7 +501,7 @@ static void mesh_start_cmd(struct mesh_state *ms, struct scsi_cmnd *cmd)
dlog(ms, "intr after disresel, intr/exc/err/fc=%.8x",
MKWORD(mr->interrupt, mr->exception,
mr->error, mr->fifo_count));
- mesh_interrupt(0, (void *)ms, NULL);
+ mesh_interrupt(ms);
if (ms->phase != arbitrating)
return;
dlog(ms, "after intr after disresel, intr/exc/err/fc=%.8x",
@@ -603,13 +599,16 @@ static void mesh_done(struct mesh_state *ms, int start_next)
cmd->result += (cmd->SCp.Message << 8);
if (DEBUG_TARGET(cmd)) {
printk(KERN_DEBUG "mesh_done: result = %x, data_ptr=%d, buflen=%d\n",
- cmd->result, ms->data_ptr, cmd->request_bufflen);
+ cmd->result, ms->data_ptr, scsi_bufflen(cmd));
+#if 0
+ /* needs to use sg? */
if ((cmd->cmnd[0] == 0 || cmd->cmnd[0] == 0x12 || cmd->cmnd[0] == 3)
&& cmd->request_buffer != 0) {
unsigned char *b = cmd->request_buffer;
printk(KERN_DEBUG "buffer = %x %x %x %x %x %x %x %x\n",
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
}
+#endif
}
cmd->SCp.this_residual -= ms->data_ptr;
mesh_completed(ms, cmd);
@@ -1016,13 +1015,14 @@ static void handle_reset(struct mesh_state *ms)
out_8(&mr->sequence, SEQ_ENBRESEL);
}
-static irqreturn_t do_mesh_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
+static irqreturn_t do_mesh_interrupt(int irq, void *dev_id)
{
unsigned long flags;
- struct Scsi_Host *dev = ((struct mesh_state *)dev_id)->host;
+ struct mesh_state *ms = dev_id;
+ struct Scsi_Host *dev = ms->host;
spin_lock_irqsave(dev->host_lock, flags);
- mesh_interrupt(irq, dev_id, ptregs);
+ mesh_interrupt(ms);
spin_unlock_irqrestore(dev->host_lock, flags);
return IRQ_HANDLED;
}
@@ -1265,15 +1265,18 @@ static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd)
dcmds = ms->dma_cmds;
dtot = 0;
if (cmd) {
- cmd->SCp.this_residual = cmd->request_bufflen;
- if (cmd->use_sg > 0) {
- int nseg;
+ int nseg;
+
+ cmd->SCp.this_residual = scsi_bufflen(cmd);
+
+ nseg = scsi_dma_map(cmd);
+ BUG_ON(nseg < 0);
+
+ if (nseg) {
total = 0;
- scl = (struct scatterlist *) cmd->buffer;
off = ms->data_ptr;
- nseg = pci_map_sg(ms->pdev, scl, cmd->use_sg,
- cmd->sc_data_direction);
- for (i = 0; i <nseg; ++i, ++scl) {
+
+ scsi_for_each_sg(cmd, scl, nseg, i) {
u32 dma_addr = sg_dma_address(scl);
u32 dma_len = sg_dma_len(scl);
@@ -1292,16 +1295,6 @@ static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd)
dtot += dma_len - off;
off = 0;
}
- } else if (ms->data_ptr < cmd->request_bufflen) {
- dtot = cmd->request_bufflen - ms->data_ptr;
- if (dtot > 0xffff)
- panic("mesh: transfer size >= 64k");
- st_le16(&dcmds->req_count, dtot);
- /* XXX Use pci DMA API here ... */
- st_le32(&dcmds->phy_addr,
- virt_to_phys(cmd->request_buffer) + ms->data_ptr);
- dcmds->xfer_status = 0;
- ++dcmds;
}
}
if (dtot == 0) {
@@ -1356,18 +1349,14 @@ static void halt_dma(struct mesh_state *ms)
dumplog(ms, ms->conn_tgt);
dumpslog(ms);
#endif /* MESH_DBG */
- } else if (cmd && cmd->request_bufflen != 0 &&
- ms->data_ptr > cmd->request_bufflen) {
+ } else if (cmd && scsi_bufflen(cmd) &&
+ ms->data_ptr > scsi_bufflen(cmd)) {
printk(KERN_DEBUG "mesh: target %d overrun, "
"data_ptr=%x total=%x goes_out=%d\n",
- ms->conn_tgt, ms->data_ptr, cmd->request_bufflen,
+ ms->conn_tgt, ms->data_ptr, scsi_bufflen(cmd),
ms->tgts[ms->conn_tgt].data_goes_out);
}
- if (cmd->use_sg != 0) {
- struct scatterlist *sg;
- sg = (struct scatterlist *)cmd->request_buffer;
- pci_unmap_sg(ms->pdev, sg, cmd->use_sg, cmd->sc_data_direction);
- }
+ scsi_dma_unmap(cmd);
ms->dma_started = 0;
}
@@ -1636,7 +1625,7 @@ static void cmd_complete(struct mesh_state *ms)
* Called by midlayer with host locked to queue a new
* request
*/
-static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int mesh_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
struct mesh_state *ms;
@@ -1657,14 +1646,15 @@ static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(mesh_queue)
+
/*
* Called to handle interrupts, either call by the interrupt
* handler (do_mesh_interrupt) or by other functions in
* exceptional circumstances
*/
-static void mesh_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
+static void mesh_interrupt(struct mesh_state *ms)
{
- struct mesh_state *ms = (struct mesh_state *) dev_id;
volatile struct mesh_regs __iomem *mr = ms->mesh;
int intr;
@@ -1748,7 +1738,7 @@ static int mesh_host_reset(struct scsi_cmnd *cmd)
static void set_mesh_power(struct mesh_state *ms, int state)
{
- if (_machine != _MACH_Pmac)
+ if (!machine_is(powermac))
return;
if (state) {
pmac_call_feature(PMAC_FTR_MESH_ENABLE, macio_get_of_node(ms->mdev), 0, 1);
@@ -1757,16 +1747,24 @@ static void set_mesh_power(struct mesh_state *ms, int state)
pmac_call_feature(PMAC_FTR_MESH_ENABLE, macio_get_of_node(ms->mdev), 0, 0);
msleep(10);
}
-}
+}
#ifdef CONFIG_PM
-static int mesh_suspend(struct macio_dev *mdev, pm_message_t state)
+static int mesh_suspend(struct macio_dev *mdev, pm_message_t mesg)
{
struct mesh_state *ms = (struct mesh_state *)macio_get_drvdata(mdev);
unsigned long flags;
- if (state.event == mdev->ofdev.dev.power.power_state.event || state.event < 2)
+ switch (mesg.event) {
+ case PM_EVENT_SUSPEND:
+ case PM_EVENT_HIBERNATE:
+ case PM_EVENT_FREEZE:
+ break;
+ default:
+ return 0;
+ }
+ if (ms->phase == sleeping)
return 0;
scsi_block_requests(ms->host);
@@ -1781,8 +1779,6 @@ static int mesh_suspend(struct macio_dev *mdev, pm_message_t state)
disable_irq(ms->meshintr);
set_mesh_power(ms, 0);
- mdev->ofdev.dev.power.power_state = state;
-
return 0;
}
@@ -1791,7 +1787,7 @@ static int mesh_resume(struct macio_dev *mdev)
struct mesh_state *ms = (struct mesh_state *)macio_get_drvdata(mdev);
unsigned long flags;
- if (mdev->ofdev.dev.power.power_state.event == PM_EVENT_ON)
+ if (ms->phase != sleeping)
return 0;
set_mesh_power(ms, 1);
@@ -1802,8 +1798,6 @@ static int mesh_resume(struct macio_dev *mdev)
enable_irq(ms->meshintr);
scsi_unblock_requests(ms->host);
- mdev->ofdev.dev.power.power_state.event = PM_EVENT_ON;
-
return 0;
}
@@ -1851,7 +1845,8 @@ static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
struct device_node *mesh = macio_get_of_node(mdev);
struct pci_dev* pdev = macio_get_pci_dev(mdev);
- int tgt, *cfp, minper;
+ int tgt, minper;
+ const int *cfp;
struct mesh_state *ms;
struct Scsi_Host *mesh_host;
void *dma_cmd_space;
@@ -1940,7 +1935,7 @@ static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
ms->tgts[tgt].current_req = NULL;
}
- if ((cfp = (int *) get_property(mesh, "clock-frequency", NULL)))
+ if ((cfp = of_get_property(mesh, "clock-frequency", NULL)))
ms->clk_freq = *cfp;
else {
printk(KERN_INFO "mesh: assuming 50MHz clock frequency\n");
@@ -2041,8 +2036,11 @@ MODULE_DEVICE_TABLE (of, mesh_match);
static struct macio_driver mesh_driver =
{
- .name = "mesh",
- .match_table = mesh_match,
+ .driver = {
+ .name = "mesh",
+ .owner = THIS_MODULE,
+ .of_match_table = mesh_match,
+ },
.probe = mesh_probe,
.remove = mesh_remove,
.shutdown = mesh_shutdown,