^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * SCSI low-level driver for the MESH (Macintosh Enhanced SCSI Hardware)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * bus adaptor found on Power Macintosh computers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * We assume the MESH is connected to a DBDMA (descriptor-based DMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Paul Mackerras, August 1996.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 1996 Paul Mackerras.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Apr. 21 2002 - BenH Rework bus reset code for new error handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Add delay after initial bus reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Add module parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Sep. 27 2003 - BenH Move to new driver model, fix some write posting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * issues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * To do:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * - handle aborts correctly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * - retry arbitration if lost (unless higher levels do this for us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * - power down the chip when no device is detected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/dbdma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <asm/hydra.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <asm/machdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <asm/pmac_feature.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <asm/macio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include "mesh.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #undef KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define KERN_DEBUG KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) MODULE_AUTHOR("Paul Mackerras (paulus@samba.org)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) MODULE_DESCRIPTION("PowerMac MESH SCSI driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int sync_rate = CONFIG_SCSI_MESH_SYNC_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int sync_targets = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static int resel_targets = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int debug_targets = 0; /* print debug for these targets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int init_reset_delay = CONFIG_SCSI_MESH_RESET_DELAY_MS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) module_param(sync_rate, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) MODULE_PARM_DESC(sync_rate, "Synchronous rate (0..10, 0=async)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) module_param(sync_targets, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) MODULE_PARM_DESC(sync_targets, "Bitmask of targets allowed to set synchronous");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) module_param(resel_targets, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) MODULE_PARM_DESC(resel_targets, "Bitmask of targets allowed to set disconnect");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) module_param(debug_targets, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MODULE_PARM_DESC(debug_targets, "Bitmask of debugged targets");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) module_param(init_reset_delay, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MODULE_PARM_DESC(init_reset_delay, "Initial bus reset delay (0=no reset)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static int mesh_sync_period = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static int mesh_sync_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static unsigned char use_active_neg = 0; /* bit mask for SEQ_ACTIVE_NEG if used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define ALLOW_SYNC(tgt) ((sync_targets >> (tgt)) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define ALLOW_RESEL(tgt) ((resel_targets >> (tgt)) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define ALLOW_DEBUG(tgt) ((debug_targets >> (tgt)) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define DEBUG_TARGET(cmd) ((cmd) && ALLOW_DEBUG((cmd)->device->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #undef MESH_DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define N_DBG_LOG 50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define N_DBG_SLOG 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define NUM_DBG_EVENTS 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #undef DBG_USE_TB /* bombs on 601 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct dbglog {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) char *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u32 tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) u8 phase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) u8 bs0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) u8 bs1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) u8 tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) enum mesh_phase {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) idle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) arbitrating,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) selecting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) commanding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) dataing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) statusing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) busfreeing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) disconnecting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) reselecting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) sleeping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) enum msg_phase {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) msg_none,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) msg_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) msg_out_xxx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) msg_out_last,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) msg_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) msg_in_bad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) enum sdtr_phase {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) do_sdtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) sdtr_sent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) sdtr_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct mesh_target {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) enum sdtr_phase sdtr_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int sync_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int data_goes_out; /* guess as to data direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct scsi_cmnd *current_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 saved_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #ifdef MESH_DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int log_ix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int n_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct dbglog log[N_DBG_LOG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct mesh_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) volatile struct mesh_regs __iomem *mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int meshintr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) volatile struct dbdma_regs __iomem *dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int dmaintr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct mesh_state *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct scsi_cmnd *request_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct scsi_cmnd *request_qtail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) enum mesh_phase phase; /* what we're currently trying to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) enum msg_phase msgphase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int conn_tgt; /* target we're connected to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct scsi_cmnd *current_req; /* req we're currently working on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int data_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int dma_started;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int dma_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int aborting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int expect_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int n_msgin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u8 msgin[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int n_msgout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int last_n_msgout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u8 msgout[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct dbdma_cmd *dma_cmds; /* space for dbdma commands, aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dma_addr_t dma_cmd_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) void *dma_cmd_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int dma_cmd_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int clk_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct mesh_target tgts[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct macio_dev *mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct pci_dev* pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #ifdef MESH_DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int log_ix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int n_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct dbglog log[N_DBG_SLOG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * Driver is too messy, we need a few prototypes...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static void mesh_done(struct mesh_state *ms, int start_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static void mesh_interrupt(struct mesh_state *ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static void cmd_complete(struct mesh_state *ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static void halt_dma(struct mesh_state *ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static void phase_mismatch(struct mesh_state *ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Some debugging & logging routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #ifdef MESH_DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static inline u32 readtb(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u32 tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #ifdef DBG_USE_TB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* Beware: if you enable this, it will crash on 601s. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) asm ("mftb %0" : "=r" (tb) : );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) tb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static void dlog(struct mesh_state *ms, char *fmt, int a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct mesh_target *tp = &ms->tgts[ms->conn_tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct dbglog *tlp, *slp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) tlp = &tp->log[tp->log_ix];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) slp = &ms->log[ms->log_ix];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) tlp->fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) tlp->tb = readtb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) tlp->phase = (ms->msgphase << 4) + ms->phase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) tlp->bs0 = ms->mesh->bus_status0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) tlp->bs1 = ms->mesh->bus_status1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) tlp->tgt = ms->conn_tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) tlp->d = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) *slp = *tlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (++tp->log_ix >= N_DBG_LOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) tp->log_ix = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (tp->n_log < N_DBG_LOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ++tp->n_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (++ms->log_ix >= N_DBG_SLOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ms->log_ix = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (ms->n_log < N_DBG_SLOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ++ms->n_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static void dumplog(struct mesh_state *ms, int t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct mesh_target *tp = &ms->tgts[t];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct dbglog *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (tp->n_log == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) i = tp->log_ix - tp->n_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (i < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) i += N_DBG_LOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) tp->n_log = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) lp = &tp->log[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) printk(KERN_DEBUG "mesh log %d: bs=%.2x%.2x ph=%.2x ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) t, lp->bs1, lp->bs0, lp->phase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #ifdef DBG_USE_TB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) printk("tb=%10u ", lp->tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) printk(lp->fmt, lp->d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (++i >= N_DBG_LOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) } while (i != tp->log_ix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static void dumpslog(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct dbglog *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (ms->n_log == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) i = ms->log_ix - ms->n_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (i < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) i += N_DBG_SLOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ms->n_log = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) lp = &ms->log[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) printk(KERN_DEBUG "mesh log: bs=%.2x%.2x ph=%.2x t%d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) lp->bs1, lp->bs0, lp->phase, lp->tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #ifdef DBG_USE_TB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) printk("tb=%10u ", lp->tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) printk(lp->fmt, lp->d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (++i >= N_DBG_SLOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) } while (i != ms->log_ix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static inline void dlog(struct mesh_state *ms, char *fmt, int a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static inline void dumplog(struct mesh_state *ms, int tgt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static inline void dumpslog(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) #endif /* MESH_DBG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #define MKWORD(a, b, c, d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) mesh_dump_regs(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) volatile struct dbdma_regs __iomem *md = ms->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct mesh_target *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) printk(KERN_DEBUG "mesh: state at %p, regs at %p, dma at %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ms, mr, md);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) printk(KERN_DEBUG " ct=%4x seq=%2x bs=%4x fc=%2x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) "exc=%2x err=%2x im=%2x int=%2x sp=%2x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) (mr->count_hi << 8) + mr->count_lo, mr->sequence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) (mr->bus_status1 << 8) + mr->bus_status0, mr->fifo_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) mr->exception, mr->error, mr->intr_mask, mr->interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) mr->sync_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) while(in_8(&mr->fifo_count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) printk(KERN_DEBUG " fifo data=%.2x\n",in_8(&mr->fifo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) printk(KERN_DEBUG " dma stat=%x cmdptr=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) in_le32(&md->status), in_le32(&md->cmdptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) printk(KERN_DEBUG " phase=%d msgphase=%d conn_tgt=%d data_ptr=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ms->phase, ms->msgphase, ms->conn_tgt, ms->data_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) printk(KERN_DEBUG " dma_st=%d dma_ct=%d n_msgout=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ms->dma_started, ms->dma_count, ms->n_msgout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) for (t = 0; t < 8; ++t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) tp = &ms->tgts[t];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (tp->current_req == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) printk(KERN_DEBUG " target %d: req=%p goes_out=%d saved_ptr=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) t, tp->current_req, tp->data_goes_out, tp->saved_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * Flush write buffers on the bus path to the mesh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static inline void mesh_flush_io(volatile struct mesh_regs __iomem *mr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) (void)in_8(&mr->mesh_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * Complete a SCSI command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static void mesh_completed(struct mesh_state *ms, struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) (*cmd->scsi_done)(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* Called with meshinterrupt disabled, initialize the chipset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * and eventually do the initial bus reset. The lock must not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * held since we can schedule.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static void mesh_init(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) volatile struct dbdma_regs __iomem *md = ms->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* Reset controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) out_le32(&md->control, (RUN|PAUSE|FLUSH|WAKE) << 16); /* stop dma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) out_8(&mr->exception, 0xff); /* clear all exception bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) out_8(&mr->error, 0xff); /* clear all error bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) out_8(&mr->sequence, SEQ_RESETMESH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) out_8(&mr->intr_mask, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) out_8(&mr->source_id, ms->host->this_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) out_8(&mr->sel_timeout, 25); /* 250ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) out_8(&mr->sync_params, ASYNC_PARAMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (init_reset_delay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) printk(KERN_INFO "mesh: performing initial bus reset...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /* Reset bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) out_8(&mr->bus_status1, BS1_RST); /* assert RST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) udelay(30); /* leave it on for >= 25us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) out_8(&mr->bus_status1, 0); /* negate RST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* Wait for bus to come back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) msleep(init_reset_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* Reconfigure controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) out_8(&mr->interrupt, 0xff); /* clear all interrupt bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) out_8(&mr->sequence, SEQ_FLUSHFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) out_8(&mr->sync_params, ASYNC_PARAMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) out_8(&mr->sequence, SEQ_ENBRESEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ms->phase = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ms->msgphase = msg_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static void mesh_start_cmd(struct mesh_state *ms, struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) int t, id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) id = cmd->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ms->current_req = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ms->tgts[id].data_goes_out = cmd->sc_data_direction == DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ms->tgts[id].current_req = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (DEBUG_TARGET(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) printk(KERN_DEBUG "mesh_start: %p tgt=%d cmd=", cmd, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) for (i = 0; i < cmd->cmd_len; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) printk(" %x", cmd->cmnd[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) printk(" use_sg=%d buffer=%p bufflen=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) scsi_sg_count(cmd), scsi_sglist(cmd), scsi_bufflen(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (ms->dma_started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) panic("mesh: double DMA start !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ms->phase = arbitrating;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) ms->msgphase = msg_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ms->data_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ms->dma_started = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ms->n_msgout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ms->last_n_msgout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ms->expect_reply = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ms->conn_tgt = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ms->tgts[id].saved_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ms->stat = DID_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ms->aborting = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) #ifdef MESH_DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ms->tgts[id].n_log = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dlog(ms, "start cmd=%x", (int) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* Off we go */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) dlog(ms, "about to arb, intr/exc/err/fc=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) MKWORD(mr->interrupt, mr->exception, mr->error, mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) out_8(&mr->interrupt, INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) out_8(&mr->sequence, SEQ_ENBRESEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (in_8(&mr->bus_status1) & (BS1_BSY | BS1_SEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * Some other device has the bus or is arbitrating for it -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * probably a target which is about to reselect us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) dlog(ms, "busy b4 arb, intr/exc/err/fc=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) MKWORD(mr->interrupt, mr->exception,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) mr->error, mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) for (t = 100; t > 0; --t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if ((in_8(&mr->bus_status1) & (BS1_BSY | BS1_SEL)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (in_8(&mr->interrupt) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dlog(ms, "intr b4 arb, intr/exc/err/fc=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) MKWORD(mr->interrupt, mr->exception,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) mr->error, mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) mesh_interrupt(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (ms->phase != arbitrating)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (in_8(&mr->bus_status1) & (BS1_BSY | BS1_SEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* XXX should try again in a little while */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ms->stat = DID_BUS_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ms->phase = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) mesh_done(ms, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * Apparently the mesh has a bug where it will assert both its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * own bit and the target's bit on the bus during arbitration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) out_8(&mr->dest_id, mr->source_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * There appears to be a race with reselection sometimes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * where a target reselects us just as we issue the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * arbitrate command. It seems that then the arbitrate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * command just hangs waiting for the bus to be free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * without giving us a reselection exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * The only way I have found to get it to respond correctly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * is this: disable reselection before issuing the arbitrate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * command, then after issuing it, if it looks like a target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * is trying to reselect us, reset the mesh and then enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * reselection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) out_8(&mr->sequence, SEQ_DISRESEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (in_8(&mr->interrupt) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) dlog(ms, "intr after disresel, intr/exc/err/fc=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) MKWORD(mr->interrupt, mr->exception,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) mr->error, mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) mesh_interrupt(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (ms->phase != arbitrating)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) dlog(ms, "after intr after disresel, intr/exc/err/fc=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) MKWORD(mr->interrupt, mr->exception,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) mr->error, mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) out_8(&mr->sequence, SEQ_ARBITRATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) for (t = 230; t > 0; --t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (in_8(&mr->interrupt) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) dlog(ms, "after arb, intr/exc/err/fc=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) MKWORD(mr->interrupt, mr->exception, mr->error, mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (in_8(&mr->interrupt) == 0 && (in_8(&mr->bus_status1) & BS1_SEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) && (in_8(&mr->bus_status0) & BS0_IO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /* looks like a reselection - try resetting the mesh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) dlog(ms, "resel? after arb, intr/exc/err/fc=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) MKWORD(mr->interrupt, mr->exception, mr->error, mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) out_8(&mr->sequence, SEQ_RESETMESH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) out_8(&mr->interrupt, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) out_8(&mr->intr_mask, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) out_8(&mr->sequence, SEQ_ENBRESEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) for (t = 10; t > 0 && in_8(&mr->interrupt) == 0; --t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) dlog(ms, "tried reset after arb, intr/exc/err/fc=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) MKWORD(mr->interrupt, mr->exception, mr->error, mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) #ifndef MESH_MULTIPLE_HOSTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (in_8(&mr->interrupt) == 0 && (in_8(&mr->bus_status1) & BS1_SEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) && (in_8(&mr->bus_status0) & BS0_IO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) printk(KERN_ERR "mesh: controller not responding"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) " to reselection!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * If this is a target reselecting us, and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * mesh isn't responding, the higher levels of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * the scsi code will eventually time out and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * reset the bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * Start the next command for a MESH.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * Should be called with interrupts disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static void mesh_start(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct scsi_cmnd *cmd, *prev, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (ms->phase != idle || ms->current_req != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) printk(KERN_ERR "inappropriate mesh_start (phase=%d, ms=%p)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) ms->phase, ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) while (ms->phase == idle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) for (cmd = ms->request_q; ; cmd = (struct scsi_cmnd *) cmd->host_scribble) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (cmd == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (ms->tgts[cmd->device->id].current_req == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) prev = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) next = (struct scsi_cmnd *) cmd->host_scribble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (prev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ms->request_q = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) prev->host_scribble = (void *) next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (next == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ms->request_qtail = prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) mesh_start_cmd(ms, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static void mesh_done(struct mesh_state *ms, int start_next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct mesh_target *tp = &ms->tgts[ms->conn_tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) cmd = ms->current_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) ms->current_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) tp->current_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) cmd->result = (ms->stat << 16) | cmd->SCp.Status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (ms->stat == DID_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) cmd->result |= cmd->SCp.Message << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (DEBUG_TARGET(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) printk(KERN_DEBUG "mesh_done: result = %x, data_ptr=%d, buflen=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) cmd->result, ms->data_ptr, scsi_bufflen(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* needs to use sg? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if ((cmd->cmnd[0] == 0 || cmd->cmnd[0] == 0x12 || cmd->cmnd[0] == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) && cmd->request_buffer != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) unsigned char *b = cmd->request_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) printk(KERN_DEBUG "buffer = %x %x %x %x %x %x %x %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) cmd->SCp.this_residual -= ms->data_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) mesh_completed(ms, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (start_next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) out_8(&ms->mesh->sequence, SEQ_ENBRESEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) mesh_flush_io(ms->mesh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ms->phase = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) mesh_start(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static inline void add_sdtr_msg(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int i = ms->n_msgout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ms->msgout[i] = EXTENDED_MESSAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ms->msgout[i+1] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ms->msgout[i+2] = EXTENDED_SDTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ms->msgout[i+3] = mesh_sync_period/4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ms->msgout[i+4] = (ALLOW_SYNC(ms->conn_tgt)? mesh_sync_offset: 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ms->n_msgout = i + 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static void set_sdtr(struct mesh_state *ms, int period, int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct mesh_target *tp = &ms->tgts[ms->conn_tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) int v, tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) tp->sdtr_state = sdtr_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (offset == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* asynchronous */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (SYNC_OFF(tp->sync_params))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) printk(KERN_INFO "mesh: target %d now asynchronous\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) tp->sync_params = ASYNC_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) out_8(&mr->sync_params, ASYNC_PARAMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * We need to compute ceil(clk_freq * period / 500e6) - 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * without incurring overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) v = (ms->clk_freq / 5000) * period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (v <= 250000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /* special case: sync_period == 5 * clk_period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) v = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /* units of tr are 100kB/s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) tr = (ms->clk_freq + 250000) / 500000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /* sync_period == (v + 2) * 2 * clk_period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) v = (v + 99999) / 100000 - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (v > 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) v = 15; /* oops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) tr = ((ms->clk_freq / (v + 2)) + 199999) / 200000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (offset > 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) offset = 15; /* can't happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) tp->sync_params = SYNC_PARAMS(offset, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) out_8(&mr->sync_params, tp->sync_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) printk(KERN_INFO "mesh: target %d synchronous at %d.%d MB/s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ms->conn_tgt, tr/10, tr%10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static void start_phase(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) int i, seq, nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) volatile struct dbdma_regs __iomem *md = ms->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) struct scsi_cmnd *cmd = ms->current_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct mesh_target *tp = &ms->tgts[ms->conn_tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) dlog(ms, "start_phase nmo/exc/fc/seq = %.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) MKWORD(ms->n_msgout, mr->exception, mr->fifo_count, mr->sequence));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) out_8(&mr->interrupt, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) seq = use_active_neg + (ms->n_msgout? SEQ_ATN: 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) switch (ms->msgphase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) case msg_none:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) case msg_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) out_8(&mr->count_hi, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) out_8(&mr->count_lo, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) out_8(&mr->sequence, SEQ_MSGIN + seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ms->n_msgin = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) case msg_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * To make sure ATN drops before we assert ACK for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * the last byte of the message, we have to do the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * last byte specially.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (ms->n_msgout <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) printk(KERN_ERR "mesh: msg_out but n_msgout=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ms->n_msgout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) mesh_dump_regs(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ms->msgphase = msg_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (ALLOW_DEBUG(ms->conn_tgt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) printk(KERN_DEBUG "mesh: sending %d msg bytes:",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ms->n_msgout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) for (i = 0; i < ms->n_msgout; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) printk(" %x", ms->msgout[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) dlog(ms, "msgout msg=%.8x", MKWORD(ms->n_msgout, ms->msgout[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ms->msgout[1], ms->msgout[2]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) out_8(&mr->count_hi, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) out_8(&mr->sequence, SEQ_FLUSHFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * If ATN is not already asserted, we assert it, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * issue a SEQ_MSGOUT to get the mesh to drop ACK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if ((in_8(&mr->bus_status0) & BS0_ATN) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) dlog(ms, "bus0 was %.2x explicitly asserting ATN", mr->bus_status0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) out_8(&mr->bus_status0, BS0_ATN); /* explicit ATN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) out_8(&mr->count_lo, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) out_8(&mr->sequence, SEQ_MSGOUT + seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) out_8(&mr->bus_status0, 0); /* release explicit ATN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) dlog(ms,"hace: after explicit ATN bus0=%.2x",mr->bus_status0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (ms->n_msgout == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * We can't issue the SEQ_MSGOUT without ATN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * until the target has asserted REQ. The logic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * in cmd_complete handles both situations:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * REQ already asserted or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) cmd_complete(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) out_8(&mr->count_lo, ms->n_msgout - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) out_8(&mr->sequence, SEQ_MSGOUT + seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) for (i = 0; i < ms->n_msgout - 1; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) out_8(&mr->fifo, ms->msgout[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) printk(KERN_ERR "mesh bug: start_phase msgphase=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) ms->msgphase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) switch (ms->phase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) case selecting:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) out_8(&mr->dest_id, ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) out_8(&mr->sequence, SEQ_SELECT + SEQ_ATN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) case commanding:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) out_8(&mr->sync_params, tp->sync_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) out_8(&mr->count_hi, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) out_8(&mr->count_lo, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) out_8(&mr->sequence, SEQ_COMMAND + seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) for (i = 0; i < cmd->cmd_len; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) out_8(&mr->fifo, cmd->cmnd[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) out_8(&mr->count_lo, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) out_8(&mr->sequence, SEQ_COMMAND + seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) for (i = 0; i < 6; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) out_8(&mr->fifo, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) case dataing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* transfer data, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (!ms->dma_started) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) set_dma_cmds(ms, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) out_le32(&md->cmdptr, virt_to_phys(ms->dma_cmds));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) out_le32(&md->control, (RUN << 16) | RUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) ms->dma_started = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) nb = ms->dma_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (nb > 0xfff0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) nb = 0xfff0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) ms->dma_count -= nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) ms->data_ptr += nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) out_8(&mr->count_lo, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) out_8(&mr->count_hi, nb >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) out_8(&mr->sequence, (tp->data_goes_out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) SEQ_DATAOUT: SEQ_DATAIN) + SEQ_DMA_MODE + seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) case statusing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) out_8(&mr->count_hi, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) out_8(&mr->count_lo, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) out_8(&mr->sequence, SEQ_STATUS + seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) case busfreeing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) case disconnecting:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) out_8(&mr->sequence, SEQ_ENBRESEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) dlog(ms, "enbresel intr/exc/err/fc=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) MKWORD(mr->interrupt, mr->exception, mr->error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) out_8(&mr->sequence, SEQ_BUSFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) printk(KERN_ERR "mesh: start_phase called with phase=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ms->phase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) dumpslog(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static inline void get_msgin(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) int i, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) n = mr->fifo_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (n != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) i = ms->n_msgin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ms->n_msgin = i + n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) for (; n > 0; --n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) ms->msgin[i++] = in_8(&mr->fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) static inline int msgin_length(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) int b, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) n = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (ms->n_msgin > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) b = ms->msgin[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (b == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /* extended message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) n = ms->n_msgin < 2? 2: ms->msgin[1] + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) } else if (0x20 <= b && b <= 0x2f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /* 2-byte message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) n = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static void reselected(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct mesh_target *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) int b, t, prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) switch (ms->phase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) case idle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) case arbitrating:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if ((cmd = ms->current_req) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /* put the command back on the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) cmd->host_scribble = (void *) ms->request_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (ms->request_q == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) ms->request_qtail = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) ms->request_q = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) tp = &ms->tgts[cmd->device->id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) tp->current_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) case busfreeing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ms->phase = reselecting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) mesh_done(ms, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) case disconnecting:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) printk(KERN_ERR "mesh: reselected in phase %d/%d tgt %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ms->msgphase, ms->phase, ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) dumplog(ms, ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) dumpslog(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (ms->dma_started) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) printk(KERN_ERR "mesh: reselected with DMA started !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) halt_dma(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) ms->current_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) ms->phase = dataing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ms->msgphase = msg_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) ms->n_msgout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) ms->last_n_msgout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) prev = ms->conn_tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * We seem to get abortive reselections sometimes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) while ((in_8(&mr->bus_status1) & BS1_BSY) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) static int mesh_aborted_resels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) mesh_aborted_resels++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) out_8(&mr->interrupt, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) out_8(&mr->sequence, SEQ_ENBRESEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) dlog(ms, "extra resel err/exc/fc = %.6x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) MKWORD(0, mr->error, mr->exception, mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) out_8(&mr->interrupt, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) out_8(&mr->sequence, SEQ_ENBRESEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) out_8(&mr->sync_params, ASYNC_PARAMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * Find out who reselected us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (in_8(&mr->fifo_count) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) printk(KERN_ERR "mesh: reselection but nothing in fifo?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) ms->conn_tgt = ms->host->this_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) goto bogus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) /* get the last byte in the fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) b = in_8(&mr->fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) dlog(ms, "reseldata %x", b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) } while (in_8(&mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) for (t = 0; t < 8; ++t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if ((b & (1 << t)) != 0 && t != ms->host->this_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (b != (1 << t) + (1 << ms->host->this_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) printk(KERN_ERR "mesh: bad reselection data %x\n", b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) ms->conn_tgt = ms->host->this_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) goto bogus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * Set up to continue with that target's transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ms->conn_tgt = t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) tp = &ms->tgts[t];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) out_8(&mr->sync_params, tp->sync_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (ALLOW_DEBUG(t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) printk(KERN_DEBUG "mesh: reselected by target %d\n", t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) printk(KERN_DEBUG "mesh: saved_ptr=%x goes_out=%d cmd=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) tp->saved_ptr, tp->data_goes_out, tp->current_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) ms->current_req = tp->current_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (tp->current_req == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) printk(KERN_ERR "mesh: reselected by tgt %d but no cmd!\n", t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) goto bogus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ms->data_ptr = tp->saved_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) dlog(ms, "resel prev tgt=%d", prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) dlog(ms, "resel err/exc=%.4x", MKWORD(0, 0, mr->error, mr->exception));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) start_phase(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) bogus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) dumplog(ms, ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) dumpslog(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) ms->data_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) ms->aborting = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) start_phase(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static void do_abort(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) ms->msgout[0] = ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) ms->n_msgout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ms->aborting = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) ms->stat = DID_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) dlog(ms, "abort", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static void handle_reset(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) int tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) struct mesh_target *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) for (tgt = 0; tgt < 8; ++tgt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) tp = &ms->tgts[tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if ((cmd = tp->current_req) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) cmd->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) tp->current_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) mesh_completed(ms, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) ms->tgts[tgt].sdtr_state = do_sdtr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ms->tgts[tgt].sync_params = ASYNC_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) ms->current_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) while ((cmd = ms->request_q) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) ms->request_q = (struct scsi_cmnd *) cmd->host_scribble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) cmd->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) mesh_completed(ms, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) ms->phase = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) ms->msgphase = msg_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) out_8(&mr->interrupt, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) out_8(&mr->sequence, SEQ_FLUSHFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) out_8(&mr->sync_params, ASYNC_PARAMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) out_8(&mr->sequence, SEQ_ENBRESEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static irqreturn_t do_mesh_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) struct mesh_state *ms = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) struct Scsi_Host *dev = ms->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) spin_lock_irqsave(dev->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) mesh_interrupt(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) spin_unlock_irqrestore(dev->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) static void handle_error(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) int err, exc, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) err = in_8(&mr->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) exc = in_8(&mr->exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) out_8(&mr->interrupt, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) dlog(ms, "error err/exc/fc/cl=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) MKWORD(err, exc, mr->fifo_count, mr->count_lo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (err & ERR_SCSIRESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /* SCSI bus was reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) printk(KERN_INFO "mesh: SCSI bus reset detected: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) "waiting for end...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) while ((in_8(&mr->bus_status1) & BS1_RST) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) printk("done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (ms->dma_started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) halt_dma(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) handle_reset(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /* request_q is empty, no point in mesh_start() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (err & ERR_UNEXPDISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* Unexpected disconnect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (exc & EXC_RESELECTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) reselected(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (!ms->aborting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) printk(KERN_WARNING "mesh: target %d aborted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) dumplog(ms, ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) dumpslog(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) out_8(&mr->interrupt, INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) ms->stat = DID_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) mesh_done(ms, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (err & ERR_PARITY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (ms->msgphase == msg_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) printk(KERN_ERR "mesh: msg parity error, target %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ms->msgout[0] = MSG_PARITY_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) ms->n_msgout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) ms->msgphase = msg_in_bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) cmd_complete(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (ms->stat == DID_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) printk(KERN_ERR "mesh: parity error, target %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) ms->stat = DID_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) count = (mr->count_hi << 8) + mr->count_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) cmd_complete(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /* reissue the data transfer command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) out_8(&mr->sequence, mr->sequence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (err & ERR_SEQERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (exc & EXC_RESELECTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /* This can happen if we issue a command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) get the bus just after the target reselects us. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static int mesh_resel_seqerr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) mesh_resel_seqerr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) reselected(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (exc == EXC_PHASEMM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) static int mesh_phasemm_seqerr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) mesh_phasemm_seqerr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) phase_mismatch(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) printk(KERN_ERR "mesh: sequence error (err=%x exc=%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) err, exc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) printk(KERN_ERR "mesh: unknown error %x (exc=%x)\n", err, exc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) mesh_dump_regs(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) dumplog(ms, ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (ms->phase > selecting && (in_8(&mr->bus_status1) & BS1_BSY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* try to do what the target wants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) do_abort(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) phase_mismatch(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) ms->stat = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) mesh_done(ms, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) static void handle_exception(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) int exc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) exc = in_8(&mr->exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) out_8(&mr->interrupt, INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (exc & EXC_RESELECTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static int mesh_resel_exc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) mesh_resel_exc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) reselected(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) } else if (exc == EXC_ARBLOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) printk(KERN_DEBUG "mesh: lost arbitration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) ms->stat = DID_BUS_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) mesh_done(ms, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) } else if (exc == EXC_SELTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) /* selection timed out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) ms->stat = DID_BAD_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) mesh_done(ms, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) } else if (exc == EXC_PHASEMM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) /* target wants to do something different:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) find out what it wants and do it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) phase_mismatch(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) printk(KERN_ERR "mesh: can't cope with exception %x\n", exc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) mesh_dump_regs(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) dumplog(ms, ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) do_abort(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) phase_mismatch(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static void handle_msgin(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) int i, code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) struct scsi_cmnd *cmd = ms->current_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct mesh_target *tp = &ms->tgts[ms->conn_tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (ms->n_msgin == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) code = ms->msgin[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (ALLOW_DEBUG(ms->conn_tgt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) printk(KERN_DEBUG "got %d message bytes:", ms->n_msgin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) for (i = 0; i < ms->n_msgin; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) printk(" %x", ms->msgin[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) dlog(ms, "msgin msg=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) MKWORD(ms->n_msgin, code, ms->msgin[1], ms->msgin[2]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) ms->expect_reply = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) ms->n_msgout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (ms->n_msgin < msgin_length(ms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) cmd->SCp.Message = code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) case COMMAND_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) case EXTENDED_MESSAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) switch (ms->msgin[2]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) case EXTENDED_MODIFY_DATA_POINTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) ms->data_ptr += (ms->msgin[3] << 24) + ms->msgin[6]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) + (ms->msgin[4] << 16) + (ms->msgin[5] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) case EXTENDED_SDTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (tp->sdtr_state != sdtr_sent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /* reply with an SDTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) add_sdtr_msg(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /* limit period to at least his value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) offset to no more than his */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (ms->msgout[3] < ms->msgin[3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) ms->msgout[3] = ms->msgin[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (ms->msgout[4] > ms->msgin[4])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) ms->msgout[4] = ms->msgin[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) set_sdtr(ms, ms->msgout[3], ms->msgout[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) ms->msgphase = msg_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) set_sdtr(ms, ms->msgin[3], ms->msgin[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) case SAVE_POINTERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) tp->saved_ptr = ms->data_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) case RESTORE_POINTERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) ms->data_ptr = tp->saved_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) case DISCONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) ms->phase = disconnecting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) case ABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) case MESSAGE_REJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (tp->sdtr_state == sdtr_sent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) set_sdtr(ms, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) case NOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (IDENTIFY_BASE <= code && code <= IDENTIFY_BASE + 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (cmd == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) do_abort(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) ms->msgphase = msg_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) } else if (code != cmd->device->lun + IDENTIFY_BASE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) printk(KERN_WARNING "mesh: lun mismatch "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) "(%d != %llu) on reselection from "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) "target %d\n", code - IDENTIFY_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) cmd->device->lun, ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) goto reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) reject:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) printk(KERN_WARNING "mesh: rejecting message from target %d:",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) for (i = 0; i < ms->n_msgin; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) printk(" %x", ms->msgin[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) ms->msgout[0] = MESSAGE_REJECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) ms->n_msgout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) ms->msgphase = msg_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) * Set up DMA commands for transferring data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) int i, dma_cmd, total, off, dtot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) struct scatterlist *scl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) struct dbdma_cmd *dcmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) dma_cmd = ms->tgts[ms->conn_tgt].data_goes_out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) OUTPUT_MORE: INPUT_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) dcmds = ms->dma_cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) dtot = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) cmd->SCp.this_residual = scsi_bufflen(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) nseg = scsi_dma_map(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) BUG_ON(nseg < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (nseg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) off = ms->data_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) scsi_for_each_sg(cmd, scl, nseg, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) u32 dma_addr = sg_dma_address(scl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) u32 dma_len = sg_dma_len(scl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) total += scl->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (off >= dma_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) off -= dma_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (dma_len > 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) panic("mesh: scatterlist element >= 64k");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) dcmds->req_count = cpu_to_le16(dma_len - off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) dcmds->command = cpu_to_le16(dma_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) dcmds->phy_addr = cpu_to_le32(dma_addr + off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) dcmds->xfer_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) ++dcmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) dtot += dma_len - off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (dtot == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) /* Either the target has overrun our buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) or the caller didn't provide a buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) static char mesh_extra_buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) dtot = sizeof(mesh_extra_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) dcmds->req_count = cpu_to_le16(dtot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) dcmds->phy_addr = cpu_to_le32(virt_to_phys(mesh_extra_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) dcmds->xfer_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) ++dcmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) dma_cmd += OUTPUT_LAST - OUTPUT_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) dcmds[-1].command = cpu_to_le16(dma_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) memset(dcmds, 0, sizeof(*dcmds));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) dcmds->command = cpu_to_le16(DBDMA_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) ms->dma_count = dtot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) static void halt_dma(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) volatile struct dbdma_regs __iomem *md = ms->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) struct scsi_cmnd *cmd = ms->current_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) int t, nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (!ms->tgts[ms->conn_tgt].data_goes_out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) /* wait a little while until the fifo drains */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) t = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) while (t > 0 && in_8(&mr->fifo_count) != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) && (in_le32(&md->status) & ACTIVE) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) --t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) out_le32(&md->control, RUN << 16); /* turn off RUN bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) nb = (mr->count_hi << 8) + mr->count_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) dlog(ms, "halt_dma fc/count=%.6x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) MKWORD(0, mr->fifo_count, 0, nb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (ms->tgts[ms->conn_tgt].data_goes_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) nb += mr->fifo_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) /* nb is the number of bytes not yet transferred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) to/from the target. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) ms->data_ptr -= nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) dlog(ms, "data_ptr %x", ms->data_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (ms->data_ptr < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) printk(KERN_ERR "mesh: halt_dma: data_ptr=%d (nb=%d, ms=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) ms->data_ptr, nb, ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) ms->data_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) #ifdef MESH_DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) dumplog(ms, ms->conn_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) dumpslog(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) #endif /* MESH_DBG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) } else if (cmd && scsi_bufflen(cmd) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) ms->data_ptr > scsi_bufflen(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) printk(KERN_DEBUG "mesh: target %d overrun, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) "data_ptr=%x total=%x goes_out=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) ms->conn_tgt, ms->data_ptr, scsi_bufflen(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) ms->tgts[ms->conn_tgt].data_goes_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) scsi_dma_unmap(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) ms->dma_started = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) static void phase_mismatch(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) int phase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) dlog(ms, "phasemm ch/cl/seq/fc=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) MKWORD(mr->count_hi, mr->count_lo, mr->sequence, mr->fifo_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) phase = in_8(&mr->bus_status0) & BS0_PHASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) if (ms->msgphase == msg_out_xxx && phase == BP_MSGOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) /* output the last byte of the message, without ATN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) out_8(&mr->count_lo, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) out_8(&mr->sequence, SEQ_MSGOUT + use_active_neg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) out_8(&mr->fifo, ms->msgout[ms->n_msgout-1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) ms->msgphase = msg_out_last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) if (ms->msgphase == msg_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) get_msgin(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (ms->n_msgin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) handle_msgin(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (ms->dma_started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) halt_dma(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (mr->fifo_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) out_8(&mr->sequence, SEQ_FLUSHFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) ms->msgphase = msg_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) switch (phase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) case BP_DATAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) ms->tgts[ms->conn_tgt].data_goes_out = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) ms->phase = dataing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) case BP_DATAOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) ms->tgts[ms->conn_tgt].data_goes_out = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) ms->phase = dataing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) case BP_COMMAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) ms->phase = commanding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) case BP_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) ms->phase = statusing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) case BP_MSGIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) ms->msgphase = msg_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) ms->n_msgin = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) case BP_MSGOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) ms->msgphase = msg_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (ms->n_msgout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (ms->aborting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) do_abort(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) if (ms->last_n_msgout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) "mesh: no msg to repeat\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) ms->msgout[0] = NOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) ms->last_n_msgout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) ms->n_msgout = ms->last_n_msgout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) printk(KERN_DEBUG "mesh: unknown scsi phase %x\n", phase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) ms->stat = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) mesh_done(ms, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) start_phase(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) static void cmd_complete(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) struct scsi_cmnd *cmd = ms->current_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) struct mesh_target *tp = &ms->tgts[ms->conn_tgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) int seq, n, t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) dlog(ms, "cmd_complete fc=%x", mr->fifo_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) seq = use_active_neg + (ms->n_msgout? SEQ_ATN: 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) switch (ms->msgphase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) case msg_out_xxx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) /* huh? we expected a phase mismatch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) ms->n_msgin = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) ms->msgphase = msg_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) case msg_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) /* should have some message bytes in fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) get_msgin(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) n = msgin_length(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (ms->n_msgin < n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) out_8(&mr->count_lo, n - ms->n_msgin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) out_8(&mr->sequence, SEQ_MSGIN + seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) ms->msgphase = msg_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) handle_msgin(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) start_phase(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) case msg_in_bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) out_8(&mr->sequence, SEQ_FLUSHFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) out_8(&mr->count_lo, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) out_8(&mr->sequence, SEQ_MSGIN + SEQ_ATN + use_active_neg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) case msg_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) * To get the right timing on ATN wrt ACK, we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) * to get the MESH to drop ACK, wait until REQ gets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * asserted, then drop ATN. To do this we first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) * issue a SEQ_MSGOUT with ATN and wait for REQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) * then change the command to a SEQ_MSGOUT w/o ATN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) * If we don't see REQ in a reasonable time, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) * change the command to SEQ_MSGIN with ATN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) * wait for the phase mismatch interrupt, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) * issue the SEQ_MSGOUT without ATN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) out_8(&mr->count_lo, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) out_8(&mr->sequence, SEQ_MSGOUT + use_active_neg + SEQ_ATN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) t = 30; /* wait up to 30us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) while ((in_8(&mr->bus_status0) & BS0_REQ) == 0 && --t >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) dlog(ms, "last_mbyte err/exc/fc/cl=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) MKWORD(mr->error, mr->exception,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) mr->fifo_count, mr->count_lo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (in_8(&mr->interrupt) & (INT_ERROR | INT_EXCEPTION)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /* whoops, target didn't do what we expected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) ms->last_n_msgout = ms->n_msgout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) ms->n_msgout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) if (in_8(&mr->interrupt) & INT_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) printk(KERN_ERR "mesh: error %x in msg_out\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) in_8(&mr->error));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) handle_error(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (in_8(&mr->exception) != EXC_PHASEMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) printk(KERN_ERR "mesh: exc %x in msg_out\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) in_8(&mr->exception));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) printk(KERN_DEBUG "mesh: bs0=%x in msg_out\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) in_8(&mr->bus_status0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) handle_exception(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (in_8(&mr->bus_status0) & BS0_REQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) out_8(&mr->sequence, SEQ_MSGOUT + use_active_neg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) out_8(&mr->fifo, ms->msgout[ms->n_msgout-1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) ms->msgphase = msg_out_last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) out_8(&mr->sequence, SEQ_MSGIN + use_active_neg + SEQ_ATN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) ms->msgphase = msg_out_xxx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) case msg_out_last:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) ms->last_n_msgout = ms->n_msgout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) ms->n_msgout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) ms->msgphase = ms->expect_reply? msg_in: msg_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) start_phase(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) case msg_none:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) switch (ms->phase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) case idle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) printk(KERN_ERR "mesh: interrupt in idle phase?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) dumpslog(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) case selecting:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) dlog(ms, "Selecting phase at command completion",0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) ms->msgout[0] = IDENTIFY(ALLOW_RESEL(ms->conn_tgt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) (cmd? cmd->device->lun: 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) ms->n_msgout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) ms->expect_reply = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) if (ms->aborting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) ms->msgout[0] = ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) ms->n_msgout++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) } else if (tp->sdtr_state == do_sdtr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) /* add SDTR message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) add_sdtr_msg(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) ms->expect_reply = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) tp->sdtr_state = sdtr_sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) ms->msgphase = msg_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) * We need to wait for REQ before dropping ATN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) * We wait for at most 30us, then fall back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) * a scheme where we issue a SEQ_COMMAND with ATN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) * which will give us a phase mismatch interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) * when REQ does come, and then we send the message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) t = 230; /* wait up to 230us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) while ((in_8(&mr->bus_status0) & BS0_REQ) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) if (--t < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) dlog(ms, "impatient for req", ms->n_msgout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) ms->msgphase = msg_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) case dataing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) if (ms->dma_count != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) start_phase(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) * We can get a phase mismatch here if the target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) * changes to the status phase, even though we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) * had a command complete interrupt. Then, if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) * issue the SEQ_STATUS command, we'll get a sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) * error interrupt. Which isn't so bad except that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) * occasionally the mesh actually executes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * SEQ_STATUS *as well as* giving us the sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) * error and phase mismatch exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) out_8(&mr->sequence, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) out_8(&mr->interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) halt_dma(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) case statusing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) if (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) cmd->SCp.Status = mr->fifo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (DEBUG_TARGET(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) printk(KERN_DEBUG "mesh: status is %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) cmd->SCp.Status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) ms->msgphase = msg_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) case busfreeing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) mesh_done(ms, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) case disconnecting:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) ms->current_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) ms->phase = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) mesh_start(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) ++ms->phase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) start_phase(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) * Called by midlayer with host locked to queue a new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) * request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) static int mesh_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) struct mesh_state *ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) cmd->scsi_done = done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) cmd->host_scribble = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) ms = (struct mesh_state *) cmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (ms->request_q == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) ms->request_q = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) ms->request_qtail->host_scribble = (void *) cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) ms->request_qtail = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) if (ms->phase == idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) mesh_start(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) static DEF_SCSI_QCMD(mesh_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) * Called to handle interrupts, either call by the interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) * handler (do_mesh_interrupt) or by other functions in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) * exceptional circumstances
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) static void mesh_interrupt(struct mesh_state *ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) int intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) if (ALLOW_DEBUG(ms->conn_tgt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) printk(KERN_DEBUG "mesh_intr, bs0=%x int=%x exc=%x err=%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) "phase=%d msgphase=%d\n", mr->bus_status0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) mr->interrupt, mr->exception, mr->error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) ms->phase, ms->msgphase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) while ((intr = in_8(&mr->interrupt)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) dlog(ms, "interrupt intr/err/exc/seq=%.8x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) MKWORD(intr, mr->error, mr->exception, mr->sequence));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) if (intr & INT_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) handle_error(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) } else if (intr & INT_EXCEPTION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) handle_exception(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) } else if (intr & INT_CMDDONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) out_8(&mr->interrupt, INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) cmd_complete(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) /* Todo: here we can at least try to remove the command from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) * queue if it isn't connected yet, and for pending command, assert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) * ATN until the bus gets freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) static int mesh_abort(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) struct mesh_state *ms = (struct mesh_state *) cmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) printk(KERN_DEBUG "mesh_abort(%p)\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) mesh_dump_regs(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) dumplog(ms, cmd->device->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) dumpslog(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) * Called by the midlayer with the lock held to reset the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) * SCSI host and bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) * The midlayer will wait for devices to come back, we don't need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) * to do that ourselves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) static int mesh_host_reset(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) struct mesh_state *ms = (struct mesh_state *) cmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) volatile struct mesh_regs __iomem *mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) volatile struct dbdma_regs __iomem *md = ms->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) printk(KERN_DEBUG "mesh_host_reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) spin_lock_irqsave(ms->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) if (ms->dma_started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) halt_dma(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) /* Reset the controller & dbdma channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) out_le32(&md->control, (RUN|PAUSE|FLUSH|WAKE) << 16); /* stop dma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) out_8(&mr->exception, 0xff); /* clear all exception bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) out_8(&mr->error, 0xff); /* clear all error bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) out_8(&mr->sequence, SEQ_RESETMESH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) out_8(&mr->intr_mask, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) out_8(&mr->source_id, ms->host->this_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) out_8(&mr->sel_timeout, 25); /* 250ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) out_8(&mr->sync_params, ASYNC_PARAMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) /* Reset the bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) out_8(&mr->bus_status1, BS1_RST); /* assert RST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) udelay(30); /* leave it on for >= 25us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) out_8(&mr->bus_status1, 0); /* negate RST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) /* Complete pending commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) handle_reset(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) spin_unlock_irqrestore(ms->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) static void set_mesh_power(struct mesh_state *ms, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) if (!machine_is(powermac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) pmac_call_feature(PMAC_FTR_MESH_ENABLE, macio_get_of_node(ms->mdev), 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) pmac_call_feature(PMAC_FTR_MESH_ENABLE, macio_get_of_node(ms->mdev), 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) static int mesh_suspend(struct macio_dev *mdev, pm_message_t mesg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) struct mesh_state *ms = (struct mesh_state *)macio_get_drvdata(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) switch (mesg.event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) case PM_EVENT_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) case PM_EVENT_HIBERNATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) case PM_EVENT_FREEZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) if (ms->phase == sleeping)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) scsi_block_requests(ms->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) spin_lock_irqsave(ms->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) while(ms->phase != idle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) spin_unlock_irqrestore(ms->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) spin_lock_irqsave(ms->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) ms->phase = sleeping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) spin_unlock_irqrestore(ms->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) disable_irq(ms->meshintr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) set_mesh_power(ms, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) static int mesh_resume(struct macio_dev *mdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) struct mesh_state *ms = (struct mesh_state *)macio_get_drvdata(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) if (ms->phase != sleeping)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) set_mesh_power(ms, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) mesh_init(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) spin_lock_irqsave(ms->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) mesh_start(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) spin_unlock_irqrestore(ms->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) enable_irq(ms->meshintr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) scsi_unblock_requests(ms->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) * If we leave drives set for synchronous transfers (especially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) * CDROMs), and reboot to MacOS, it gets confused, poor thing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) * So, on reboot we reset the SCSI bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) static int mesh_shutdown(struct macio_dev *mdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) struct mesh_state *ms = (struct mesh_state *)macio_get_drvdata(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) volatile struct mesh_regs __iomem *mr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) printk(KERN_INFO "resetting MESH scsi bus(es)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) spin_lock_irqsave(ms->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) mr = ms->mesh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) out_8(&mr->intr_mask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) out_8(&mr->interrupt, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) out_8(&mr->bus_status1, BS1_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) mesh_flush_io(mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) udelay(30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) out_8(&mr->bus_status1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) spin_unlock_irqrestore(ms->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) static struct scsi_host_template mesh_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) .proc_name = "mesh",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) .name = "MESH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) .queuecommand = mesh_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) .eh_abort_handler = mesh_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) .eh_host_reset_handler = mesh_host_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) .can_queue = 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) .this_id = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) .sg_tablesize = SG_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) .cmd_per_lun = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) .max_segment_size = 65535,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) struct device_node *mesh = macio_get_of_node(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) struct pci_dev* pdev = macio_get_pci_dev(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) int tgt, minper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) const int *cfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) struct mesh_state *ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) struct Scsi_Host *mesh_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) void *dma_cmd_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) dma_addr_t dma_cmd_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) switch (mdev->bus->chip->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) case macio_heathrow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) case macio_gatwick:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) case macio_paddington:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) use_active_neg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) use_active_neg = SEQ_ACTIVE_NEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) printk(KERN_ERR "mesh: expected 2 addrs and 2 intrs"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) " (got %d,%d)\n", macio_resource_count(mdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) macio_irq_count(mdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) if (macio_request_resources(mdev, "mesh") != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) printk(KERN_ERR "mesh: unable to request memory resources");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) mesh_host = scsi_host_alloc(&mesh_template, sizeof(struct mesh_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) if (mesh_host == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) printk(KERN_ERR "mesh: couldn't register host");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) /* Old junk for root discovery, that will die ultimately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) #if !defined(MODULE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) note_scsi_host(mesh, mesh_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) mesh_host->base = macio_resource_start(mdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) mesh_host->irq = macio_irq(mdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) ms = (struct mesh_state *) mesh_host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) macio_set_drvdata(mdev, ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) ms->host = mesh_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) ms->mdev = mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) ms->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) ms->mesh = ioremap(macio_resource_start(mdev, 0), 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) if (ms->mesh == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) printk(KERN_ERR "mesh: can't map registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) ms->dma = ioremap(macio_resource_start(mdev, 1), 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) if (ms->dma == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) printk(KERN_ERR "mesh: can't map registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) iounmap(ms->mesh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) ms->meshintr = macio_irq(mdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) ms->dmaintr = macio_irq(mdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) /* Space for dma command list: +1 for stop command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) * +1 to allow for aligning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) ms->dma_cmd_size = (mesh_host->sg_tablesize + 2) * sizeof(struct dbdma_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) /* We use the PCI APIs for now until the generic one gets fixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) * enough or until we get some macio-specific versions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) dma_cmd_space = dma_alloc_coherent(&macio_get_pci_dev(mdev)->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) ms->dma_cmd_size, &dma_cmd_bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) if (dma_cmd_space == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) printk(KERN_ERR "mesh: can't allocate DMA table\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) ms->dma_cmds = (struct dbdma_cmd *) DBDMA_ALIGN(dma_cmd_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) ms->dma_cmd_space = dma_cmd_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) ms->dma_cmd_bus = dma_cmd_bus + ((unsigned long)ms->dma_cmds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) - (unsigned long)dma_cmd_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) ms->current_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) for (tgt = 0; tgt < 8; ++tgt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) ms->tgts[tgt].sdtr_state = do_sdtr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) ms->tgts[tgt].sync_params = ASYNC_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) ms->tgts[tgt].current_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) if ((cfp = of_get_property(mesh, "clock-frequency", NULL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) ms->clk_freq = *cfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) printk(KERN_INFO "mesh: assuming 50MHz clock frequency\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) ms->clk_freq = 50000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) /* The maximum sync rate is clock / 5; increase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) * mesh_sync_period if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) minper = 1000000000 / (ms->clk_freq / 5); /* ns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) if (mesh_sync_period < minper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) mesh_sync_period = minper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) /* Power up the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) set_mesh_power(ms, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) /* Set it up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) mesh_init(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) /* Request interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) if (request_irq(ms->meshintr, do_mesh_interrupt, 0, "MESH", ms)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) printk(KERN_ERR "MESH: can't get irq %d\n", ms->meshintr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) goto out_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) /* Add scsi host & scan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) if (scsi_add_host(mesh_host, &mdev->ofdev.dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) goto out_release_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) scsi_scan_host(mesh_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) out_release_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) free_irq(ms->meshintr, ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) out_shutdown:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) /* shutdown & reset bus in case of error or macos can be confused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) * at reboot if the bus was set to synchronous mode already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) mesh_shutdown(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) set_mesh_power(ms, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) dma_free_coherent(&macio_get_pci_dev(mdev)->dev, ms->dma_cmd_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) ms->dma_cmd_space, ms->dma_cmd_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) iounmap(ms->dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) iounmap(ms->mesh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) scsi_host_put(mesh_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) out_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) macio_release_resources(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) static int mesh_remove(struct macio_dev *mdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) struct mesh_state *ms = (struct mesh_state *)macio_get_drvdata(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) struct Scsi_Host *mesh_host = ms->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) scsi_remove_host(mesh_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) free_irq(ms->meshintr, ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) /* Reset scsi bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) mesh_shutdown(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) /* Shut down chip & termination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) set_mesh_power(ms, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) /* Unmap registers & dma controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) iounmap(ms->mesh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) iounmap(ms->dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) /* Free DMA commands memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) dma_free_coherent(&macio_get_pci_dev(mdev)->dev, ms->dma_cmd_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) ms->dma_cmd_space, ms->dma_cmd_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) /* Release memory resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) macio_release_resources(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) scsi_host_put(mesh_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) static struct of_device_id mesh_match[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) .name = "mesh",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) .type = "scsi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) .compatible = "chrp,mesh0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) MODULE_DEVICE_TABLE (of, mesh_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) static struct macio_driver mesh_driver =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) .name = "mesh",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) .of_match_table = mesh_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) .probe = mesh_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) .remove = mesh_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) .shutdown = mesh_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) .suspend = mesh_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) .resume = mesh_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) static int __init init_mesh(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) /* Calculate sync rate from module parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) if (sync_rate > 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) sync_rate = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) if (sync_rate > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) printk(KERN_INFO "mesh: configured for synchronous %d MB/s\n", sync_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) mesh_sync_period = 1000 / sync_rate; /* ns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) mesh_sync_offset = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) printk(KERN_INFO "mesh: configured for asynchronous\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) return macio_register_driver(&mesh_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) static void __exit exit_mesh(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) return macio_unregister_driver(&mesh_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) module_init(init_mesh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) module_exit(exit_mesh);