^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Linux MegaRAID device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2002 LSI Logic Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2002 Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * - fixes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * - speed-ups (list handling fixes, issued_list, optimizations.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * - lots of cleanups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (c) 2003 Christoph Hellwig <hch@lst.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * - new-style, hotplug-aware pci probing and scsi registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Version : v2.00.4 Mon Nov 14 14:02:43 EST 2005 - Seokmann Ju
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * <Seokmann.Ju@lsil.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Description: Linux device driver for LSI Logic MegaRAID controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Supported controllers: MegaRAID 418, 428, 438, 466, 762, 467, 471, 490, 493
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * 518, 520, 531, 532
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * This driver is supported by LSI Logic, with assistance from Red Hat, Dell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * and others. Please send updates to the mailing list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * linux-scsi@vger.kernel.org .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <scsi/scsicam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include "scsi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include "megaraid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define MEGARAID_MODULE_VERSION "2.00.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) MODULE_AUTHOR ("sju@lsil.com");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) MODULE_DESCRIPTION ("LSI Logic MegaRAID legacy driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) MODULE_LICENSE ("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) MODULE_VERSION(MEGARAID_MODULE_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static DEFINE_MUTEX(megadev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static unsigned int max_cmd_per_lun = DEF_CMD_PER_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) module_param(max_cmd_per_lun, uint, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) MODULE_PARM_DESC(max_cmd_per_lun, "Maximum number of commands which can be issued to a single LUN (default=DEF_CMD_PER_LUN=63)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static unsigned short int max_sectors_per_io = MAX_SECTORS_PER_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) module_param(max_sectors_per_io, ushort, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) MODULE_PARM_DESC(max_sectors_per_io, "Maximum number of sectors per I/O request (default=MAX_SECTORS_PER_IO=128)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static unsigned short int max_mbox_busy_wait = MBOX_BUSY_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) module_param(max_mbox_busy_wait, ushort, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) MODULE_PARM_DESC(max_mbox_busy_wait, "Maximum wait for mailbox in microseconds if busy (default=MBOX_BUSY_WAIT=10)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define RDINDOOR(adapter) readl((adapter)->mmio_base + 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define RDOUTDOOR(adapter) readl((adapter)->mmio_base + 0x2C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define WRINDOOR(adapter,value) writel(value, (adapter)->mmio_base + 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define WROUTDOOR(adapter,value) writel(value, (adapter)->mmio_base + 0x2C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Global variables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static int hba_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static adapter_t *hba_soft_state[MAX_CONTROLLERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static struct proc_dir_entry *mega_proc_dir_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* For controller re-ordering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static struct mega_hbas mega_hbas[MAX_CONTROLLERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) megadev_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * The File Operations structure for the serial/ioctl interface of the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static const struct file_operations megadev_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .unlocked_ioctl = megadev_unlocked_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .open = megadev_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Array to structures for storing the information about the controllers. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * information is sent to the user level applications, when they do an ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * for this information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static struct mcontroller mcontroller[MAX_CONTROLLERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* The current driver version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static u32 driver_ver = 0x02000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* major number used by the device for character interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static int major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define IS_RAID_CH(hba, ch) (((hba)->mega_ch_class >> (ch)) & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Debug variable to print some diagnostic messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int trace_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * mega_setup_mailbox()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Allocates a 8 byte aligned memory for the handshake mailbox.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) mega_setup_mailbox(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned long align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) adapter->una_mbox64 = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) sizeof(mbox64_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) &adapter->una_mbox64_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if( !adapter->una_mbox64 ) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) adapter->mbox = &adapter->una_mbox64->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) adapter->mbox = (mbox_t *)((((unsigned long) adapter->mbox) + 15) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) (~0UL ^ 0xFUL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) adapter->mbox64 = (mbox64_t *)(((unsigned long)adapter->mbox) - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) align = ((void *)adapter->mbox) - ((void *)&adapter->una_mbox64->mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) adapter->mbox_dma = adapter->una_mbox64_dma + 8 + align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * Register the mailbox if the controller is an io-mapped controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if( adapter->flag & BOARD_IOMAP ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) outb(adapter->mbox_dma & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) adapter->host->io_port + MBOX_PORT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) outb((adapter->mbox_dma >> 8) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) adapter->host->io_port + MBOX_PORT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) outb((adapter->mbox_dma >> 16) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) adapter->host->io_port + MBOX_PORT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) outb((adapter->mbox_dma >> 24) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) adapter->host->io_port + MBOX_PORT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) outb(ENABLE_MBOX_BYTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) adapter->host->io_port + ENABLE_MBOX_REGION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) irq_ack(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) irq_enable(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^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) * mega_query_adapter()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * @adapter - pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * Issue the adapter inquiry commands to the controller and find out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * information and parameter about the devices attached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) mega_query_adapter(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dma_addr_t prod_info_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) mega_inquiry3 *inquiry3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u8 raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* Initialize adapter inquiry mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Try to issue Inquiry3 command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * if not succeeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * update enquiry3 structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) inquiry3 = (mega_inquiry3 *)adapter->mega_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) raw_mbox[0] = FC_NEW_CONFIG; /* i.e. mbox->cmd=0xA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) raw_mbox[2] = NC_SUBOP_ENQUIRY3; /* i.e. 0x0F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) raw_mbox[3] = ENQ3_GET_SOLICITED_FULL; /* i.e. 0x02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* Issue a blocking command to the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if ((retval = issue_scb_block(adapter, raw_mbox))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* the adapter does not support 40ld */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) mraid_ext_inquiry *ext_inq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) mraid_inquiry *inq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) dma_addr_t dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ext_inq = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) sizeof(mraid_ext_inquiry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) &dma_handle, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if( ext_inq == NULL ) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) inq = &ext_inq->raid_inq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) mbox->m_out.xferaddr = (u32)dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /*issue old 0x04 command to adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) mbox->m_out.cmd = MEGA_MBOXCMD_ADPEXTINQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * update Enquiry3 and ProductInfo structures with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * mraid_inquiry structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) mega_8_to_40ld(inq, inquiry3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) (mega_product_info *)&adapter->product_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) dma_free_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) sizeof(mraid_ext_inquiry), ext_inq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) } else { /*adapter supports 40ld */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) adapter->flag |= BOARD_40LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * get product_info, which is static information and will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) prod_info_dma_handle = dma_map_single(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) (void *)&adapter->product_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) sizeof(mega_product_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) mbox->m_out.xferaddr = prod_info_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) raw_mbox[0] = FC_NEW_CONFIG; /* i.e. mbox->cmd=0xA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) raw_mbox[2] = NC_SUBOP_PRODUCT_INFO; /* i.e. 0x0E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if ((retval = issue_scb_block(adapter, raw_mbox)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) "Product_info cmd failed with error: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) dma_unmap_single(&adapter->dev->dev, prod_info_dma_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) sizeof(mega_product_info), DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * kernel scans the channels from 0 to <= max_channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) adapter->host->max_channel =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) adapter->product_info.nchannels + NVIRT_CHAN -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) adapter->host->max_id = 16; /* max targets per channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) adapter->host->max_lun = 7; /* Up to 7 luns for non disk devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) adapter->host->cmd_per_lun = max_cmd_per_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) adapter->numldrv = inquiry3->num_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) adapter->max_cmds = adapter->product_info.max_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if(adapter->max_cmds > MAX_COMMANDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) adapter->max_cmds = MAX_COMMANDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) adapter->host->can_queue = adapter->max_cmds - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * Get the maximum number of scatter-gather elements supported by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) mega_get_max_sgl(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) adapter->host->sg_tablesize = adapter->sglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* use HP firmware and bios version encoding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) Note: fw_version[0|1] and bios_version[0|1] were originally shifted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) right 8 bits making them zero. This 0 value was hardcoded to fix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) sparse warnings. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (adapter->product_info.subsysvid == PCI_VENDOR_ID_HP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) snprintf(adapter->fw_version, sizeof(adapter->fw_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) "%c%d%d.%d%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) adapter->product_info.fw_version[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) adapter->product_info.fw_version[1] & 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) adapter->product_info.fw_version[0] & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) snprintf(adapter->bios_version, sizeof(adapter->fw_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) "%c%d%d.%d%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) adapter->product_info.bios_version[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) adapter->product_info.bios_version[1] & 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) adapter->product_info.bios_version[0] & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) memcpy(adapter->fw_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) (char *)adapter->product_info.fw_version, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) adapter->fw_version[4] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) memcpy(adapter->bios_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) (char *)adapter->product_info.bios_version, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) adapter->bios_version[4] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) dev_notice(&adapter->dev->dev, "[%s:%s] detected %d logical drives\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) adapter->fw_version, adapter->bios_version, adapter->numldrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * Do we support extended (>10 bytes) cdbs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) adapter->support_ext_cdb = mega_support_ext_cdb(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (adapter->support_ext_cdb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) dev_notice(&adapter->dev->dev, "supports extended CDBs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return 0;
^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) * mega_runpendq()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * Runs through the list of pending requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) mega_runpendq(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if(!list_empty(&adapter->pending_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) __mega_runpendq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * megaraid_queue()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * @scmd - Issue this scsi command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * @done - the callback hook into the scsi mid-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * The command queuing entry point for the mid-layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) megaraid_queue_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) adapter_t *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int busy=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) adapter = (adapter_t *)scmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) scmd->scsi_done = done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * Allocate and build a SCB request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * busy flag will be set if mega_build_cmd() command could not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * allocate scb. We will return non-zero status in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * NOTE: scb can be null even though certain commands completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * successfully, e.g., MODE_SENSE and TEST_UNIT_READY, we would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * return 0 in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) spin_lock_irqsave(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) scb = mega_build_cmd(adapter, scmd, &busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (!scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) scb->state |= SCB_PENDQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) list_add_tail(&scb->list, &adapter->pending_list);
^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) * Check if the HBA is in quiescent state, e.g., during a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * delete logical drive opertion. If it is, don't run
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * the pending_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (atomic_read(&adapter->quiescent) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) mega_runpendq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) busy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) spin_unlock_irqrestore(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return busy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static DEF_SCSI_QCMD(megaraid_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * mega_allocate_scb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * @cmd: scsi command from the mid-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * Allocate a SCB structure. This is the central structure for controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static inline scb_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) mega_allocate_scb(adapter_t *adapter, struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct list_head *head = &adapter->free_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* Unlink command from Free List */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if( !list_empty(head) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) scb = list_entry(head->next, scb_t, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) list_del_init(head->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) scb->state = SCB_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) scb->cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) scb->dma_type = MEGA_DMA_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * mega_get_ldrv_num()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * @cmd: scsi mid layer command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * @channel: channel on the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * Calculate the logical drive number based on the information in scsi command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * and the channel number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) mega_get_ldrv_num(adapter_t *adapter, struct scsi_cmnd *cmd, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) int tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) int ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) tgt = cmd->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if ( tgt > adapter->this_id )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) tgt--; /* we do not get inquires for initiator id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ldrv_num = (channel * 15) + tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * If we have a logical drive with boot enabled, project it first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if( adapter->boot_ldrv_enabled ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if( ldrv_num == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ldrv_num = adapter->boot_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if( ldrv_num <= adapter->boot_ldrv ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ldrv_num--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * If "delete logical drive" feature is enabled on this controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * Do only if at least one delete logical drive operation was done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * Also, after logical drive deletion, instead of logical drive number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * the value returned should be 0x80+logical drive id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * These is valid only for IO commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (adapter->support_random_del && adapter->read_ldidmap )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) switch (cmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) case READ_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) case WRITE_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) case READ_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) case WRITE_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ldrv_num += 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * mega_build_cmd()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * @cmd: Prepare using this scsi command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * @busy: busy flag if no resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * Prepares a command and scatter gather list for the controller. This routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * also finds out if the commands is intended for a logical drive or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * physical device and prepares the controller command accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * We also re-order the logical drives and physical devices based on their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * boot settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static scb_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) mega_build_cmd(adapter_t *adapter, struct scsi_cmnd *cmd, int *busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) mega_passthru *pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) u32 seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) char islogical;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) int max_ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) int target = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) int ldrv_num = 0; /* logical drive number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * We know what channels our logical drives are on - mega_find_card()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) islogical = adapter->logdrv_chan[cmd->device->channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * The theory: If physical drive is chosen for boot, all the physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * devices are exported before the logical drives, otherwise physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * devices are pushed after logical drives, in which case - Kernel sees
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * the physical devices on virtual channel which is obviously converted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * to actual channel on the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if( adapter->boot_pdrv_enabled ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if( islogical ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /* logical channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) channel = cmd->device->channel -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) adapter->product_info.nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /* this is physical channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) channel = cmd->device->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) target = cmd->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * boot from a physical disk, that disk needs to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * exposed first IF both the channels are SCSI, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * booting from the second channel is not allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if( target == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) target = adapter->boot_pdrv_tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) else if( target == adapter->boot_pdrv_tgt ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) target = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if( islogical ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* this is the logical channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) channel = cmd->device->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* physical channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) channel = cmd->device->channel - NVIRT_CHAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) target = cmd->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if(islogical) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /* have just LUN 0 for each target on virtual channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (cmd->device->lun) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) cmd->result = (DID_BAD_TARGET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ldrv_num = mega_get_ldrv_num(adapter, cmd, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) max_ldrv_num = (adapter->flag & BOARD_40LD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) MAX_LOGICAL_DRIVES_40LD : MAX_LOGICAL_DRIVES_8LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * max_ldrv_num increases by 0x80 if some logical drive was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * deleted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if(adapter->read_ldidmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) max_ldrv_num += 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if(ldrv_num > max_ldrv_num ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) cmd->result = (DID_BAD_TARGET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if( cmd->device->lun > 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * Do not support lun >7 for physically accessed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) cmd->result = (DID_BAD_TARGET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^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) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * Logical drive commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if(islogical) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) switch (cmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) case TEST_UNIT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) #if MEGA_HAVE_CLUSTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * Do we support clustering and is the support enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * If no, return success always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if( !adapter->has_cluster ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) cmd->result = (DID_OK << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if(!(scb = mega_allocate_scb(adapter, cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) *busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) scb->raw_mbox[0] = MEGA_CLUSTER_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) scb->raw_mbox[2] = MEGA_RESERVATION_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) scb->raw_mbox[3] = ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) scb->dma_direction = DMA_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) cmd->result = (DID_OK << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) case MODE_SENSE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) sg = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) buf = kmap_atomic(sg_page(sg)) + sg->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) memset(buf, 0, cmd->cmnd[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) kunmap_atomic(buf - sg->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) cmd->result = (DID_OK << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if(!(adapter->flag & (1L << cmd->device->channel))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) dev_notice(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) "scsi%d: scanning scsi channel %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) "for logical drives\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) adapter->host->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) cmd->device->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) adapter->flag |= (1L << cmd->device->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* Allocate a SCB and initialize passthru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if(!(scb = mega_allocate_scb(adapter, cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) *busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) pthru = scb->pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) mbox = (mbox_t *)scb->raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) memset(mbox, 0, sizeof(scb->raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) memset(pthru, 0, sizeof(mega_passthru));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) pthru->timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) pthru->ars = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) pthru->reqsenselen = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) pthru->islogical = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) pthru->logdrv = ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) pthru->cdblen = cmd->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) memcpy(pthru->cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if( adapter->has_64bit_addr ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) scb->dma_direction = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) pthru->numsgelements = mega_build_sglist(adapter, scb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) &pthru->dataxferaddr, &pthru->dataxferlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) mbox->m_out.xferaddr = scb->pthru_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) case READ_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) case WRITE_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) case READ_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) case WRITE_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) case READ_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) case WRITE_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* Allocate a SCB and initialize mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if(!(scb = mega_allocate_scb(adapter, cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) *busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) mbox = (mbox_t *)scb->raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) memset(mbox, 0, sizeof(scb->raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) mbox->m_out.logdrv = ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * A little hack: 2nd bit is zero for all scsi read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * commands and is set for all scsi write commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if( adapter->has_64bit_addr ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) mbox->m_out.cmd = (*cmd->cmnd & 0x02) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) MEGA_MBOXCMD_LWRITE64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) MEGA_MBOXCMD_LREAD64 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) mbox->m_out.cmd = (*cmd->cmnd & 0x02) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) MEGA_MBOXCMD_LWRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) MEGA_MBOXCMD_LREAD ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * 6-byte READ(0x08) or WRITE(0x0A) cdb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if( cmd->cmd_len == 6 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) mbox->m_out.numsectors = (u32) cmd->cmnd[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) mbox->m_out.lba =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ((u32)cmd->cmnd[1] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ((u32)cmd->cmnd[2] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) (u32)cmd->cmnd[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) mbox->m_out.lba &= 0x1FFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * Take modulo 0x80, since the logical drive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * number increases by 0x80 when a logical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * drive was deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (*cmd->cmnd == READ_6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) adapter->nreads[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) adapter->nreadblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) adapter->nwrites[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) adapter->nwriteblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * 10-byte READ(0x28) or WRITE(0x2A) cdb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if( cmd->cmd_len == 10 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) mbox->m_out.numsectors =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) (u32)cmd->cmnd[8] |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) ((u32)cmd->cmnd[7] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) mbox->m_out.lba =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) ((u32)cmd->cmnd[2] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) ((u32)cmd->cmnd[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) ((u32)cmd->cmnd[4] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) (u32)cmd->cmnd[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (*cmd->cmnd == READ_10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) adapter->nreads[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) adapter->nreadblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) adapter->nwrites[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) adapter->nwriteblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * 12-byte READ(0xA8) or WRITE(0xAA) cdb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if( cmd->cmd_len == 12 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) mbox->m_out.lba =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) ((u32)cmd->cmnd[2] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ((u32)cmd->cmnd[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) ((u32)cmd->cmnd[4] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) (u32)cmd->cmnd[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) mbox->m_out.numsectors =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) ((u32)cmd->cmnd[6] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) ((u32)cmd->cmnd[7] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) ((u32)cmd->cmnd[8] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) (u32)cmd->cmnd[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (*cmd->cmnd == READ_12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) adapter->nreads[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) adapter->nreadblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) adapter->nwrites[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) adapter->nwriteblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * If it is a read command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if( (*cmd->cmnd & 0x0F) == 0x08 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) scb->dma_direction = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) scb->dma_direction = DMA_TO_DEVICE;
^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) /* Calculate Scatter-Gather info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) mbox->m_out.numsgelements = mega_build_sglist(adapter, scb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) (u32 *)&mbox->m_out.xferaddr, &seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) #if MEGA_HAVE_CLUSTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) case RESERVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) case RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * Do we support clustering and is the support enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if( ! adapter->has_cluster ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) cmd->result = (DID_BAD_TARGET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* Allocate a SCB and initialize mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if(!(scb = mega_allocate_scb(adapter, cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) *busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) scb->raw_mbox[0] = MEGA_CLUSTER_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) scb->raw_mbox[2] = ( *cmd->cmnd == RESERVE ) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) MEGA_RESERVE_LD : MEGA_RELEASE_LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) scb->raw_mbox[3] = ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) scb->dma_direction = DMA_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) cmd->result = (DID_BAD_TARGET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * Passthru drive commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) /* Allocate a SCB and initialize passthru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if(!(scb = mega_allocate_scb(adapter, cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) *busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) mbox = (mbox_t *)scb->raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) memset(mbox, 0, sizeof(scb->raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if( adapter->support_ext_cdb ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) mega_prepare_extpassthru(adapter, scb, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) channel, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) mbox->m_out.cmd = MEGA_MBOXCMD_EXTPTHRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) mbox->m_out.xferaddr = scb->epthru_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) pthru = mega_prepare_passthru(adapter, scb, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) channel, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) /* Initialize mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if( adapter->has_64bit_addr ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) mbox->m_out.xferaddr = scb->pthru_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) * mega_prepare_passthru()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) * @scb: our scsi control block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) * @cmd: scsi command from the mid-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * @channel: actual channel on the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * @target: actual id on the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * prepare a command for the scsi physical devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) static mega_passthru *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) mega_prepare_passthru(adapter_t *adapter, scb_t *scb, struct scsi_cmnd *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) int channel, int target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) mega_passthru *pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) pthru = scb->pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) memset(pthru, 0, sizeof (mega_passthru));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /* 0=6sec/1=60sec/2=10min/3=3hrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) pthru->timeout = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) pthru->ars = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) pthru->reqsenselen = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) pthru->islogical = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) pthru->channel = (adapter->flag & BOARD_40LD) ? 0 : channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) pthru->target = (adapter->flag & BOARD_40LD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) (channel << 4) | target : target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) pthru->cdblen = cmd->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) pthru->logdrv = cmd->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) memcpy(pthru->cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) /* Not sure about the direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) scb->dma_direction = DMA_BIDIRECTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) /* Special Code for Handling READ_CAPA/ INQ using bounce buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) switch (cmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if(!(adapter->flag & (1L << cmd->device->channel))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) dev_notice(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) "scsi%d: scanning scsi channel %d [P%d] "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) "for physical devices\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) adapter->host->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) cmd->device->channel, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) adapter->flag |= (1L << cmd->device->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) pthru->numsgelements = mega_build_sglist(adapter, scb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) &pthru->dataxferaddr, &pthru->dataxferlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) * mega_prepare_extpassthru()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * @scb: our scsi control block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) * @cmd: scsi command from the mid-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * @channel: actual channel on the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * @target: actual id on the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) * prepare a command for the scsi physical devices. This rountine prepares
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) * commands for devices which can take extended CDBs (>10 bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static mega_ext_passthru *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) mega_prepare_extpassthru(adapter_t *adapter, scb_t *scb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct scsi_cmnd *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) int channel, int target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) mega_ext_passthru *epthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) epthru = scb->epthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) memset(epthru, 0, sizeof(mega_ext_passthru));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /* 0=6sec/1=60sec/2=10min/3=3hrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) epthru->timeout = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) epthru->ars = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) epthru->reqsenselen = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) epthru->islogical = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) epthru->channel = (adapter->flag & BOARD_40LD) ? 0 : channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) epthru->target = (adapter->flag & BOARD_40LD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) (channel << 4) | target : target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) epthru->cdblen = cmd->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) epthru->logdrv = cmd->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) memcpy(epthru->cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /* Not sure about the direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) scb->dma_direction = DMA_BIDIRECTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) switch(cmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if(!(adapter->flag & (1L << cmd->device->channel))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) dev_notice(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) "scsi%d: scanning scsi channel %d [P%d] "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) "for physical devices\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) adapter->host->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) cmd->device->channel, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) adapter->flag |= (1L << cmd->device->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) epthru->numsgelements = mega_build_sglist(adapter, scb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) &epthru->dataxferaddr, &epthru->dataxferlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return epthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) __mega_runpendq(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) struct list_head *pos, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) /* Issue any pending commands to the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) list_for_each_safe(pos, next, &adapter->pending_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) scb = list_entry(pos, scb_t, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if( !(scb->state & SCB_ISSUED) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if( issue_scb(adapter, scb) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * issue_scb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * @scb: scsi control block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) * Post a command to the card if the mailbox is available, otherwise return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * busy. We also take the scb from the pending list if the mailbox is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) issue_scb(adapter_t *adapter, scb_t *scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) volatile mbox64_t *mbox64 = adapter->mbox64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) volatile mbox_t *mbox = adapter->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) unsigned int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if(unlikely(mbox->m_in.busy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) } while( mbox->m_in.busy && (i < max_mbox_busy_wait) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if(mbox->m_in.busy) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /* Copy mailbox data into host structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) memcpy((char *)&mbox->m_out, (char *)scb->raw_mbox,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) sizeof(struct mbox_out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) mbox->m_out.cmdid = scb->idx; /* Set cmdid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) mbox->m_in.busy = 1; /* Set busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * Increment the pending queue counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) atomic_inc(&adapter->pend_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) switch (mbox->m_out.cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) case MEGA_MBOXCMD_LREAD64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) case MEGA_MBOXCMD_LWRITE64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) case MEGA_MBOXCMD_PASSTHRU64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) case MEGA_MBOXCMD_EXTPTHRU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) mbox64->xfer_segment_lo = mbox->m_out.xferaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) mbox64->xfer_segment_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) mbox->m_out.xferaddr = 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) mbox64->xfer_segment_lo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) mbox64->xfer_segment_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) * post the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) scb->state |= SCB_ISSUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if( likely(adapter->flag & BOARD_MEMMAP) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) mbox->m_in.poll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) mbox->m_in.ack = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) WRINDOOR(adapter, adapter->mbox_dma | 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) irq_enable(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) issue_command(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) * Wait until the controller's mailbox is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) mega_busywait_mbox (adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (adapter->mbox->m_in.busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) return __mega_busywait_mbox(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) * issue_scb_block()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) * @raw_mbox: the mailbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * Issue a scb in synchronous and non-interrupt mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) issue_scb_block(adapter_t *adapter, u_char *raw_mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) volatile mbox64_t *mbox64 = adapter->mbox64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) volatile mbox_t *mbox = adapter->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) u8 byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* Wait until mailbox is free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if(mega_busywait_mbox (adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) goto bug_blocked_mailbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* Copy mailbox data into host structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) memcpy((char *) mbox, raw_mbox, sizeof(struct mbox_out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) mbox->m_out.cmdid = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) mbox->m_in.busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) switch (raw_mbox[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) case MEGA_MBOXCMD_LREAD64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) case MEGA_MBOXCMD_LWRITE64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) case MEGA_MBOXCMD_PASSTHRU64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) case MEGA_MBOXCMD_EXTPTHRU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) mbox64->xfer_segment_lo = mbox->m_out.xferaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) mbox64->xfer_segment_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) mbox->m_out.xferaddr = 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) mbox64->xfer_segment_lo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) mbox64->xfer_segment_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if( likely(adapter->flag & BOARD_MEMMAP) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) mbox->m_in.poll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) mbox->m_in.ack = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) mbox->m_in.numstatus = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) mbox->m_in.status = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) WRINDOOR(adapter, adapter->mbox_dma | 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) while((volatile u8)mbox->m_in.numstatus == 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) mbox->m_in.numstatus = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) while( (volatile u8)mbox->m_in.poll != 0x77 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) mbox->m_in.poll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) mbox->m_in.ack = 0x77;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) WRINDOOR(adapter, adapter->mbox_dma | 0x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) while(RDINDOOR(adapter) & 0x2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) irq_disable(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) issue_command(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) while (!((byte = irq_state(adapter)) & INTR_VALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) set_irq_state(adapter, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) irq_enable(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) irq_ack(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return mbox->m_in.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) bug_blocked_mailbox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) dev_warn(&adapter->dev->dev, "Blocked mailbox......!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) udelay (1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) * megaraid_isr_iomapped()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) * @irq: irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) * @devp: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) * Interrupt service routine for io-mapped controllers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) * Find out if our device is interrupting. If yes, acknowledge the interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) * and service the completed commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) megaraid_isr_iomapped(int irq, void *devp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) adapter_t *adapter = devp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) u8 nstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) u8 completed[MAX_FIRMWARE_STATUS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) u8 byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) int handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) * loop till F/W has more commands for us to complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) spin_lock_irqsave(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) /* Check if a valid interrupt is pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) byte = irq_state(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if( (byte & VALID_INTR_BYTE) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) * No more pending commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) set_irq_state(adapter, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) while((nstatus = (volatile u8)adapter->mbox->m_in.numstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) == 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) adapter->mbox->m_in.numstatus = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) status = adapter->mbox->m_in.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) * decrement the pending queue counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) atomic_sub(nstatus, &adapter->pend_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) memcpy(completed, (void *)adapter->mbox->m_in.completed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) nstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) /* Acknowledge interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) irq_ack(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) mega_cmd_done(adapter, completed, nstatus, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) mega_rundoneq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) /* Loop through any pending requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if(atomic_read(&adapter->quiescent) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) mega_runpendq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) } while(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) spin_unlock_irqrestore(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) * megaraid_isr_memmapped()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) * @irq: irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) * @devp: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) * Interrupt service routine for memory-mapped controllers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) * Find out if our device is interrupting. If yes, acknowledge the interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) * and service the completed commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) megaraid_isr_memmapped(int irq, void *devp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) adapter_t *adapter = devp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) u32 dword = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) u8 nstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) u8 completed[MAX_FIRMWARE_STATUS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) int handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) * loop till F/W has more commands for us to complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) spin_lock_irqsave(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) /* Check if a valid interrupt is pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) dword = RDOUTDOOR(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if(dword != 0x10001234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) * No more pending commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) WROUTDOOR(adapter, 0x10001234);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) while((nstatus = (volatile u8)adapter->mbox->m_in.numstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) == 0xFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) adapter->mbox->m_in.numstatus = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) status = adapter->mbox->m_in.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) * decrement the pending queue counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) atomic_sub(nstatus, &adapter->pend_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) memcpy(completed, (void *)adapter->mbox->m_in.completed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) nstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) /* Acknowledge interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) WRINDOOR(adapter, 0x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) while( RDINDOOR(adapter) & 0x02 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) mega_cmd_done(adapter, completed, nstatus, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) mega_rundoneq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) /* Loop through any pending requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if(atomic_read(&adapter->quiescent) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) mega_runpendq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) } while(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) spin_unlock_irqrestore(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) * mega_cmd_done()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) * @completed: array of ids of completed commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) * @nstatus: number of completed commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) * @status: status of the last command completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) * Complete the commands and call the scsi mid-layer callback hooks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) mega_ext_passthru *epthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) struct scatterlist *sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) struct scsi_cmnd *cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) mega_passthru *pthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) mbox_t *mbox = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) u8 c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) int islogical;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) int cmdid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) * for all the commands completed, call the mid-layer callback routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) * and free the scb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) for( i = 0; i < nstatus; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) cmdid = completed[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) * Only free SCBs for the commands coming down from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) * mid-layer, not for which were issued internally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) * For internal command, restore the status returned by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) * firmware so that user can interpret it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (cmdid == CMDID_INT_CMDS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) scb = &adapter->int_scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) list_del_init(&scb->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) scb->state = SCB_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) adapter->int_status = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) complete(&adapter->int_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) scb = &adapter->scb_list[cmdid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * Make sure f/w has completed a valid command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) if( !(scb->state & SCB_ISSUED) || scb->cmd == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) dev_crit(&adapter->dev->dev, "invalid command "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) "Id %d, scb->state:%x, scsi cmd:%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) cmdid, scb->state, scb->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) * Was a abort issued for this command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) if( scb->state & SCB_ABORT ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) "aborted cmd [%x] complete\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) scb->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) scb->cmd->result = (DID_ABORT << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) list_add_tail(SCSI_LIST(scb->cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) &adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) mega_free_scb(adapter, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) * Was a reset issued for this command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) if( scb->state & SCB_RESET ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) "reset cmd [%x] complete\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) scb->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) scb->cmd->result = (DID_RESET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) list_add_tail(SCSI_LIST(scb->cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) &adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) mega_free_scb (adapter, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) cmd = scb->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) pthru = scb->pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) epthru = scb->epthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) mbox = (mbox_t *)scb->raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) int logdrv = mbox->m_out.logdrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) islogical = adapter->logdrv_chan[cmd->channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) * Maintain an error counter for the logical drive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) * Some application like SNMP agent need such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) * statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if( status && islogical && (cmd->cmnd[0] == READ_6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) cmd->cmnd[0] == READ_10 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) cmd->cmnd[0] == READ_12)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) * Logical drive number increases by 0x80 when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) * a logical drive is deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) adapter->rd_errors[logdrv%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if( status && islogical && (cmd->cmnd[0] == WRITE_6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) cmd->cmnd[0] == WRITE_10 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) cmd->cmnd[0] == WRITE_12)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) * Logical drive number increases by 0x80 when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) * a logical drive is deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) adapter->wr_errors[logdrv%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) * Do not return the presence of hard disk on the channel so,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) * inquiry sent, and returned data==hard disk or removable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) * hard disk and not logical, request should return failure! -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) * PJ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) islogical = adapter->logdrv_chan[cmd->device->channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) if( cmd->cmnd[0] == INQUIRY && !islogical ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) sgl = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) if( sg_page(sgl) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) c = *(unsigned char *) sg_virt(&sgl[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) dev_warn(&adapter->dev->dev, "invalid sg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if(IS_RAID_CH(adapter, cmd->device->channel) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) ((c & 0x1F ) == TYPE_DISK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) status = 0xF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) /* clear result; otherwise, success returns corrupt value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) cmd->result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) /* Convert MegaRAID status to Linux error code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) case 0x00: /* SUCCESS , i.e. SCSI_STATUS_GOOD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) cmd->result |= (DID_OK << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) case 0x02: /* ERROR_ABORTED, i.e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) SCSI_STATUS_CHECK_CONDITION */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) /* set sense_buffer and result fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) if( mbox->m_out.cmd == MEGA_MBOXCMD_PASSTHRU ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) mbox->m_out.cmd == MEGA_MBOXCMD_PASSTHRU64 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) memcpy(cmd->sense_buffer, pthru->reqsensearea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) cmd->result = (DRIVER_SENSE << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) (DID_OK << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) (CHECK_CONDITION << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (mbox->m_out.cmd == MEGA_MBOXCMD_EXTPTHRU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) memcpy(cmd->sense_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) epthru->reqsensearea, 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) cmd->result = (DRIVER_SENSE << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) (DID_OK << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) (CHECK_CONDITION << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) cmd->sense_buffer[0] = 0x70;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) cmd->sense_buffer[2] = ABORTED_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) cmd->result |= (CHECK_CONDITION << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) case 0x08: /* ERR_DEST_DRIVE_FAILED, i.e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) SCSI_STATUS_BUSY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) cmd->result |= (DID_BUS_BUSY << 16) | status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) #if MEGA_HAVE_CLUSTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) * If TEST_UNIT_READY fails, we know
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) * MEGA_RESERVATION_STATUS failed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) if( cmd->cmnd[0] == TEST_UNIT_READY ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) cmd->result |= (DID_ERROR << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) (RESERVATION_CONFLICT << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) * Error code returned is 1 if Reserve or Release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) * failed or the input parameter is invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) if( status == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) (cmd->cmnd[0] == RESERVE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) cmd->cmnd[0] == RELEASE) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) cmd->result |= (DID_ERROR << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) (RESERVATION_CONFLICT << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) cmd->result |= (DID_BAD_TARGET << 16)|status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) mega_free_scb(adapter, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /* Add Scsi_Command to end of completed queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) list_add_tail(SCSI_LIST(cmd), &adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) * mega_runpendq()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) * Run through the list of completed requests and finish it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) mega_rundoneq (adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) struct list_head *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) list_for_each(pos, &adapter->completed_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) struct scsi_pointer* spos = (struct scsi_pointer *)pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) cmd = list_entry(spos, struct scsi_cmnd, SCp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) INIT_LIST_HEAD(&adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) * Free a SCB structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) * Note: We assume the scsi commands associated with this scb is not free yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) mega_free_scb(adapter_t *adapter, scb_t *scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) switch( scb->dma_type ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) case MEGA_DMA_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) case MEGA_SGLIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) scsi_dma_unmap(scb->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) * Remove from the pending list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) list_del_init(&scb->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) /* Link the scb back into free list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) scb->state = SCB_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) scb->cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) list_add(&scb->list, &adapter->free_list);
^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) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) __mega_busywait_mbox (adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) volatile mbox_t *mbox = adapter->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) long counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) for (counter = 0; counter < 10000; counter++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) if (!mbox->m_in.busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) return -1; /* give up after 1 second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) * Copies data to SGLIST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) * Note: For 64 bit cards, we need a minimum of one SG element for read/write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) int sgcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) cmd = scb->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) * Copy Scatter-Gather list info into controller structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) * The number of sg elements returned must not exceed our limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) sgcnt = scsi_dma_map(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) scb->dma_type = MEGA_SGLIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) BUG_ON(sgcnt > adapter->sglen || sgcnt < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) *len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (scsi_sg_count(cmd) == 1 && !adapter->has_64bit_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) sg = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) scb->dma_h_bulkdata = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) *buf = (u32)scb->dma_h_bulkdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) *len = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) scsi_for_each_sg(cmd, sg, sgcnt, idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (adapter->has_64bit_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) scb->sgl64[idx].address = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) *len += scb->sgl64[idx].length = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) scb->sgl[idx].address = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) *len += scb->sgl[idx].length = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) /* Reset pointer and length fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) *buf = scb->sgl_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) /* Return count of SG requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) return sgcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) * mega_8_to_40ld()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) * takes all info in AdapterInquiry structure and puts it into ProductInfo and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) * Enquiry3 structures for later use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) mega_8_to_40ld(mraid_inquiry *inquiry, mega_inquiry3 *enquiry3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) mega_product_info *product_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) product_info->max_commands = inquiry->adapter_info.max_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) enquiry3->rebuild_rate = inquiry->adapter_info.rebuild_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) product_info->nchannels = inquiry->adapter_info.nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) product_info->fw_version[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) inquiry->adapter_info.fw_version[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) product_info->bios_version[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) inquiry->adapter_info.bios_version[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) enquiry3->cache_flush_interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) inquiry->adapter_info.cache_flush_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) product_info->dram_size = inquiry->adapter_info.dram_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) enquiry3->num_ldrv = inquiry->logdrv_info.num_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) for (i = 0; i < MAX_LOGICAL_DRIVES_8LD; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) enquiry3->ldrv_size[i] = inquiry->logdrv_info.ldrv_size[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) enquiry3->ldrv_prop[i] = inquiry->logdrv_info.ldrv_prop[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) enquiry3->ldrv_state[i] = inquiry->logdrv_info.ldrv_state[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) for (i = 0; i < (MAX_PHYSICAL_DRIVES); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) enquiry3->pdrv_state[i] = inquiry->pdrv_info.pdrv_state[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) mega_free_sgl(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) for(i = 0; i < adapter->max_cmds; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) scb = &adapter->scb_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) if( scb->sgl64 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) dma_free_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) sizeof(mega_sgl64) * adapter->sglen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) scb->sgl64, scb->sgl_dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) scb->sgl64 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) if( scb->pthru ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) dma_free_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) sizeof(mega_passthru), scb->pthru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) scb->pthru_dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) scb->pthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if( scb->epthru ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) dma_free_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) sizeof(mega_ext_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) scb->epthru, scb->epthru_dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) scb->epthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) * Get information about the card/driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) const char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) megaraid_info(struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) static char buffer[512];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) adapter_t *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) adapter = (adapter_t *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) sprintf (buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) "LSI Logic MegaRAID %s %d commands %d targs %d chans %d luns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) adapter->fw_version, adapter->product_info.max_commands,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) adapter->host->max_id, adapter->host->max_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) (u32)adapter->host->max_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) return buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) * Abort a previous SCSI request. Only commands on the pending list can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) * aborted. All the commands issued to the F/W must complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) megaraid_abort(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) adapter_t *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) adapter = (adapter_t *)cmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) rval = megaraid_abort_and_reset(adapter, cmd, SCB_ABORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) * This is required here to complete any completed requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) * to be communicated over to the mid layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) mega_rundoneq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) megaraid_reset(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) adapter_t *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) megacmd_t mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) adapter = (adapter_t *)cmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) #if MEGA_HAVE_CLUSTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) mc.cmd = MEGA_CLUSTER_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) mc.opcode = MEGA_RESET_RESERVATIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) if( mega_internal_command(adapter, &mc, NULL) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) dev_warn(&adapter->dev->dev, "reservation reset failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) dev_info(&adapter->dev->dev, "reservation reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) spin_lock_irq(&adapter->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) rval = megaraid_abort_and_reset(adapter, cmd, SCB_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) * This is required here to complete any completed requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) * to be communicated over to the mid layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) mega_rundoneq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) spin_unlock_irq(&adapter->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) * megaraid_abort_and_reset()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) * @adapter: megaraid soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) * @cmd: scsi command to be aborted or reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) * @aor: abort or reset flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) * Try to locate the scsi command in the pending queue. If found and is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) * issued to the controller, abort/reset it. Otherwise return failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) megaraid_abort_and_reset(adapter_t *adapter, struct scsi_cmnd *cmd, int aor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) struct list_head *pos, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) dev_warn(&adapter->dev->dev, "%s cmd=%x <c=%d t=%d l=%d>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) (aor == SCB_ABORT)? "ABORTING":"RESET",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) cmd->cmnd[0], cmd->device->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) cmd->device->id, (u32)cmd->device->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) if(list_empty(&adapter->pending_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) list_for_each_safe(pos, next, &adapter->pending_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) scb = list_entry(pos, scb_t, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) if (scb->cmd == cmd) { /* Found command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) scb->state |= aor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) * Check if this command has firmware ownership. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) * yes, we cannot reset this command. Whenever f/w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) * completes this command, we will return appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) * status from ISR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if( scb->state & SCB_ISSUED ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) "%s[%x], fw owner\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) (aor==SCB_ABORT) ? "ABORTING":"RESET",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) scb->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) * Not yet issued! Remove from the pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) * list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) "%s-[%x], driver owner\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) (aor==SCB_ABORT) ? "ABORTING":"RESET",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) scb->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) mega_free_scb(adapter, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) if( aor == SCB_ABORT ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) cmd->result = (DID_ABORT << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) cmd->result = (DID_RESET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) list_add_tail(SCSI_LIST(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) &adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) return SUCCESS;
^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) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) make_local_pdev(adapter_t *adapter, struct pci_dev **pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) *pdev = pci_alloc_dev(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) if( *pdev == NULL ) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) memcpy(*pdev, adapter->dev, sizeof(struct pci_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) if (dma_set_mask(&(*pdev)->dev, DMA_BIT_MASK(32)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) kfree(*pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) free_local_pdev(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) kfree(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) * mega_allocate_inquiry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) * @dma_handle: handle returned for dma address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) * @pdev: handle to pci device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) * allocates memory for inquiry structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) static inline void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) return dma_alloc_coherent(&pdev->dev, sizeof(mega_inquiry3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) dma_handle, GFP_KERNEL);
^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) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) mega_free_inquiry(void *inquiry, dma_addr_t dma_handle, struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) dma_free_coherent(&pdev->dev, sizeof(mega_inquiry3), inquiry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) /* Following code handles /proc fs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) * proc_show_config()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * Display configuration information about the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) proc_show_config(struct seq_file *m, void *v)
^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) adapter_t *adapter = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) seq_puts(m, MEGARAID_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) if(adapter->product_info.product_name[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) seq_printf(m, "%s\n", adapter->product_info.product_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) seq_puts(m, "Controller Type: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) if( adapter->flag & BOARD_MEMMAP )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) seq_puts(m, "438/466/467/471/493/518/520/531/532\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) seq_puts(m, "418/428/434\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) if(adapter->flag & BOARD_40LD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) seq_puts(m, "Controller Supports 40 Logical Drives\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) if(adapter->flag & BOARD_64BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) seq_puts(m, "Controller capable of 64-bit memory addressing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) if( adapter->has_64bit_addr )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) seq_puts(m, "Controller using 64-bit memory addressing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) seq_puts(m, "Controller is not using 64-bit memory addressing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) seq_printf(m, "Base = %08lx, Irq = %d, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) adapter->base, adapter->host->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) seq_printf(m, "Logical Drives = %d, Channels = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) adapter->numldrv, adapter->product_info.nchannels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) seq_printf(m, "Version =%s:%s, DRAM = %dMb\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) adapter->fw_version, adapter->bios_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) adapter->product_info.dram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) seq_printf(m, "Controller Queue Depth = %d, Driver Queue Depth = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) adapter->product_info.max_commands, adapter->max_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) seq_printf(m, "support_ext_cdb = %d\n", adapter->support_ext_cdb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) seq_printf(m, "support_random_del = %d\n", adapter->support_random_del);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) seq_printf(m, "boot_ldrv_enabled = %d\n", adapter->boot_ldrv_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) seq_printf(m, "boot_ldrv = %d\n", adapter->boot_ldrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) seq_printf(m, "boot_pdrv_enabled = %d\n", adapter->boot_pdrv_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) seq_printf(m, "boot_pdrv_ch = %d\n", adapter->boot_pdrv_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) seq_printf(m, "boot_pdrv_tgt = %d\n", adapter->boot_pdrv_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) seq_printf(m, "quiescent = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) atomic_read(&adapter->quiescent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) seq_printf(m, "has_cluster = %d\n", adapter->has_cluster);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) seq_puts(m, "\nModule Parameters:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) seq_printf(m, "max_cmd_per_lun = %d\n", max_cmd_per_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) seq_printf(m, "max_sectors_per_io = %d\n", max_sectors_per_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) * proc_show_stat()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) * Display statistical information about the I/O activity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) proc_show_stat(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) adapter_t *adapter = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) seq_puts(m, "Statistical Information for this controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) seq_printf(m, "pend_cmds = %d\n", atomic_read(&adapter->pend_cmds));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) for(i = 0; i < adapter->numldrv; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) seq_printf(m, "Logical Drive %d:\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) seq_printf(m, "\tReads Issued = %lu, Writes Issued = %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) adapter->nreads[i], adapter->nwrites[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) seq_printf(m, "\tSectors Read = %lu, Sectors Written = %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) adapter->nreadblocks[i], adapter->nwriteblocks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) seq_printf(m, "\tRead errors = %lu, Write errors = %lu\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) adapter->rd_errors[i], adapter->wr_errors[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) seq_puts(m, "IO and error counters not compiled in driver.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) * proc_show_mbox()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) * Display mailbox information for the last command issued. This information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) * is good for debugging.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) proc_show_mbox(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) adapter_t *adapter = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) volatile mbox_t *mbox = adapter->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) seq_puts(m, "Contents of Mail Box Structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) seq_printf(m, " Fw Command = 0x%02x\n", mbox->m_out.cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) seq_printf(m, " Cmd Sequence = 0x%02x\n", mbox->m_out.cmdid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) seq_printf(m, " No of Sectors= %04d\n", mbox->m_out.numsectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) seq_printf(m, " LBA = 0x%02x\n", mbox->m_out.lba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) seq_printf(m, " DTA = 0x%08x\n", mbox->m_out.xferaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) seq_printf(m, " Logical Drive= 0x%02x\n", mbox->m_out.logdrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) seq_printf(m, " No of SG Elmt= 0x%02x\n", mbox->m_out.numsgelements);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) seq_printf(m, " Busy = %01x\n", mbox->m_in.busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) seq_printf(m, " Status = 0x%02x\n", mbox->m_in.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) * proc_show_rebuild_rate()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) * Display current rebuild rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) proc_show_rebuild_rate(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) adapter_t *adapter = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) dma_addr_t dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) caddr_t inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) if( make_local_pdev(adapter, &pdev) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) goto free_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) if( mega_adapinq(adapter, dma_handle) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) seq_puts(m, "Adapter inquiry failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) dev_warn(&adapter->dev->dev, "inquiry failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) if( adapter->flag & BOARD_40LD )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) seq_printf(m, "Rebuild Rate: [%d%%]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) ((mega_inquiry3 *)inquiry)->rebuild_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) seq_printf(m, "Rebuild Rate: [%d%%]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) ((mraid_ext_inquiry *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) inquiry)->raid_inq.adapter_info.rebuild_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) free_inquiry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) mega_free_inquiry(inquiry, dma_handle, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) free_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) * proc_show_battery()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) * Display information about the battery module on the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) proc_show_battery(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) adapter_t *adapter = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) dma_addr_t dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) caddr_t inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) u8 battery_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) if( make_local_pdev(adapter, &pdev) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) goto free_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) if( mega_adapinq(adapter, dma_handle) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) seq_puts(m, "Adapter inquiry failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) dev_warn(&adapter->dev->dev, "inquiry failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) battery_status = ((mega_inquiry3 *)inquiry)->battery_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) battery_status = ((mraid_ext_inquiry *)inquiry)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) raid_inq.adapter_info.battery_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) * Decode the battery status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) seq_printf(m, "Battery Status:[%d]", battery_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) if(battery_status == MEGA_BATT_CHARGE_DONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) seq_puts(m, " Charge Done");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) if(battery_status & MEGA_BATT_MODULE_MISSING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) seq_puts(m, " Module Missing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) if(battery_status & MEGA_BATT_LOW_VOLTAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) seq_puts(m, " Low Voltage");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) if(battery_status & MEGA_BATT_TEMP_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) seq_puts(m, " Temperature High");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) if(battery_status & MEGA_BATT_PACK_MISSING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) seq_puts(m, " Pack Missing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) if(battery_status & MEGA_BATT_CHARGE_INPROG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) seq_puts(m, " Charge In-progress");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) if(battery_status & MEGA_BATT_CHARGE_FAIL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) seq_puts(m, " Charge Fail");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) if(battery_status & MEGA_BATT_CYCLES_EXCEEDED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) seq_puts(m, " Cycles Exceeded");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) free_inquiry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) mega_free_inquiry(inquiry, dma_handle, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) free_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) * Display scsi inquiry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) mega_print_inquiry(struct seq_file *m, char *scsi_inq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) seq_puts(m, " Vendor: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) seq_write(m, scsi_inq + 8, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) seq_puts(m, " Model: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) seq_write(m, scsi_inq + 16, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) seq_puts(m, " Rev: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) seq_write(m, scsi_inq + 32, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) i = scsi_inq[0] & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) seq_printf(m, " Type: %s ", scsi_device_type(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) seq_printf(m, " ANSI SCSI revision: %02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) scsi_inq[2] & 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) if( (scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) seq_puts(m, " CCS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) * proc_show_pdrv()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) * @channel: channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) * Display information about the physical drives.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) proc_show_pdrv(struct seq_file *m, adapter_t *adapter, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) dma_addr_t dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) char *scsi_inq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) dma_addr_t scsi_inq_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) caddr_t inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) u8 *pdrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) u8 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) int tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) int max_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) if( make_local_pdev(adapter, &pdev) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) goto free_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) if( mega_adapinq(adapter, dma_handle) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) seq_puts(m, "Adapter inquiry failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) dev_warn(&adapter->dev->dev, "inquiry failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) scsi_inq = dma_alloc_coherent(&pdev->dev, 256, &scsi_inq_dma_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) if( scsi_inq == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) seq_puts(m, "memory not available for scsi inq.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) pdrv_state = ((mega_inquiry3 *)inquiry)->pdrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) pdrv_state = ((mraid_ext_inquiry *)inquiry)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) raid_inq.pdrv_info.pdrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) max_channels = adapter->product_info.nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) if( channel >= max_channels ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) goto free_pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) for( tgt = 0; tgt <= MAX_TARGET; tgt++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) i = channel*16 + tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) state = *(pdrv_state + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) switch( state & 0x0F ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) case PDRV_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) seq_printf(m, "Channel:%2d Id:%2d State: Online",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) channel, tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) case PDRV_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) seq_printf(m, "Channel:%2d Id:%2d State: Failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) channel, tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) case PDRV_RBLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) seq_printf(m, "Channel:%2d Id:%2d State: Rebuild",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) channel, tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) case PDRV_HOTSPARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) seq_printf(m, "Channel:%2d Id:%2d State: Hot spare",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) channel, tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) seq_printf(m, "Channel:%2d Id:%2d State: Un-configured",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) channel, tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) * This interface displays inquiries for disk drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) * only. Inquries for logical drives and non-disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) * devices are available through /proc/scsi/scsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) memset(scsi_inq, 0, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) if( mega_internal_dev_inquiry(adapter, channel, tgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) scsi_inq_dma_handle) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) (scsi_inq[0] & 0x1F) != TYPE_DISK ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) * Check for overflow. We print less than 240
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) * characters for inquiry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) seq_puts(m, ".\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) mega_print_inquiry(m, scsi_inq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) free_pci:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) dma_free_coherent(&pdev->dev, 256, scsi_inq, scsi_inq_dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) free_inquiry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) mega_free_inquiry(inquiry, dma_handle, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) free_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) * proc_show_pdrv_ch0()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) * Display information about the physical drives on physical channel 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) proc_show_pdrv_ch0(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) return proc_show_pdrv(m, m->private, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) * proc_show_pdrv_ch1()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) * Display information about the physical drives on physical channel 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) proc_show_pdrv_ch1(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) return proc_show_pdrv(m, m->private, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) * proc_show_pdrv_ch2()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) * Display information about the physical drives on physical channel 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) proc_show_pdrv_ch2(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) return proc_show_pdrv(m, m->private, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) * proc_show_pdrv_ch3()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) * Display information about the physical drives on physical channel 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) proc_show_pdrv_ch3(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) return proc_show_pdrv(m, m->private, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) * proc_show_rdrv()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) * @start: starting logical drive to display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) * @end: ending logical drive to display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) * We do not print the inquiry information since its already available through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) * /proc/scsi/scsi interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) proc_show_rdrv(struct seq_file *m, adapter_t *adapter, int start, int end )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) dma_addr_t dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) logdrv_param *lparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) megacmd_t mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) char *disk_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) dma_addr_t disk_array_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) caddr_t inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) u8 *rdrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) int num_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) u32 array_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) if( make_local_pdev(adapter, &pdev) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) goto free_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) if( mega_adapinq(adapter, dma_handle) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) seq_puts(m, "Adapter inquiry failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) dev_warn(&adapter->dev->dev, "inquiry failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) memset(&mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) array_sz = sizeof(disk_array_40ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) rdrv_state = ((mega_inquiry3 *)inquiry)->ldrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) num_ldrv = ((mega_inquiry3 *)inquiry)->num_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) array_sz = sizeof(disk_array_8ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) rdrv_state = ((mraid_ext_inquiry *)inquiry)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) raid_inq.logdrv_info.ldrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) num_ldrv = ((mraid_ext_inquiry *)inquiry)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) raid_inq.logdrv_info.num_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) disk_array = dma_alloc_coherent(&pdev->dev, array_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) &disk_array_dma_handle, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) if( disk_array == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) seq_puts(m, "memory not available.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) mc.xferaddr = (u32)disk_array_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) mc.cmd = FC_NEW_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) mc.opcode = OP_DCMD_READ_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) if( mega_internal_command(adapter, &mc, NULL) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) seq_puts(m, "40LD read config failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) goto free_pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) mc.cmd = NEW_READ_CONFIG_8LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) if( mega_internal_command(adapter, &mc, NULL) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) mc.cmd = READ_CONFIG_8LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) if( mega_internal_command(adapter, &mc, NULL) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) seq_puts(m, "8LD read config failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) goto free_pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) for( i = start; i < ( (end+1 < num_ldrv) ? end+1 : num_ldrv ); i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) lparam =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) &((disk_array_40ld *)disk_array)->ldrv[i].lparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) lparam =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) &((disk_array_8ld *)disk_array)->ldrv[i].lparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) * Check for overflow. We print less than 240 characters for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) * information about each logical drive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) seq_printf(m, "Logical drive:%2d:, ", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) switch( rdrv_state[i] & 0x0F ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) case RDRV_OFFLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) seq_puts(m, "state: offline");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) case RDRV_DEGRADED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) seq_puts(m, "state: degraded");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) case RDRV_OPTIMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) seq_puts(m, "state: optimal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) case RDRV_DELETED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) seq_puts(m, "state: deleted");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) seq_puts(m, "state: unknown");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) * Check if check consistency or initialization is going on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) * for this logical drive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) if( (rdrv_state[i] & 0xF0) == 0x20 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) seq_puts(m, ", check-consistency in progress");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) else if( (rdrv_state[i] & 0xF0) == 0x10 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) seq_puts(m, ", initialization in progress");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) seq_printf(m, "Span depth:%3d, ", lparam->span_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) seq_printf(m, "RAID level:%3d, ", lparam->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) seq_printf(m, "Stripe size:%3d, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) lparam->stripe_sz ? lparam->stripe_sz/2: 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) seq_printf(m, "Row size:%3d\n", lparam->row_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) seq_puts(m, "Read Policy: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) switch(lparam->read_ahead) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) case NO_READ_AHEAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) seq_puts(m, "No read ahead, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) case READ_AHEAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) seq_puts(m, "Read ahead, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) case ADAP_READ_AHEAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) seq_puts(m, "Adaptive, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) seq_puts(m, "Write Policy: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) switch(lparam->write_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) case WRMODE_WRITE_THRU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) seq_puts(m, "Write thru, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) case WRMODE_WRITE_BACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) seq_puts(m, "Write back, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) seq_puts(m, "Cache Policy: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) switch(lparam->direct_io) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) case CACHED_IO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) seq_puts(m, "Cached IO\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) case DIRECT_IO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) seq_puts(m, "Direct IO\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) free_pci:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) dma_free_coherent(&pdev->dev, array_sz, disk_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) disk_array_dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) free_inquiry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) mega_free_inquiry(inquiry, dma_handle, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) free_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) * proc_show_rdrv_10()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) * Display real time information about the logical drives 0 through 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) proc_show_rdrv_10(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) return proc_show_rdrv(m, m->private, 0, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) * proc_show_rdrv_20()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) * Display real time information about the logical drives 0 through 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) proc_show_rdrv_20(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) return proc_show_rdrv(m, m->private, 10, 19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) * proc_show_rdrv_30()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) * Display real time information about the logical drives 0 through 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) proc_show_rdrv_30(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) return proc_show_rdrv(m, m->private, 20, 29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) * proc_show_rdrv_40()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) * Display real time information about the logical drives 0 through 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) proc_show_rdrv_40(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) return proc_show_rdrv(m, m->private, 30, 39);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) * mega_create_proc_entry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) * @index: index in soft state array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) * @parent: parent node for this /proc entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) * Creates /proc entries for our controllers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) mega_create_proc_entry(int index, struct proc_dir_entry *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) adapter_t *adapter = hba_soft_state[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) struct proc_dir_entry *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) u8 string[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) sprintf(string, "hba%d", adapter->host->host_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) dir = proc_mkdir_data(string, 0, parent, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) if (!dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) dev_warn(&adapter->dev->dev, "proc_mkdir failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) proc_create_single_data("config", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) proc_show_config, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) proc_create_single_data("stat", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) proc_show_stat, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) proc_create_single_data("mailbox", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) proc_show_mbox, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) #if MEGA_HAVE_ENH_PROC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) proc_create_single_data("rebuild-rate", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) proc_show_rebuild_rate, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) proc_create_single_data("battery-status", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) proc_show_battery, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) proc_create_single_data("diskdrives-ch0", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) proc_show_pdrv_ch0, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) proc_create_single_data("diskdrives-ch1", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) proc_show_pdrv_ch1, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) proc_create_single_data("diskdrives-ch2", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) proc_show_pdrv_ch2, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) proc_create_single_data("diskdrives-ch3", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) proc_show_pdrv_ch3, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) proc_create_single_data("raiddrives-0-9", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) proc_show_rdrv_10, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) proc_create_single_data("raiddrives-10-19", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) proc_show_rdrv_20, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) proc_create_single_data("raiddrives-20-29", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) proc_show_rdrv_30, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) proc_create_single_data("raiddrives-30-39", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) proc_show_rdrv_40, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) static inline void mega_create_proc_entry(int index, struct proc_dir_entry *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) * megaraid_biosparam()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) * Return the disk geometry for a particular disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) megaraid_biosparam(struct scsi_device *sdev, struct block_device *bdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) sector_t capacity, int geom[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) adapter_t *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) int heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) int sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) int cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) /* Get pointer to host config structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) adapter = (adapter_t *)sdev->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) if (IS_RAID_CH(adapter, sdev->channel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) /* Default heads (64) & sectors (32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) heads = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) cylinders = (ulong)capacity / (heads * sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) * Handle extended translation size for logical drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) * > 1Gb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) if ((ulong)capacity >= 0x200000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) heads = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) sectors = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) cylinders = (ulong)capacity / (heads * sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) /* return result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) geom[0] = heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) geom[1] = sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) geom[2] = cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) if (scsi_partsize(bdev, capacity, geom))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) dev_info(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) "invalid partition on this disk on channel %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) sdev->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) /* Default heads (64) & sectors (32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) heads = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) cylinders = (ulong)capacity / (heads * sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) /* Handle extended translation size for logical drives > 1Gb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) if ((ulong)capacity >= 0x200000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) heads = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) sectors = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) cylinders = (ulong)capacity / (heads * sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) /* return result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) geom[0] = heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) geom[1] = sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) geom[2] = cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) * mega_init_scb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) * Allocate memory for the various pointers in the scb structures:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) * scatter-gather list pointer, passthru and extended passthru structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) * pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) mega_init_scb(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) for( i = 0; i < adapter->max_cmds; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) scb = &adapter->scb_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) scb->sgl64 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) scb->sgl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) scb->pthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) scb->epthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) for( i = 0; i < adapter->max_cmds; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) scb = &adapter->scb_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) scb->idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) scb->sgl64 = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) sizeof(mega_sgl64) * adapter->sglen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) &scb->sgl_dma_addr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) scb->sgl = (mega_sglist *)scb->sgl64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) if( !scb->sgl ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) dev_warn(&adapter->dev->dev, "RAID: Can't allocate sglist\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) mega_free_sgl(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) scb->pthru = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) &scb->pthru_dma_addr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) if( !scb->pthru ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) dev_warn(&adapter->dev->dev, "RAID: Can't allocate passthru\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) mega_free_sgl(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) scb->epthru = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) sizeof(mega_ext_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) &scb->epthru_dma_addr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) if( !scb->epthru ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) "Can't allocate extended passthru\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) mega_free_sgl(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) scb->dma_type = MEGA_DMA_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) * Link to free list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) * lock not required since we are loading the driver, so no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) * commands possible right now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) scb->state = SCB_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) scb->cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) list_add(&scb->list, &adapter->free_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) * megadev_open()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) * @inode: unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) * @filep: unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) * Routines for the character/ioctl interface to the driver. Find out if this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) * is a valid open.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) megadev_open (struct inode *inode, struct file *filep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) * Only allow superuser to access private ioctl interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) if( !capable(CAP_SYS_ADMIN) ) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) * megadev_ioctl()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) * @filep: Our device file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) * @cmd: ioctl command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) * @arg: user buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) * ioctl entry point for our private ioctl interface. We move the data in from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) * the user space, prepare the command (if necessary, convert the old MIMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) * ioctl to new ioctl command), and issue a synchronous command to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) * controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) megadev_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) adapter_t *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) nitioctl_t uioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) int adapno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) mega_passthru __user *upthru; /* user address for passthru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) mega_passthru *pthru; /* copy user passthru here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) dma_addr_t pthru_dma_hndl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) void *data = NULL; /* data to be transferred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) dma_addr_t data_dma_hndl; /* dma handle for data xfer area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) megacmd_t mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) megastat_t __user *ustats = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) int num_ldrv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) u32 uxferaddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) * Make sure only USCSICMD are issued through this interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) * MIMD application would still fire different command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) if( (_IOC_TYPE(cmd) != MEGAIOC_MAGIC) && (cmd != USCSICMD) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) * Check and convert a possible MIMD command to NIT command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) * mega_m_to_n() copies the data from the user space, so we do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) * have to do it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) * NOTE: We will need some user address to copyout the data, therefore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) * the inteface layer will also provide us with the required user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) * addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) memset(&uioc, 0, sizeof(nitioctl_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) if( (rval = mega_m_to_n( (void __user *)arg, &uioc)) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) switch( uioc.opcode ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) case GET_DRIVER_VER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) if( put_user(driver_ver, (u32 __user *)uioc.uioc_uaddr) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) case GET_N_ADAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) if( put_user(hba_count, (u32 __user *)uioc.uioc_uaddr) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) * Shucks. MIMD interface returns a positive value for number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) * of adapters. TODO: Change it to return 0 when there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) * applicatio using mimd interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) return hba_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) case GET_ADAP_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) * Which adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) return (-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) if( copy_to_user(uioc.uioc_uaddr, mcontroller+adapno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) sizeof(struct mcontroller)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) case GET_STATS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) * Which adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) return (-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) adapter = hba_soft_state[adapno];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) ustats = uioc.uioc_uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) if( copy_from_user(&num_ldrv, &ustats->num_ldrv, sizeof(int)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) * Check for the validity of the logical drive number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) if( num_ldrv >= MAX_LOGICAL_DRIVES_40LD ) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) if( copy_to_user(ustats->nreads, adapter->nreads,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) if( copy_to_user(ustats->nreadblocks, adapter->nreadblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) if( copy_to_user(ustats->nwrites, adapter->nwrites,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) if( copy_to_user(ustats->nwriteblocks, adapter->nwriteblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) if( copy_to_user(ustats->rd_errors, adapter->rd_errors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) if( copy_to_user(ustats->wr_errors, adapter->wr_errors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) case MBOX_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) * Which adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) return (-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) adapter = hba_soft_state[adapno];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) * Deletion of logical drive is a special case. The adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) * should be quiescent before this command is issued.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) if( uioc.uioc_rmbox[0] == FC_DEL_LOGDRV &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) uioc.uioc_rmbox[2] == OP_DEL_LOGDRV ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) * Do we support this feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) if( !adapter->support_random_del ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) dev_warn(&adapter->dev->dev, "logdrv "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) "delete on non-supporting F/W\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) rval = mega_del_logdrv( adapter, uioc.uioc_rmbox[3] );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) if( rval == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) memset(&mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) mc.status = rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) rval = mega_n_to_m((void __user *)arg, &mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) * This interface only support the regular passthru commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) * Reject extended passthru and 64-bit passthru
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU64 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) uioc.uioc_rmbox[0] == MEGA_MBOXCMD_EXTPTHRU ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) dev_warn(&adapter->dev->dev, "rejected passthru\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) * For all internal commands, the buffer must be allocated in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) * <4GB address range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) if( make_local_pdev(adapter, &pdev) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) /* Is it a passthru command or a DCMD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) /* Passthru commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) pthru = dma_alloc_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) &pthru_dma_hndl, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) if( pthru == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) return (-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) * The user passthru structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) upthru = (mega_passthru __user *)(unsigned long)MBOX(uioc)->xferaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) * Copy in the user passthru here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) if( copy_from_user(pthru, upthru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) sizeof(mega_passthru)) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) pthru, pthru_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) * Is there a data transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) if( pthru->dataxferlen ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) data = dma_alloc_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) pthru->dataxferlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) &data_dma_hndl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) if( data == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) pthru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) pthru_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) return (-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) * Save the user address and point the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) * address at just allocated memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) uxferaddr = pthru->dataxferaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) pthru->dataxferaddr = data_dma_hndl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) * Is data coming down-stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) if( pthru->dataxferlen && (uioc.flags & UIOC_WR) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) * Get the user data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) if( copy_from_user(data, (char __user *)(unsigned long) uxferaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) pthru->dataxferlen) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) rval = (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) goto freemem_and_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) memset(&mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) mc.cmd = MEGA_MBOXCMD_PASSTHRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) mc.xferaddr = (u32)pthru_dma_hndl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) * Issue the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) mega_internal_command(adapter, &mc, pthru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) rval = mega_n_to_m((void __user *)arg, &mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) if( rval ) goto freemem_and_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) * Is data going up-stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) if( pthru->dataxferlen && (uioc.flags & UIOC_RD) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) if( copy_to_user((char __user *)(unsigned long) uxferaddr, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) pthru->dataxferlen) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) rval = (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) * Send the request sense data also, irrespective of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) * whether the user has asked for it or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) if (copy_to_user(upthru->reqsensearea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) pthru->reqsensearea, 14))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) rval = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) freemem_and_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) if( pthru->dataxferlen ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) pthru->dataxferlen, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) data_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) dma_free_coherent(&pdev->dev, sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) pthru, pthru_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) /* DCMD commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) * Is there a data transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) if( uioc.xferlen ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) data = dma_alloc_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) uioc.xferlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) &data_dma_hndl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) if( data == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) return (-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) uxferaddr = MBOX(uioc)->xferaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) * Is data coming down-stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) if( uioc.xferlen && (uioc.flags & UIOC_WR) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) * Get the user data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) if( copy_from_user(data, (char __user *)(unsigned long) uxferaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) uioc.xferlen) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) uioc.xferlen, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) data_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) memcpy(&mc, MBOX(uioc), sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) mc.xferaddr = (u32)data_dma_hndl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) * Issue the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) mega_internal_command(adapter, &mc, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) rval = mega_n_to_m((void __user *)arg, &mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) if( rval ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) if( uioc.xferlen ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) uioc.xferlen, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) data_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) * Is data going up-stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) if( uioc.xferlen && (uioc.flags & UIOC_RD) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) if( copy_to_user((char __user *)(unsigned long) uxferaddr, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) uioc.xferlen) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) rval = (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) if( uioc.xferlen ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) dma_free_coherent(&pdev->dev, uioc.xferlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) data, data_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) megadev_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) mutex_lock(&megadev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) ret = megadev_ioctl(filep, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) mutex_unlock(&megadev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) * mega_m_to_n()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) * @arg: user address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) * @uioc: new ioctl structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) * A thin layer to convert older mimd interface ioctl structure to NIT ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) * structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) * Converts the older mimd ioctl structure to newer NIT structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) mega_m_to_n(void __user *arg, nitioctl_t *uioc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) struct uioctl_t uioc_mimd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) char signature[8] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) u8 opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) u8 subopcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) * check is the application conforms to NIT. We do not have to do much
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) * in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) * We exploit the fact that the signature is stored in the very
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) * beginning of the structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) if( copy_from_user(signature, arg, 7) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) if( memcmp(signature, "MEGANIT", 7) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) * NOTE NOTE: The nit ioctl is still under flux because of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) * change of mailbox definition, in HPE. No applications yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) * use this interface and let's not have applications use this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) * interface till the new specifitions are in place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) if( copy_from_user(uioc, arg, sizeof(nitioctl_t)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) * Else assume we have mimd uioctl_t as arg. Convert to nitioctl_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) * Get the user ioctl structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) if( copy_from_user(&uioc_mimd, arg, sizeof(struct uioctl_t)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) * Get the opcode and subopcode for the commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) opcode = uioc_mimd.ui.fcs.opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) subopcode = uioc_mimd.ui.fcs.subopcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) case 0x82:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) switch (subopcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) case MEGAIOC_QDRVRVER: /* Query driver version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) uioc->opcode = GET_DRIVER_VER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) uioc->uioc_uaddr = uioc_mimd.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) case MEGAIOC_QNADAP: /* Get # of adapters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) uioc->opcode = GET_N_ADAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) uioc->uioc_uaddr = uioc_mimd.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) case MEGAIOC_QADAPINFO: /* Get adapter information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) uioc->opcode = GET_ADAP_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) uioc->adapno = uioc_mimd.ui.fcs.adapno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) uioc->uioc_uaddr = uioc_mimd.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) return(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) case 0x81:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) uioc->opcode = MBOX_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) uioc->adapno = uioc_mimd.ui.fcs.adapno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) memcpy(uioc->uioc_rmbox, uioc_mimd.mbox, 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) uioc->xferlen = uioc_mimd.ui.fcs.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) if( uioc_mimd.outlen ) uioc->flags = UIOC_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) if( uioc_mimd.inlen ) uioc->flags |= UIOC_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) case 0x80:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) uioc->opcode = MBOX_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) uioc->adapno = uioc_mimd.ui.fcs.adapno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) memcpy(uioc->uioc_rmbox, uioc_mimd.mbox, 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) * Choose the xferlen bigger of input and output data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) uioc->xferlen = uioc_mimd.outlen > uioc_mimd.inlen ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) uioc_mimd.outlen : uioc_mimd.inlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) if( uioc_mimd.outlen ) uioc->flags = UIOC_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) if( uioc_mimd.inlen ) uioc->flags |= UIOC_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) * mega_n_to_m()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) * @arg: user address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) * @mc: mailbox command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) * Updates the status information to the application, depending on application
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) * conforms to older mimd ioctl interface or newer NIT ioctl interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) mega_n_to_m(void __user *arg, megacmd_t *mc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) nitioctl_t __user *uiocp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) megacmd_t __user *umc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) mega_passthru __user *upthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) struct uioctl_t __user *uioc_mimd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) char signature[8] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) * check is the application conforms to NIT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) if( copy_from_user(signature, arg, 7) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) if( memcmp(signature, "MEGANIT", 7) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) uiocp = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) if( put_user(mc->status, (u8 __user *)&MBOX_P(uiocp)->status) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) umc = MBOX_P(uiocp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) if (get_user(upthru, (mega_passthru __user * __user *)&umc->xferaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) if( put_user(mc->status, (u8 __user *)&upthru->scsistatus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) uioc_mimd = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) if( put_user(mc->status, (u8 __user *)&uioc_mimd->mbox[17]) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) umc = (megacmd_t __user *)uioc_mimd->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) if (get_user(upthru, (mega_passthru __user * __user *)&umc->xferaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) if( put_user(mc->status, (u8 __user *)&upthru->scsistatus) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) * MEGARAID 'FW' commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) * mega_is_bios_enabled()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) * issue command to find out if the BIOS is enabled for this controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) mega_is_bios_enabled(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) unsigned char raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) raw_mbox[0] = IS_BIOS_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) raw_mbox[2] = GET_BIOS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) return *(char *)adapter->mega_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) * mega_enum_raid_scsi()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) * Find out what channels are RAID/SCSI. This information is used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) * differentiate the virtual channels and physical channels and to support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) * ROMB feature and non-disk devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) mega_enum_raid_scsi(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) unsigned char raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) * issue command to find out what channels are raid/scsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) raw_mbox[0] = CHNL_CLASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) raw_mbox[2] = GET_CHNL_CLASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) * Non-ROMB firmware fail this command, so all channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) * must be shown RAID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) adapter->mega_ch_class = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) if(!issue_scb_block(adapter, raw_mbox)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) adapter->mega_ch_class = *((char *)adapter->mega_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) for( i = 0; i < adapter->product_info.nchannels; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) if( (adapter->mega_ch_class >> i) & 0x01 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) dev_info(&adapter->dev->dev, "channel[%d] is raid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) dev_info(&adapter->dev->dev, "channel[%d] is scsi\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) * mega_get_boot_drv()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) * Find out which device is the boot device. Note, any logical drive or any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) * phyical device (e.g., a CDROM) can be designated as a boot device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) mega_get_boot_drv(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) struct private_bios_data *prv_bios_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) unsigned char raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) u16 cksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) u8 *cksum_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) u8 boot_pdrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) raw_mbox[0] = BIOS_PVT_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) raw_mbox[2] = GET_BIOS_PVT_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) adapter->boot_ldrv_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) adapter->boot_ldrv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) adapter->boot_pdrv_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) adapter->boot_pdrv_ch = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) adapter->boot_pdrv_tgt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) if(issue_scb_block(adapter, raw_mbox) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) prv_bios_data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) (struct private_bios_data *)adapter->mega_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) cksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) cksum_p = (char *)prv_bios_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) for (i = 0; i < 14; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) cksum += (u16)(*cksum_p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) if (prv_bios_data->cksum == (u16)(0-cksum) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) * If MSB is set, a physical drive is set as boot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) * device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) if( prv_bios_data->boot_drv & 0x80 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) adapter->boot_pdrv_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) boot_pdrv = prv_bios_data->boot_drv & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) adapter->boot_pdrv_ch = boot_pdrv / 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) adapter->boot_pdrv_tgt = boot_pdrv % 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) adapter->boot_ldrv_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) adapter->boot_ldrv = prv_bios_data->boot_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) * mega_support_random_del()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) * Find out if this controller supports random deletion and addition of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) * logical drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) mega_support_random_del(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) unsigned char raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) * issue command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) raw_mbox[0] = FC_DEL_LOGDRV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) raw_mbox[2] = OP_SUP_DEL_LOGDRV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) rval = issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) return !rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) * mega_support_ext_cdb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) * Find out if this firmware support cdblen > 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) mega_support_ext_cdb(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) unsigned char raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) * issue command to find out if controller supports extended CDBs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) raw_mbox[0] = 0xA4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) raw_mbox[2] = 0x16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) rval = issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) return !rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) * mega_del_logdrv()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) * @logdrv: logical drive to be deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) * Delete the specified logical drive. It is the responsibility of the user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) * app to let the OS know about this operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) mega_del_logdrv(adapter_t *adapter, int logdrv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) * Stop sending commands to the controller, queue them internally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) * When deletion is complete, ISR will flush the queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) atomic_set(&adapter->quiescent, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) * Wait till all the issued commands are complete and there are no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) * commands in the pending queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) while (atomic_read(&adapter->pend_cmds) > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) !list_empty(&adapter->pending_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) msleep(1000); /* sleep for 1s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) rval = mega_do_del_logdrv(adapter, logdrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) spin_lock_irqsave(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) * If delete operation was successful, add 0x80 to the logical drive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) * ids for commands in the pending queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) if (adapter->read_ldidmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) struct list_head *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) list_for_each(pos, &adapter->pending_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) scb = list_entry(pos, scb_t, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) if (scb->pthru->logdrv < 0x80 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) scb->pthru->logdrv += 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) atomic_set(&adapter->quiescent, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) mega_runpendq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) spin_unlock_irqrestore(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) mega_do_del_logdrv(adapter_t *adapter, int logdrv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) megacmd_t mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) memset( &mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) mc.cmd = FC_DEL_LOGDRV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) mc.opcode = OP_DEL_LOGDRV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) mc.subopcode = logdrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) rval = mega_internal_command(adapter, &mc, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) /* log this event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) if(rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) dev_warn(&adapter->dev->dev, "Delete LD-%d failed", logdrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) * After deleting first logical drive, the logical drives must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) * addressed by adding 0x80 to the logical drive id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) adapter->read_ldidmap = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) * mega_get_max_sgl()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) * Find out the maximum number of scatter-gather elements supported by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) * version of the firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) mega_get_max_sgl(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) unsigned char raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) memset(mbox, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) raw_mbox[0] = MAIN_MISC_OPCODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) raw_mbox[2] = GET_MAX_SG_SUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) if( issue_scb_block(adapter, raw_mbox) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) * f/w does not support this command. Choose the default value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) adapter->sglen = MIN_SGLIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) adapter->sglen = *((char *)adapter->mega_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) * Make sure this is not more than the resources we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) * planning to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) if ( adapter->sglen > MAX_SGLIST )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) adapter->sglen = MAX_SGLIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) * mega_support_cluster()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) * Find out if this firmware support cluster calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) mega_support_cluster(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) unsigned char raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) memset(mbox, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) * Try to get the initiator id. This command will succeed iff the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) * clustering is available on this HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) raw_mbox[0] = MEGA_GET_TARGET_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) if( issue_scb_block(adapter, raw_mbox) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) * Cluster support available. Get the initiator target id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) * Tell our id to mid-layer too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) adapter->this_id = *(u32 *)adapter->mega_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) adapter->host->this_id = adapter->this_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) * mega_adapinq()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) * @dma_handle: DMA address of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) * Issue internal commands while interrupts are available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) * We only issue direct mailbox commands from within the driver. ioctl()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) * interface using these routines can issue passthru commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) mega_adapinq(adapter_t *adapter, dma_addr_t dma_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) megacmd_t mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) memset(&mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) mc.cmd = FC_NEW_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) mc.opcode = NC_SUBOP_ENQUIRY3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) mc.subopcode = ENQ3_GET_SOLICITED_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) mc.cmd = MEGA_MBOXCMD_ADPEXTINQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) mc.xferaddr = (u32)dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) if ( mega_internal_command(adapter, &mc, NULL) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) * mega_internal_dev_inquiry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) * @ch: channel for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) * @tgt: ID of this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) * @buf_dma_handle: DMA address of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) * Issue the scsi inquiry for the specified device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) dma_addr_t buf_dma_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) mega_passthru *pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) dma_addr_t pthru_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) megacmd_t mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) * For all internal commands, the buffer must be allocated in <4GB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) * address range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) if( make_local_pdev(adapter, &pdev) != 0 ) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) pthru = dma_alloc_coherent(&pdev->dev, sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) &pthru_dma_handle, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) if( pthru == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) pthru->timeout = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) pthru->ars = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) pthru->reqsenselen = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) pthru->islogical = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) pthru->channel = (adapter->flag & BOARD_40LD) ? 0 : ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) pthru->target = (adapter->flag & BOARD_40LD) ? (ch << 4)|tgt : tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) pthru->cdblen = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) pthru->cdb[0] = INQUIRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) pthru->cdb[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) pthru->cdb[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) pthru->cdb[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) pthru->cdb[4] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) pthru->cdb[5] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) pthru->dataxferaddr = (u32)buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) pthru->dataxferlen = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) memset(&mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) mc.cmd = MEGA_MBOXCMD_PASSTHRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) mc.xferaddr = (u32)pthru_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) rval = mega_internal_command(adapter, &mc, pthru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) dma_free_coherent(&pdev->dev, sizeof(mega_passthru), pthru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) pthru_dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) * mega_internal_command()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) * @mc: the mailbox command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) * @pthru: Passthru structure for DCDB commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) * Issue the internal commands in interrupt mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) * The last argument is the address of the passthru structure if the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) * to be fired is a passthru command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) * Note: parameter 'pthru' is null for non-passthru commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) * The internal commands share one command id and hence are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) * serialized. This is so because we want to reserve maximum number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) * available command ids for the I/O commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) mutex_lock(&adapter->int_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) scb = &adapter->int_scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) memset(scb, 0, sizeof(scb_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) scb->idx = CMDID_INT_CMDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) scb->state |= SCB_ACTIVE | SCB_PENDQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) memcpy(scb->raw_mbox, mc, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) * Is it a passthru command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) if (mc->cmd == MEGA_MBOXCMD_PASSTHRU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) scb->pthru = pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) spin_lock_irqsave(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) list_add_tail(&scb->list, &adapter->pending_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) * Check if the HBA is in quiescent state, e.g., during a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) * delete logical drive opertion. If it is, don't run
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) * the pending_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) if (atomic_read(&adapter->quiescent) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) mega_runpendq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) spin_unlock_irqrestore(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) wait_for_completion(&adapter->int_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) mc->status = rval = adapter->int_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) * Print a debug message for all failed commands. Applications can use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) * this information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) if (rval && trace_level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) dev_info(&adapter->dev->dev, "cmd [%x, %x, %x] status:[%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) mc->cmd, mc->opcode, mc->subopcode, rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) mutex_unlock(&adapter->int_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) static struct scsi_host_template megaraid_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) .name = "MegaRAID",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) .proc_name = "megaraid_legacy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) .info = megaraid_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) .queuecommand = megaraid_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) .bios_param = megaraid_biosparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) .max_sectors = MAX_SECTORS_PER_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) .can_queue = MAX_COMMANDS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) .this_id = DEFAULT_INITIATOR_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) .sg_tablesize = MAX_SGLIST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) .cmd_per_lun = DEF_CMD_PER_LUN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) .eh_abort_handler = megaraid_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) .eh_device_reset_handler = megaraid_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) .eh_bus_reset_handler = megaraid_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) .eh_host_reset_handler = megaraid_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) .no_write_same = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) adapter_t *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) unsigned long mega_baseport, tbase, flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) u16 subsysid, subsysvid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) u8 pci_bus, pci_dev_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) int irq, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) int error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) if (hba_count >= MAX_CONTROLLERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) if (pci_enable_device(pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) pci_bus = pdev->bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) pci_dev_func = pdev->devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) * The megaraid3 stuff reports the ID of the Intel part which is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) * remotely specific to the megaraid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) u16 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) * Don't fall over the Compaq management cards using the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) * PCI identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) pdev->subsystem_device == 0xC000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) goto out_disable_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) /* Now check the magic signature byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) if (magic != HBA_SIGNATURE_471 && magic != HBA_SIGNATURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) goto out_disable_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) /* Ok it is probably a megaraid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) * For these vendor and device ids, signature offsets are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) * valid and 64 bit is implicit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) if (id->driver_data & BOARD_64BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) flag |= BOARD_64BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) u32 magic64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) pci_read_config_dword(pdev, PCI_CONF_AMISIG64, &magic64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) if (magic64 == HBA_SIGNATURE_64BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) flag |= BOARD_64BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) subsysvid = pdev->subsystem_vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) subsysid = pdev->subsystem_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) dev_notice(&pdev->dev, "found 0x%4.04x:0x%4.04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) id->vendor, id->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) /* Read the base port and IRQ from PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) mega_baseport = pci_resource_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) irq = pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) tbase = mega_baseport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) if (pci_resource_flags(pdev, 0) & IORESOURCE_MEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) flag |= BOARD_MEMMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) if (!request_mem_region(mega_baseport, 128, "megaraid")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) dev_warn(&pdev->dev, "mem region busy!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) goto out_disable_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) mega_baseport = (unsigned long)ioremap(mega_baseport, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) if (!mega_baseport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) dev_warn(&pdev->dev, "could not map hba memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) goto out_release_region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) flag |= BOARD_IOMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) mega_baseport += 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) if (!request_region(mega_baseport, 16, "megaraid"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) goto out_disable_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) /* Initialize SCSI Host structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) host = scsi_host_alloc(&megaraid_template, sizeof(adapter_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) goto out_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) adapter = (adapter_t *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) memset(adapter, 0, sizeof(adapter_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) dev_notice(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) "scsi%d:Found MegaRAID controller at 0x%lx, IRQ:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) host->host_no, mega_baseport, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) adapter->base = mega_baseport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) if (flag & BOARD_MEMMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) adapter->mmio_base = (void __iomem *) mega_baseport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) INIT_LIST_HEAD(&adapter->free_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) INIT_LIST_HEAD(&adapter->pending_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) INIT_LIST_HEAD(&adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) adapter->flag = flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) spin_lock_init(&adapter->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) host->cmd_per_lun = max_cmd_per_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) host->max_sectors = max_sectors_per_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) adapter->dev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) adapter->host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) adapter->host->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) if (flag & BOARD_MEMMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) adapter->host->base = tbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) adapter->host->io_port = tbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) adapter->host->n_io_port = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) adapter->host->unique_id = (pci_bus << 8) | pci_dev_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) * Allocate buffer to issue internal commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) adapter->mega_buffer = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) MEGA_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) &adapter->buf_dma_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) if (!adapter->mega_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) dev_warn(&pdev->dev, "out of RAM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) goto out_host_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) adapter->scb_list = kmalloc_array(MAX_COMMANDS, sizeof(scb_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) if (!adapter->scb_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) dev_warn(&pdev->dev, "out of RAM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) goto out_free_cmd_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) if (request_irq(irq, (adapter->flag & BOARD_MEMMAP) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) megaraid_isr_memmapped : megaraid_isr_iomapped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) IRQF_SHARED, "megaraid", adapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) dev_warn(&pdev->dev, "Couldn't register IRQ %d!\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) goto out_free_scb_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) if (mega_setup_mailbox(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) goto out_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) if (mega_query_adapter(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) goto out_free_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) * Have checks for some buggy f/w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) if ((subsysid == 0x1111) && (subsysvid == 0x1111)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) * Which firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) if (!strcmp(adapter->fw_version, "3.00") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) !strcmp(adapter->fw_version, "3.01")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) dev_warn(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) "Your card is a Dell PERC "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) "2/SC RAID controller with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) "firmware\nmegaraid: 3.00 or 3.01. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) "This driver is known to have "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) "corruption issues\nmegaraid: with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) "those firmware versions on this "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) "specific card. In order\nmegaraid: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) "to protect your data, please upgrade "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) "your firmware to version\nmegaraid: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) "3.10 or later, available from the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) "Dell Technical Support web\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) "megaraid: site at\nhttp://support."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) "dell.com/us/en/filelib/download/"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) "index.asp?fileid=2940\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) * If we have a HP 1M(0x60E7)/2M(0x60E8) controller with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) * firmware H.01.07, H.01.08, and H.01.09 disable 64 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) * support, since this firmware cannot handle 64 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) * addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) if ((subsysvid == PCI_VENDOR_ID_HP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) ((subsysid == 0x60E7) || (subsysid == 0x60E8))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) * which firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) if (!strcmp(adapter->fw_version, "H01.07") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) !strcmp(adapter->fw_version, "H01.08") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) !strcmp(adapter->fw_version, "H01.09") ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) dev_warn(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) "Firmware H.01.07, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) "H.01.08, and H.01.09 on 1M/2M "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) "controllers\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) "do not support 64 bit "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) "addressing.\nDISABLING "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) "64 bit support.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) adapter->flag &= ~BOARD_64BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) if (mega_is_bios_enabled(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) mega_hbas[hba_count].is_bios_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) mega_hbas[hba_count].hostdata_addr = adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) * Find out which channel is raid and which is scsi. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) * for ROMB support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) mega_enum_raid_scsi(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) * Find out if a logical drive is set as the boot drive. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) * there is one, will make that as the first logical drive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) * ROMB: Do we have to boot from a physical drive. Then all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) * the physical drives would appear before the logical disks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) * Else, all the physical drives would be exported to the mid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) * layer after logical drives.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) mega_get_boot_drv(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) if (adapter->boot_pdrv_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) j = adapter->product_info.nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) for( i = 0; i < j; i++ )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) adapter->logdrv_chan[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) for( i = j; i < NVIRT_CHAN + j; i++ )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) adapter->logdrv_chan[i] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) for (i = 0; i < NVIRT_CHAN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) adapter->logdrv_chan[i] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) for (i = NVIRT_CHAN; i < MAX_CHANNELS+NVIRT_CHAN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) adapter->logdrv_chan[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) adapter->mega_ch_class <<= NVIRT_CHAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) * Do we support random deletion and addition of logical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) * drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) adapter->read_ldidmap = 0; /* set it after first logdrv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) delete cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) adapter->support_random_del = mega_support_random_del(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) /* Initialize SCBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) if (mega_init_scb(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) goto out_free_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) * Reset the pending commands counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) atomic_set(&adapter->pend_cmds, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) * Reset the adapter quiescent flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) atomic_set(&adapter->quiescent, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) hba_soft_state[hba_count] = adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) * Fill in the structure which needs to be passed back to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) * application when it does an ioctl() for controller related
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) * information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) i = hba_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) mcontroller[i].base = mega_baseport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) mcontroller[i].irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) mcontroller[i].numldrv = adapter->numldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) mcontroller[i].pcibus = pci_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) mcontroller[i].pcidev = id->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) mcontroller[i].pcifun = PCI_FUNC (pci_dev_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) mcontroller[i].pciid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) mcontroller[i].pcivendor = id->vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) mcontroller[i].pcislot = PCI_SLOT(pci_dev_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) mcontroller[i].uid = (pci_bus << 8) | pci_dev_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) /* Set the Mode of addressing to 64 bit if we can */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) if ((adapter->flag & BOARD_64BIT) && (sizeof(dma_addr_t) == 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) adapter->has_64bit_addr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) adapter->has_64bit_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) mutex_init(&adapter->int_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) init_completion(&adapter->int_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) adapter->this_id = DEFAULT_INITIATOR_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) adapter->host->this_id = DEFAULT_INITIATOR_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) #if MEGA_HAVE_CLUSTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) * Is cluster support enabled on this controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) * Note: In a cluster the HBAs ( the initiators ) will have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) * different target IDs and we cannot assume it to be 7. Call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) * to mega_support_cluster() will get the target ids also if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) * the cluster support is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) adapter->has_cluster = mega_support_cluster(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) if (adapter->has_cluster) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) dev_notice(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) "Cluster driver, initiator id:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) adapter->this_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) pci_set_drvdata(pdev, host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) mega_create_proc_entry(hba_count, mega_proc_dir_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) error = scsi_add_host(host, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) goto out_free_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) scsi_scan_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) hba_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) out_free_mbox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) dma_free_coherent(&adapter->dev->dev, sizeof(mbox64_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) adapter->una_mbox64, adapter->una_mbox64_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) out_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) free_irq(adapter->host->irq, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) out_free_scb_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) kfree(adapter->scb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) out_free_cmd_buffer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) dma_free_coherent(&adapter->dev->dev, MEGA_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) adapter->mega_buffer, adapter->buf_dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) out_host_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) out_iounmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) if (flag & BOARD_MEMMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) iounmap((void *)mega_baseport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) out_release_region:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) if (flag & BOARD_MEMMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) release_mem_region(tbase, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) release_region(mega_baseport, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) out_disable_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) __megaraid_shutdown(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) u_char raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) mbox_t *mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) /* Flush adapter cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) raw_mbox[0] = FLUSH_ADAPTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) free_irq(adapter->host->irq, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) /* Issue a blocking (interrupts disabled) command to the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) /* Flush disks cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) raw_mbox[0] = FLUSH_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) /* Issue a blocking (interrupts disabled) command to the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) if (atomic_read(&adapter->pend_cmds) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) dev_warn(&adapter->dev->dev, "pending commands!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) * Have a delibrate delay to make sure all the caches are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) * actually flushed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) for (i = 0; i <= 10; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) mdelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) megaraid_remove_one(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) struct Scsi_Host *host = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) adapter_t *adapter = (adapter_t *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) char buf[12] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) scsi_remove_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) __megaraid_shutdown(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) /* Free our resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) if (adapter->flag & BOARD_MEMMAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) iounmap((void *)adapter->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) release_mem_region(adapter->host->base, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) release_region(adapter->base, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) mega_free_sgl(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) sprintf(buf, "hba%d", adapter->host->host_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) remove_proc_subtree(buf, mega_proc_dir_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) dma_free_coherent(&adapter->dev->dev, MEGA_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) adapter->mega_buffer, adapter->buf_dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) kfree(adapter->scb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) dma_free_coherent(&adapter->dev->dev, sizeof(mbox64_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) adapter->una_mbox64, adapter->una_mbox64_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) hba_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) megaraid_shutdown(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) struct Scsi_Host *host = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) adapter_t *adapter = (adapter_t *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) __megaraid_shutdown(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) static struct pci_device_id megaraid_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) {PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) {PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_AMI_MEGARAID3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) {0,}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) static struct pci_driver megaraid_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) .name = "megaraid_legacy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) .id_table = megaraid_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) .probe = megaraid_probe_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) .remove = megaraid_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) .shutdown = megaraid_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) static int __init megaraid_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) if ((max_cmd_per_lun <= 0) || (max_cmd_per_lun > MAX_CMD_PER_LUN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) max_cmd_per_lun = MAX_CMD_PER_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) if (max_mbox_busy_wait > MBOX_BUSY_WAIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) max_mbox_busy_wait = MBOX_BUSY_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) mega_proc_dir_entry = proc_mkdir("megaraid", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) if (!mega_proc_dir_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) "megaraid: failed to create megaraid root\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) error = pci_register_driver(&megaraid_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) remove_proc_entry("megaraid", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) * Register the driver as a character device, for applications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) * to access it for ioctls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) * First argument (major) to register_chrdev implies a dynamic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) * major number allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) major = register_chrdev(0, "megadev_legacy", &megadev_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) if (!major) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) "megaraid: failed to register char device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) static void __exit megaraid_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) * Unregister the character device interface to the driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) unregister_chrdev(major, "megadev_legacy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) pci_unregister_driver(&megaraid_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) remove_proc_entry("megaraid", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) module_init(megaraid_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) module_exit(megaraid_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) /* vi: set ts=8 sw=8 tw=78: */