Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Aic94xx SAS/SATA driver initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include "aic94xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include "aic94xx_reg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include "aic94xx_hwi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "aic94xx_seq.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "aic94xx_sds.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) /* The format is "version.release.patchlevel" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #define ASD_DRIVER_VERSION "1.0.3"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) static int use_msi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) module_param_named(use_msi, use_msi, int, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) MODULE_PARM_DESC(use_msi, "\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 	"\tEnable(1) or disable(0) using PCI MSI.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 	"\tDefault: 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) static struct scsi_transport_template *aic94xx_transport_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) static int asd_scan_finished(struct Scsi_Host *, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) static void asd_scan_start(struct Scsi_Host *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) static struct scsi_host_template aic94xx_sht = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	.module			= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	/* .name is initialized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	.name			= "aic94xx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	.queuecommand		= sas_queuecommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	.dma_need_drain		= ata_scsi_dma_need_drain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	.target_alloc		= sas_target_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	.slave_configure	= sas_slave_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	.scan_finished		= asd_scan_finished,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	.scan_start		= asd_scan_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	.change_queue_depth	= sas_change_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	.bios_param		= sas_bios_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	.can_queue		= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	.this_id		= -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	.sg_tablesize		= SG_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	.max_sectors		= SCSI_DEFAULT_MAX_SECTORS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	.eh_device_reset_handler	= sas_eh_device_reset_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	.eh_target_reset_handler	= sas_eh_target_reset_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	.slave_alloc		= sas_slave_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	.target_destroy		= sas_target_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	.ioctl			= sas_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	.compat_ioctl		= sas_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	.track_queue_depth	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) static int asd_map_memio(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	struct asd_ha_addrspace *io_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	asd_ha->iospace = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	for (i = 0; i < 3; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 		io_handle = &asd_ha->io_handle[i==0?0:1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 		io_handle->start = pci_resource_start(asd_ha->pcidev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 		io_handle->len   = pci_resource_len(asd_ha->pcidev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 		io_handle->flags = pci_resource_flags(asd_ha->pcidev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 		if (!io_handle->start || !io_handle->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 			asd_printk("MBAR%d start or length for %s is 0.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 				   i==0?0:1, pci_name(asd_ha->pcidev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 			goto Err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 		err = pci_request_region(asd_ha->pcidev, i, ASD_DRIVER_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 			asd_printk("couldn't reserve memory region for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 				   pci_name(asd_ha->pcidev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 			goto Err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 		io_handle->addr = ioremap(io_handle->start, io_handle->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 		if (!io_handle->addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 			asd_printk("couldn't map MBAR%d of %s\n", i==0?0:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 				   pci_name(asd_ha->pcidev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 			goto Err_unreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) Err_unreq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	pci_release_region(asd_ha->pcidev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) Err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	if (i > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		io_handle = &asd_ha->io_handle[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 		iounmap(io_handle->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 		pci_release_region(asd_ha->pcidev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) static void asd_unmap_memio(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	struct asd_ha_addrspace *io_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	io_handle = &asd_ha->io_handle[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	iounmap(io_handle->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	pci_release_region(asd_ha->pcidev, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	io_handle = &asd_ha->io_handle[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	iounmap(io_handle->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	pci_release_region(asd_ha->pcidev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) static int asd_map_ioport(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	int i = PCI_IOBAR_OFFSET, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	asd_ha->iospace = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	io_handle->start = pci_resource_start(asd_ha->pcidev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	io_handle->len   = pci_resource_len(asd_ha->pcidev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	io_handle->flags = pci_resource_flags(asd_ha->pcidev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	io_handle->addr  = (void __iomem *) io_handle->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	if (!io_handle->start || !io_handle->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 		asd_printk("couldn't get IO ports for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 			   pci_name(asd_ha->pcidev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	err = pci_request_region(asd_ha->pcidev, i, ASD_DRIVER_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 		asd_printk("couldn't reserve io space for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 			   pci_name(asd_ha->pcidev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) static void asd_unmap_ioport(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	pci_release_region(asd_ha->pcidev, PCI_IOBAR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static int asd_map_ha(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	u16 cmd_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	err = pci_read_config_word(asd_ha->pcidev, PCI_COMMAND, &cmd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 		asd_printk("couldn't read command register of %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 			   pci_name(asd_ha->pcidev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		goto Err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	if (cmd_reg & PCI_COMMAND_MEMORY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		if ((err = asd_map_memio(asd_ha)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 			goto Err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	} else if (cmd_reg & PCI_COMMAND_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		if ((err = asd_map_ioport(asd_ha)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 			goto Err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 		asd_printk("%s ioport mapped -- upgrade your hardware\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 			   pci_name(asd_ha->pcidev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		asd_printk("no proper device access to %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 			   pci_name(asd_ha->pcidev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 		goto Err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) Err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	return err;
^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) static void asd_unmap_ha(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	if (asd_ha->iospace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		asd_unmap_ioport(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		asd_unmap_memio(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) static const char *asd_dev_rev[30] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	[0] = "A0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	[1] = "A1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	[8] = "B0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) static int asd_common_setup(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	asd_ha->revision_id = asd_ha->pcidev->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	if (asd_ha->revision_id < AIC9410_DEV_REV_B0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		asd_printk("%s is revision %s (%X), which is not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 			   pci_name(asd_ha->pcidev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 			   asd_dev_rev[asd_ha->revision_id],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 			   asd_ha->revision_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		goto Err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	/* Provide some sane default values. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	asd_ha->hw_prof.max_scbs = 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	asd_ha->hw_prof.max_ddbs = ASD_MAX_DDBS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	asd_ha->hw_prof.num_phys = ASD_MAX_PHYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	/* All phys are enabled, by default. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	asd_ha->hw_prof.enabled_phys = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	for (i = 0; i < ASD_MAX_PHYS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		asd_ha->hw_prof.phy_desc[i].max_sas_lrate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 			SAS_LINK_RATE_3_0_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		asd_ha->hw_prof.phy_desc[i].min_sas_lrate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 			SAS_LINK_RATE_1_5_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		asd_ha->hw_prof.phy_desc[i].max_sata_lrate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 			SAS_LINK_RATE_1_5_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 		asd_ha->hw_prof.phy_desc[i].min_sata_lrate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 			SAS_LINK_RATE_1_5_GBPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) Err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) static int asd_aic9410_setup(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	int err = asd_common_setup(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	asd_ha->hw_prof.addr_range = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	asd_ha->hw_prof.port_name_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	asd_ha->hw_prof.dev_name_base = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	asd_ha->hw_prof.sata_name_base = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) static int asd_aic9405_setup(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	int err = asd_common_setup(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	asd_ha->hw_prof.addr_range = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	asd_ha->hw_prof.port_name_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	asd_ha->hw_prof.dev_name_base = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	asd_ha->hw_prof.sata_name_base = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) static ssize_t asd_show_dev_rev(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 				struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	return snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 			asd_dev_rev[asd_ha->revision_id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) static DEVICE_ATTR(aic_revision, S_IRUGO, asd_show_dev_rev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) static ssize_t asd_show_dev_bios_build(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 				       struct device_attribute *attr,char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	return snprintf(buf, PAGE_SIZE, "%d\n", asd_ha->hw_prof.bios.bld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) static DEVICE_ATTR(bios_build, S_IRUGO, asd_show_dev_bios_build, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) static ssize_t asd_show_dev_pcba_sn(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 				    struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	return snprintf(buf, PAGE_SIZE, "%s\n", asd_ha->hw_prof.pcba_sn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) static DEVICE_ATTR(pcba_sn, S_IRUGO, asd_show_dev_pcba_sn, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) #define FLASH_CMD_NONE      0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) #define FLASH_CMD_UPDATE    0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) #define FLASH_CMD_VERIFY    0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) struct flash_command {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293)      u8      command[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294)      int     code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) static struct flash_command flash_command_table[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299)      {"verify",      FLASH_CMD_VERIFY},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300)      {"update",      FLASH_CMD_UPDATE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301)      {"",            FLASH_CMD_NONE}      /* Last entry should be NULL. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) struct error_bios {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305)      char    *reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306)      int     err_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) static struct error_bios flash_error_table[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311)      {"Failed to open bios image file",      FAIL_OPEN_BIOS_FILE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312)      {"PCI ID mismatch",                     FAIL_CHECK_PCI_ID},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313)      {"Checksum mismatch",                   FAIL_CHECK_SUM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314)      {"Unknown Error",                       FAIL_UNKNOWN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315)      {"Failed to verify.",                   FAIL_VERIFY},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316)      {"Failed to reset flash chip.",         FAIL_RESET_FLASH},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)      {"Failed to find flash chip type.",     FAIL_FIND_FLASH_ID},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318)      {"Failed to erash flash chip.",         FAIL_ERASE_FLASH},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319)      {"Failed to program flash chip.",       FAIL_WRITE_FLASH},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320)      {"Flash in progress",                   FLASH_IN_PROGRESS},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321)      {"Image file size Error",               FAIL_FILE_SIZE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322)      {"Input parameter error",               FAIL_PARAMETERS},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323)      {"Out of memory",                       FAIL_OUT_MEMORY},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324)      {"OK", 0}	/* Last entry err_code = 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) static ssize_t asd_store_update_bios(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	char *cmd_ptr, *filename_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	struct bios_file_header header, *hdr_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	int res, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	u32 csum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	int flash_command = FLASH_CMD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	cmd_ptr = kcalloc(count, 2, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	if (!cmd_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		err = FAIL_OUT_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	filename_ptr = cmd_ptr + count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	res = sscanf(buf, "%s %s", cmd_ptr, filename_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	if (res != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		err = FAIL_PARAMETERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		goto out1;
^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) 	for (i = 0; flash_command_table[i].code != FLASH_CMD_NONE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		if (!memcmp(flash_command_table[i].command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 				 cmd_ptr, strlen(cmd_ptr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 			flash_command = flash_command_table[i].code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	if (flash_command == FLASH_CMD_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		err = FAIL_PARAMETERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	if (asd_ha->bios_status == FLASH_IN_PROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		err = FLASH_IN_PROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	err = request_firmware(&asd_ha->bios_image,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 				   filename_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 				   &asd_ha->pcidev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 		asd_printk("Failed to load bios image file %s, error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 			   filename_ptr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		err = FAIL_OPEN_BIOS_FILE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	hdr_ptr = (struct bios_file_header *)asd_ha->bios_image->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	if ((hdr_ptr->contrl_id.vendor != asd_ha->pcidev->vendor ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		hdr_ptr->contrl_id.device != asd_ha->pcidev->device) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		(hdr_ptr->contrl_id.sub_vendor != asd_ha->pcidev->vendor ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 		hdr_ptr->contrl_id.sub_device != asd_ha->pcidev->device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		ASD_DPRINTK("The PCI vendor or device id does not match\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		ASD_DPRINTK("vendor=%x dev=%x sub_vendor=%x sub_dev=%x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		" pci vendor=%x pci dev=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		hdr_ptr->contrl_id.vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		hdr_ptr->contrl_id.device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		hdr_ptr->contrl_id.sub_vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		hdr_ptr->contrl_id.sub_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		asd_ha->pcidev->vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		asd_ha->pcidev->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		err = FAIL_CHECK_PCI_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	if (hdr_ptr->filelen != asd_ha->bios_image->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		err = FAIL_FILE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		goto out2;
^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) 	/* calculate checksum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	for (i = 0; i < hdr_ptr->filelen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		csum += asd_ha->bios_image->data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	if ((csum & 0x0000ffff) != hdr_ptr->checksum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		ASD_DPRINTK("BIOS file checksum mismatch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		err = FAIL_CHECK_SUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	if (flash_command == FLASH_CMD_UPDATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		asd_ha->bios_status = FLASH_IN_PROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		err = asd_write_flash_seg(asd_ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 			&asd_ha->bios_image->data[sizeof(*hdr_ptr)],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 			0, hdr_ptr->filelen-sizeof(*hdr_ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 			err = asd_verify_flash_seg(asd_ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 				&asd_ha->bios_image->data[sizeof(*hdr_ptr)],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 				0, hdr_ptr->filelen-sizeof(*hdr_ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		asd_ha->bios_status = FLASH_IN_PROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		err = asd_verify_flash_seg(asd_ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 			&asd_ha->bios_image->data[sizeof(header)],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			0, hdr_ptr->filelen-sizeof(header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	release_firmware(asd_ha->bios_image);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	kfree(cmd_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	asd_ha->bios_status = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		return -err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) static ssize_t asd_show_update_bios(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 				    struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	for (i = 0; flash_error_table[i].err_code != 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		if (flash_error_table[i].err_code == asd_ha->bios_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	if (asd_ha->bios_status != FLASH_IN_PROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		asd_ha->bios_status = FLASH_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	return snprintf(buf, PAGE_SIZE, "status=%x %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			flash_error_table[i].err_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 			flash_error_table[i].reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) static DEVICE_ATTR(update_bios, S_IRUGO|S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	asd_show_update_bios, asd_store_update_bios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) static int asd_create_dev_attrs(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_aic_revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_bios_build);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		goto err_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_pcba_sn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		goto err_biosb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_update_bios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		goto err_update_bios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) err_update_bios:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	device_remove_file(&asd_ha->pcidev->dev, &dev_attr_pcba_sn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) err_biosb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	device_remove_file(&asd_ha->pcidev->dev, &dev_attr_bios_build);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) err_rev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	device_remove_file(&asd_ha->pcidev->dev, &dev_attr_aic_revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) static void asd_remove_dev_attrs(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	device_remove_file(&asd_ha->pcidev->dev, &dev_attr_aic_revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	device_remove_file(&asd_ha->pcidev->dev, &dev_attr_bios_build);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	device_remove_file(&asd_ha->pcidev->dev, &dev_attr_pcba_sn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	device_remove_file(&asd_ha->pcidev->dev, &dev_attr_update_bios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) /* The first entry, 0, is used for dynamic ids, the rest for devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502)  * we know about.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) static const struct asd_pcidev_struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	const char * name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	int (*setup)(struct asd_ha_struct *asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) } asd_pcidev_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	/* Id 0 is used for dynamic ids. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	{ .name  = "Adaptec AIC-94xx SAS/SATA Host Adapter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	  .setup = asd_aic9410_setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	{ .name  = "Adaptec AIC-9410W SAS/SATA Host Adapter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	  .setup = asd_aic9410_setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	{ .name  = "Adaptec AIC-9405W SAS/SATA Host Adapter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	  .setup = asd_aic9405_setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) static int asd_create_ha_caches(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	asd_ha->scb_pool = dma_pool_create(ASD_DRIVER_NAME "_scb_pool",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 					   &asd_ha->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 					   sizeof(struct scb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 					   8, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	if (!asd_ha->scb_pool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		asd_printk("couldn't create scb pool\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535)  * asd_free_edbs -- free empty data buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536)  * asd_ha: pointer to host adapter structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) static void asd_free_edbs(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	struct asd_seq_data *seq = &asd_ha->seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	for (i = 0; i < seq->num_edbs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		asd_free_coherent(asd_ha, seq->edb_arr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	kfree(seq->edb_arr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	seq->edb_arr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) static void asd_free_escbs(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	struct asd_seq_data *seq = &asd_ha->seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	for (i = 0; i < seq->num_escbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		if (!list_empty(&seq->escb_arr[i]->list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 			list_del_init(&seq->escb_arr[i]->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		asd_ascb_free(seq->escb_arr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	kfree(seq->escb_arr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	seq->escb_arr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) static void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	if (asd_ha->hw_prof.ddb_ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		asd_free_coherent(asd_ha, asd_ha->hw_prof.ddb_ext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	if (asd_ha->hw_prof.scb_ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		asd_free_coherent(asd_ha, asd_ha->hw_prof.scb_ext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	kfree(asd_ha->hw_prof.ddb_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	asd_ha->hw_prof.ddb_bitmap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	for (i = 0; i < ASD_MAX_PHYS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		struct asd_phy *phy = &asd_ha->phys[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		asd_free_coherent(asd_ha, phy->id_frm_tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	if (asd_ha->seq.escb_arr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		asd_free_escbs(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	if (asd_ha->seq.edb_arr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		asd_free_edbs(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	if (asd_ha->hw_prof.ue.area) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		kfree(asd_ha->hw_prof.ue.area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		asd_ha->hw_prof.ue.area = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	if (asd_ha->seq.tc_index_array) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		kfree(asd_ha->seq.tc_index_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		kfree(asd_ha->seq.tc_index_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		asd_ha->seq.tc_index_array = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		asd_ha->seq.tc_index_bitmap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	if (asd_ha->seq.actual_dl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 			asd_free_coherent(asd_ha, asd_ha->seq.actual_dl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 			asd_ha->seq.actual_dl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 			asd_ha->seq.dl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	if (asd_ha->seq.next_scb.vaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		dma_pool_free(asd_ha->scb_pool, asd_ha->seq.next_scb.vaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 			      asd_ha->seq.next_scb.dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		asd_ha->seq.next_scb.vaddr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	dma_pool_destroy(asd_ha->scb_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	asd_ha->scb_pool = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) struct kmem_cache *asd_dma_token_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) struct kmem_cache *asd_ascb_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) static int asd_create_global_caches(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	if (!asd_dma_token_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		asd_dma_token_cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 			= kmem_cache_create(ASD_DRIVER_NAME "_dma_token",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 					    sizeof(struct asd_dma_tok),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 					    0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 					    SLAB_HWCACHE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 					    NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		if (!asd_dma_token_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 			asd_printk("couldn't create dma token cache\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 			return -ENOMEM;
^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) 	if (!asd_ascb_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		asd_ascb_cache = kmem_cache_create(ASD_DRIVER_NAME "_ascb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 						   sizeof(struct asd_ascb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 						   0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 						   SLAB_HWCACHE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 						   NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		if (!asd_ascb_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 			asd_printk("couldn't create ascb cache\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 			goto Err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) Err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	kmem_cache_destroy(asd_dma_token_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	asd_dma_token_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) static void asd_destroy_global_caches(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	kmem_cache_destroy(asd_dma_token_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	asd_dma_token_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	kmem_cache_destroy(asd_ascb_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	asd_ascb_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) static int asd_register_sas_ha(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	struct asd_sas_phy   **sas_phys =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		kcalloc(ASD_MAX_PHYS, sizeof(*sas_phys), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	struct asd_sas_port  **sas_ports =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		kcalloc(ASD_MAX_PHYS, sizeof(*sas_ports), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	if (!sas_phys || !sas_ports) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		kfree(sas_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		kfree(sas_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	asd_ha->sas_ha.sas_ha_name = (char *) asd_ha->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	asd_ha->sas_ha.lldd_module = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	asd_ha->sas_ha.sas_addr = &asd_ha->hw_prof.sas_addr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	for (i = 0; i < ASD_MAX_PHYS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		sas_phys[i] = &asd_ha->phys[i].sas_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		sas_ports[i] = &asd_ha->ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	asd_ha->sas_ha.sas_phy = sas_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	asd_ha->sas_ha.sas_port= sas_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	asd_ha->sas_ha.num_phys= ASD_MAX_PHYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	return sas_register_ha(&asd_ha->sas_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) static int asd_unregister_sas_ha(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	err = sas_unregister_ha(&asd_ha->sas_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	sas_remove_host(asd_ha->sas_ha.core.shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	scsi_host_put(asd_ha->sas_ha.core.shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	kfree(asd_ha->sas_ha.sas_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	kfree(asd_ha->sas_ha.sas_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) static int asd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	const struct asd_pcidev_struct *asd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	unsigned asd_id = (unsigned) id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	struct asd_ha_struct *asd_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	if (asd_id >= ARRAY_SIZE(asd_pcidev_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		asd_printk("wrong driver_data in PCI table\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	if ((err = pci_enable_device(dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		asd_printk("couldn't enable device %s\n", pci_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	pci_set_master(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	shost = scsi_host_alloc(&aic94xx_sht, sizeof(void *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	if (!shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		goto Err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	asd_dev = &asd_pcidev_data[asd_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	asd_ha = kzalloc(sizeof(*asd_ha), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	if (!asd_ha) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		asd_printk("out of memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		goto Err_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	asd_ha->pcidev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	asd_ha->sas_ha.dev = &asd_ha->pcidev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	asd_ha->sas_ha.lldd_ha = asd_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	asd_ha->bios_status = FLASH_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	asd_ha->name = asd_dev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	asd_printk("found %s, device %s\n", asd_ha->name, pci_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	SHOST_TO_SAS_HA(shost) = &asd_ha->sas_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	asd_ha->sas_ha.core.shost = shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	shost->transportt = aic94xx_transport_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	shost->max_id = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	shost->max_lun = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	shost->max_cmd_len = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	err = scsi_add_host(shost, &dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		goto Err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	err = asd_dev->setup(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		goto Err_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	err = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		err = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		asd_printk("no suitable DMA mask for %s\n", pci_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		goto Err_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	pci_set_drvdata(dev, asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	err = asd_map_ha(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		goto Err_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	err = asd_create_ha_caches(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772)         if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		goto Err_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	err = asd_init_hw(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		goto Err_free_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	asd_printk("device %s: SAS addr %llx, PCBA SN %s, %d phys, %d enabled "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		   "phys, flash %s, BIOS %s%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		   pci_name(dev), SAS_ADDR(asd_ha->hw_prof.sas_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		   asd_ha->hw_prof.pcba_sn, asd_ha->hw_prof.max_phys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		   asd_ha->hw_prof.num_phys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		   asd_ha->hw_prof.flash.present ? "present" : "not present",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		   asd_ha->hw_prof.bios.present ? "build " : "not present",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		   asd_ha->hw_prof.bios.bld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	shost->can_queue = asd_ha->seq.can_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	if (use_msi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		pci_enable_msi(asd_ha->pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	err = request_irq(asd_ha->pcidev->irq, asd_hw_isr, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			  ASD_DRIVER_NAME, asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		asd_printk("couldn't get irq %d for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 			   asd_ha->pcidev->irq, pci_name(asd_ha->pcidev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		goto Err_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	asd_enable_ints(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	err = asd_init_post_escbs(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		asd_printk("couldn't post escbs for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 			   pci_name(asd_ha->pcidev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		goto Err_escbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	ASD_DPRINTK("escbs posted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	err = asd_create_dev_attrs(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		goto Err_dev_attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	err = asd_register_sas_ha(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		goto Err_reg_sas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	scsi_scan_host(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) Err_reg_sas:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	asd_remove_dev_attrs(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) Err_dev_attrs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) Err_escbs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	asd_disable_ints(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	free_irq(dev->irq, asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) Err_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	if (use_msi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		pci_disable_msi(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	asd_chip_hardrst(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) Err_free_cache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	asd_destroy_ha_caches(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) Err_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	asd_unmap_ha(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) Err_remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	scsi_remove_host(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) Err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	kfree(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) Err_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	scsi_host_put(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) Err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	pci_disable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) static void asd_free_queues(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	LIST_HEAD(pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	struct list_head *n, *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	asd_ha->seq.pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	list_splice_init(&asd_ha->seq.pend_q, &pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	if (!list_empty(&pending))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		ASD_DPRINTK("Uh-oh! Pending is not empty!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	list_for_each_safe(pos, n, &pending) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		struct asd_ascb *ascb = list_entry(pos, struct asd_ascb, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		 * Delete unexpired ascb timers.  This may happen if we issue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		 * a CONTROL PHY scb to an adapter and rmmod before the scb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		 * times out.  Apparently we don't wait for the CONTROL PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		 * to complete, so it doesn't matter if we kill the timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		del_timer_sync(&ascb->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		WARN_ON(ascb->scb->header.opcode != CONTROL_PHY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		list_del_init(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		ASD_DPRINTK("freeing from pending\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		asd_ascb_free(ascb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) static void asd_turn_off_leds(struct asd_ha_struct *asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	u8 phy_mask = asd_ha->hw_prof.enabled_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	for_each_phy(phy_mask, phy_mask, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		asd_turn_led(asd_ha, i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		asd_control_led(asd_ha, i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) static void asd_pci_remove(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	struct asd_ha_struct *asd_ha = pci_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	if (!asd_ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	asd_unregister_sas_ha(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	asd_disable_ints(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	asd_remove_dev_attrs(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	/* XXX more here as needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	free_irq(dev->irq, asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	if (use_msi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		pci_disable_msi(asd_ha->pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	asd_turn_off_leds(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	asd_chip_hardrst(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	asd_free_queues(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	asd_destroy_ha_caches(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	asd_unmap_ha(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	kfree(asd_ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	pci_disable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) static void asd_scan_start(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	struct asd_ha_struct *asd_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	asd_ha = SHOST_TO_SAS_HA(shost)->lldd_ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	err = asd_enable_phys(asd_ha, asd_ha->hw_prof.enabled_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		asd_printk("Couldn't enable phys, err:%d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) static int asd_scan_finished(struct Scsi_Host *shost, unsigned long time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	/* give the phy enabling interrupt event time to come in (1s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	 * is empirically about all it takes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	if (time < HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	/* Wait for discovery to finish */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	sas_drain_work(SHOST_TO_SAS_HA(shost));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) static ssize_t version_show(struct device_driver *driver, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	return snprintf(buf, PAGE_SIZE, "%s\n", ASD_DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) static DRIVER_ATTR_RO(version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) static int asd_create_driver_attrs(struct device_driver *driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	return driver_create_file(driver, &driver_attr_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) static void asd_remove_driver_attrs(struct device_driver *driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	driver_remove_file(driver, &driver_attr_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) static struct sas_domain_function_template aic94xx_transport_functions = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	.lldd_dev_found		= asd_dev_found,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	.lldd_dev_gone		= asd_dev_gone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	.lldd_execute_task	= asd_execute_task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	.lldd_abort_task	= asd_abort_task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	.lldd_abort_task_set	= asd_abort_task_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	.lldd_clear_aca		= asd_clear_aca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	.lldd_clear_task_set	= asd_clear_task_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	.lldd_I_T_nexus_reset	= asd_I_T_nexus_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	.lldd_lu_reset		= asd_lu_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	.lldd_query_task	= asd_query_task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	.lldd_clear_nexus_port	= asd_clear_nexus_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	.lldd_clear_nexus_ha	= asd_clear_nexus_ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	.lldd_control_phy	= asd_control_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	.lldd_ata_set_dmamode	= asd_set_dmamode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) static const struct pci_device_id aic94xx_pci_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x410),0, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x412),0, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x416),0, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x41E),0, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x41F),0, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x430),0, 0, 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x432),0, 0, 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x43E),0, 0, 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x43F),0, 0, 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) MODULE_DEVICE_TABLE(pci, aic94xx_pci_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) static struct pci_driver aic94xx_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	.name		= ASD_DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	.id_table	= aic94xx_pci_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	.probe		= asd_pci_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	.remove		= asd_pci_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) static int __init aic94xx_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	int err;
^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) 	asd_printk("%s version %s loaded\n", ASD_DRIVER_DESCRIPTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		   ASD_DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	err = asd_create_global_caches();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	aic94xx_transport_template =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		sas_domain_attach_transport(&aic94xx_transport_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	if (!aic94xx_transport_template) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		goto out_destroy_caches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	err = pci_register_driver(&aic94xx_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		goto out_release_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	err = asd_create_driver_attrs(&aic94xx_pci_driver.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		goto out_unregister_pcidrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)  out_unregister_pcidrv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	pci_unregister_driver(&aic94xx_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)  out_release_transport:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	sas_release_transport(aic94xx_transport_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)  out_destroy_caches:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	asd_destroy_global_caches();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) static void __exit aic94xx_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	asd_remove_driver_attrs(&aic94xx_pci_driver.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	pci_unregister_driver(&aic94xx_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	sas_release_transport(aic94xx_transport_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	asd_release_firmware();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	asd_destroy_global_caches();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	asd_printk("%s version %s unloaded\n", ASD_DRIVER_DESCRIPTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		   ASD_DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) module_init(aic94xx_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) module_exit(aic94xx_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) MODULE_AUTHOR("Luben Tuikov <luben_tuikov@adaptec.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) MODULE_DESCRIPTION(ASD_DRIVER_DESCRIPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) MODULE_VERSION(ASD_DRIVER_VERSION);