Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d67e9111 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
  [SCSI] a100u2w: fix bitmap lookup routine
  [SCSI] fix media change events for polled devices
  [SCSI] sd, sr: do not emit change event at device add
  [SCSI] mpt fusion: Power Management fixes for MPT SAS PCI-E controllers
  [SCSI] gdth: Allocate sense_buffer to prevent NULL pointer dereference
  [SCSI] arcmsr: fix iounmap error for Type B adapter
  [SCSI] isd200: Allocate sense_buffer for hacked up scsi_cmnd
  [SCSI] fix bsg queue oops with iscsi logout
  [SCSI] Fix dependency problems in SCSI drivers
  [SCSI] advansys: Fix bug in AdvLoadMicrocode
parents 00c04db9 28aef2f7
Loading
Loading
Loading
Loading
+156 −120
Original line number Diff line number Diff line
@@ -1430,6 +1430,98 @@ mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
		sprintf(prod_name, "%s", product_str);
}

/**
 *	mpt_mapresources - map in memory mapped io
 *	@ioc: Pointer to pointer to IOC adapter
 *
 **/
static int
mpt_mapresources(MPT_ADAPTER *ioc)
{
	u8		__iomem *mem;
	int		 ii;
	unsigned long	 mem_phys;
	unsigned long	 port;
	u32		 msize;
	u32		 psize;
	u8		 revision;
	int		 r = -ENODEV;
	struct pci_dev *pdev;

	pdev = ioc->pcidev;
	ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
	if (pci_enable_device_mem(pdev)) {
		printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
		    "failed\n", ioc->name);
		return r;
	}
	if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
		printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
		    "MEM failed\n", ioc->name);
		return r;
	}

	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);

	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
	    && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
		dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
		    ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
		    ioc->name));
	} else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
	    && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
		dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
		    ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
		    ioc->name));
	} else {
		printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
		    ioc->name, pci_name(pdev));
		pci_release_selected_regions(pdev, ioc->bars);
		return r;
	}

	mem_phys = msize = 0;
	port = psize = 0;
	for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
		if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
			if (psize)
				continue;
			/* Get I/O space! */
			port = pci_resource_start(pdev, ii);
			psize = pci_resource_len(pdev, ii);
		} else {
			if (msize)
				continue;
			/* Get memmap */
			mem_phys = pci_resource_start(pdev, ii);
			msize = pci_resource_len(pdev, ii);
		}
	}
	ioc->mem_size = msize;

	mem = NULL;
	/* Get logical ptr for PciMem0 space */
	/*mem = ioremap(mem_phys, msize);*/
	mem = ioremap(mem_phys, msize);
	if (mem == NULL) {
		printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
			" memory!\n", ioc->name);
		return -EINVAL;
	}
	ioc->memmap = mem;
	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
	    ioc->name, mem, mem_phys));

	ioc->mem_phys = mem_phys;
	ioc->chip = (SYSIF_REGS __iomem *)mem;

	/* Save Port IO values in case we need to do downloadboot */
	ioc->pio_mem_phys = port;
	ioc->pio_chip = (SYSIF_REGS __iomem *)port;

	return 0;
}

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
 *	mpt_attach - Install a PCI intelligent MPT adapter.
@@ -1452,13 +1544,6 @@ int
mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
{
	MPT_ADAPTER	*ioc;
	u8		__iomem *mem;
	u8		__iomem *pmem;
	unsigned long	 mem_phys;
	unsigned long	 port;
	u32		 msize;
	u32		 psize;
	int		 ii;
	u8		 cb_idx;
	int		 r = -ENODEV;
	u8		 revision;
@@ -1468,52 +1553,32 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
	struct proc_dir_entry *dent, *ent;
#endif

	if (mpt_debug_level)
		printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);

	ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
	if (ioc == NULL) {
		printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
		return -ENOMEM;
	}
	ioc->debug_level = mpt_debug_level;

	ioc->id = mpt_ids++;
	sprintf(ioc->name, "ioc%d", ioc->id);

	ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
	if (pci_enable_device_mem(pdev)) {
		printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
		       "failed\n", ioc->name);
		kfree(ioc);
		return r;
	}
	if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
		printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
		       "MEM failed\n", ioc->name);
		kfree(ioc);
		return r;
	}
	/*
	 * set initial debug level
	 * (refer to mptdebug.h)
	 *
	 */
	ioc->debug_level = mpt_debug_level;
	if (mpt_debug_level)
		printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);

	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));

	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
		dprintk(ioc, printk(MYIOC_s_INFO_FMT
			": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", ioc->name));
	} else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
		printk(MYIOC_s_WARN_FMT ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n",
		    ioc->name);
	ioc->pcidev = pdev;
	if (mpt_mapresources(ioc)) {
		kfree(ioc);
		return r;
	}

	if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
		dprintk(ioc, printk(MYIOC_s_INFO_FMT
			": Using 64 bit consistent mask\n", ioc->name));
	} else {
		dprintk(ioc, printk(MYIOC_s_INFO_FMT
			": Not using 64 bit consistent mask\n", ioc->name));
	}

	ioc->alloc_total = sizeof(MPT_ADAPTER);
	ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;		/* avoid div by zero! */
	ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
@@ -1551,48 +1616,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
	/* Find lookup slot. */
	INIT_LIST_HEAD(&ioc->list);

	mem_phys = msize = 0;
	port = psize = 0;
	for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
		if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
			if (psize)
				continue;
			/* Get I/O space! */
			port = pci_resource_start(pdev, ii);
			psize = pci_resource_len(pdev,ii);
		} else {
			if (msize)
				continue;
			/* Get memmap */
			mem_phys = pci_resource_start(pdev, ii);
			msize = pci_resource_len(pdev,ii);
		}
	}
	ioc->mem_size = msize;

	mem = NULL;
	/* Get logical ptr for PciMem0 space */
	/*mem = ioremap(mem_phys, msize);*/
	mem = ioremap(mem_phys, msize);
	if (mem == NULL) {
		printk(MYIOC_s_ERR_FMT "Unable to map adapter memory!\n", ioc->name);
		kfree(ioc);
		return -EINVAL;
	}
	ioc->memmap = mem;
	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", ioc->name, mem, mem_phys));

	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
	    ioc->name, &ioc->facts, &ioc->pfacts[0]));

	ioc->mem_phys = mem_phys;
	ioc->chip = (SYSIF_REGS __iomem *)mem;

	/* Save Port IO values in case we need to do downloadboot */
	ioc->pio_mem_phys = port;
	pmem = (u8 __iomem *)port;
	ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;

	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
	mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);

@@ -1688,7 +1714,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
		list_del(&ioc->list);
		if (ioc->alt_ioc)
			ioc->alt_ioc->alt_ioc = NULL;
		iounmap(mem);
		iounmap(ioc->memmap);
		if (r != -5)
			pci_release_selected_regions(pdev, ioc->bars);
		kfree(ioc);
		pci_set_drvdata(pdev, NULL);
		return r;
@@ -1785,12 +1813,9 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);

	device_state = pci_choose_state(pdev, state);

	printk(MYIOC_s_INFO_FMT
	"pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
		ioc->name, pdev, pci_name(pdev), device_state);

	pci_save_state(pdev);
	printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
	    "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
	    device_state);

	/* put ioc into READY_STATE */
	if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
@@ -1805,10 +1830,14 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
	/* Clear any lingering interrupt */
	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);

	free_irq(ioc->pci_irq, ioc);
	if (mpt_msi_enable)
		pci_disable_msi(ioc->pcidev);
	ioc->pci_irq = -1;
	pci_save_state(pdev);
	pci_disable_device(pdev);
	pci_release_selected_regions(pdev, ioc->bars);
	pci_set_power_state(pdev, device_state);

	return 0;
}

@@ -1823,48 +1852,54 @@ mpt_resume(struct pci_dev *pdev)
	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
	u32 device_state = pdev->current_state;
	int recovery_state;
	int err;

	printk(MYIOC_s_INFO_FMT
	"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
		ioc->name, pdev, pci_name(pdev), device_state);
	printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
	    "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
	    device_state);

	pci_set_power_state(pdev, 0);
	pci_set_power_state(pdev, PCI_D0);
	pci_enable_wake(pdev, PCI_D0, 0);
	pci_restore_state(pdev);
	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) {
		ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
			IORESOURCE_IO);
		if (pci_enable_device(pdev))
			return 0;
	} else {
		ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
		if (pci_enable_device_mem(pdev))
			return 0;
	}
	if (pci_request_selected_regions(pdev, ioc->bars, "mpt"))
		return 0;

	/* enable interrupts */
	CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
	ioc->active = 1;
	ioc->pcidev = pdev;
	err = mpt_mapresources(ioc);
	if (err)
		return err;

	printk(MYIOC_s_INFO_FMT
		"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
		ioc->name,
		(mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
	printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
	    ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
	    CHIPREG_READ32(&ioc->chip->Doorbell));

	/*
	 * Errata workaround for SAS pci express:
	 * Upon returning to the D0 state, the contents of the doorbell will be
	 * stale data, and this will incorrectly signal to the host driver that
	 * the firmware is ready to process mpt commands.   The workaround is
	 * to issue a diagnostic reset.
	 */
	if (ioc->bus_type == SAS && (pdev->device ==
	    MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
	    MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
		if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
			printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
			    ioc->name);
			goto out;
		}
	}

	/* bring ioc to operational state */
	if ((recovery_state = mpt_do_ioc_recovery(ioc,
	    MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
		printk(MYIOC_s_INFO_FMT
			"pci-resume: Cannot recover, error:[%x]\n",
			ioc->name, recovery_state);
	} else {
	printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
	recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
						 CAN_SLEEP);
	if (recovery_state != 0)
		printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
		    "error:[%x]\n", ioc->name, recovery_state);
	else
		printk(MYIOC_s_INFO_FMT
		    "pci-resume: success\n", ioc->name);
	}

 out:
	return 0;

}
#endif

@@ -1903,6 +1938,7 @@ mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
 *		-3 if READY but PrimeIOCFifos Failed
 *		-4 if READY but IOCInit Failed
 *		-5 if failed to enable_device and/or request_selected_regions
 *		-6 if failed to upload firmware
 */
static int
mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
@@ -2097,7 +2133,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
				} else {
					printk(MYIOC_s_WARN_FMT
					    "firmware upload failure!\n", ioc->name);
					ret = -5;
					ret = -6;
				}
			}
		}
+10 −1
Original line number Diff line number Diff line
@@ -1170,6 +1170,10 @@ mptscsih_shutdown(struct pci_dev *pdev)
int
mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
{
	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);

	scsi_block_requests(ioc->sh);
	flush_scheduled_work();
	mptscsih_shutdown(pdev);
	return mpt_suspend(pdev,state);
}
@@ -1183,7 +1187,12 @@ mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
int
mptscsih_resume(struct pci_dev *pdev)
{
	return mpt_resume(pdev);
	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
	int rc;

	rc = mpt_resume(pdev);
	scsi_unblock_requests(ioc->sh);
	return rc;
}

#endif
+1 −1
Original line number Diff line number Diff line
@@ -325,7 +325,7 @@ menuconfig SCSI_LOWLEVEL
	depends on SCSI!=n
	default y

if SCSI_LOWLEVEL
if SCSI_LOWLEVEL && SCSI

config ISCSI_TCP
	tristate "iSCSI Initiator over TCP/IP"
+5 −4
Original line number Diff line number Diff line
@@ -674,12 +674,13 @@ static struct orc_scb *__orc_alloc_scb(struct orc_host * host)
		for (index = 0; index < 32; index++) {
			if ((host->allocation_map[channel][i] >> index) & 0x01) {
				host->allocation_map[channel][i] &= ~(1 << index);
				break;
				idx = index + 32 * i;
				/*
				 * Translate the index to a structure instance
				 */
				return host->scb_virt + idx;
			}
		}
		idx = index + 32 * i;
		/* Translate the index to a structure instance */
		return (struct orc_scb *) ((unsigned long) host->scb_virt + (idx * sizeof(struct orc_scb)));
	}
	return NULL;
}
+1 −1
Original line number Diff line number Diff line
@@ -6439,7 +6439,7 @@ static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
			i += 2;
			len += 2;
		} else {
			unsigned char off = buf[i] * 2;
			unsigned int off = buf[i] * 2;
			unsigned short word = (buf[off + 1] << 8) | buf[off];
			AdvWriteWordAutoIncLram(iop_base, word);
			len += 2;
Loading