diff options
Diffstat (limited to 'drivers/scsi')
47 files changed, 2921 insertions, 1080 deletions
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 6b49f6a2524..efd9d8d3a89 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -4,7 +4,7 @@ Written By: Adam Radford <linuxraid@amcc.com> Modifications By: Tom Couch <linuxraid@amcc.com> - Copyright (C) 2004-2006 Applied Micro Circuits Corporation. + Copyright (C) 2004-2007 Applied Micro Circuits Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -69,6 +69,8 @@ 2.26.02.008 - Free irq handler in __twa_shutdown(). Serialize reset code. Add support for 9650SE controllers. + 2.26.02.009 - Fix dma mask setting to fallback to 32-bit if 64-bit fails. + 2.26.02.010 - Add support for 9690SA controllers. */ #include <linux/module.h> @@ -92,7 +94,7 @@ #include "3w-9xxx.h" /* Globals */ -#define TW_DRIVER_VERSION "2.26.02.008" +#define TW_DRIVER_VERSION "2.26.02.010" static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static unsigned int twa_device_extension_count; static int twa_major = -1; @@ -124,11 +126,11 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits, unsigned short *fw_on_ctlr_branch, unsigned short *fw_on_ctlr_build, u32 *init_connect_result); -static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length); +static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length); static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds); static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds); static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal); -static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset); +static int twa_reset_device_extension(TW_Device_Extension *tw_dev); static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset); static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg); static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id); @@ -683,7 +685,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int full_command_packet = &tw_ioctl->firmware_command; /* Load request id and sglist for both command types */ - twa_load_sgl(full_command_packet, request_id, dma_handle, data_buffer_length_adjusted); + twa_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted); memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full)); @@ -700,10 +702,10 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { /* Now we need to reset the board */ printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n", - tw_dev->host->host_no, TW_DRIVER, 0xc, + tw_dev->host->host_no, TW_DRIVER, 0x37, cmd); retval = TW_IOCTL_ERROR_OS_EIO; - twa_reset_device_extension(tw_dev, 1); + twa_reset_device_extension(tw_dev); goto out3; } @@ -890,7 +892,9 @@ static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value) } if (status_reg_value & TW_STATUS_QUEUE_ERROR) { - if ((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev->flags))) + if (((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) && + (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9690SA)) || + (!test_bit(TW_IN_RESET, &tw_dev->flags))) TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); } @@ -935,8 +939,7 @@ static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev) unsigned long before; int retval = 1; - if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) || - (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) { + if (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9000) { before = jiffies; while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) { response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); @@ -1195,7 +1198,6 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) u32 status_reg_value; TW_Response_Queue response_que; TW_Command_Full *full_command_packet; - TW_Command *command_packet; TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance; int handled = 0; @@ -1273,7 +1275,6 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) request_id = TW_RESID_OUT(response_que.response_id); full_command_packet = tw_dev->command_packet_virt[request_id]; error = 0; - command_packet = &full_command_packet->command.oldcommand; /* Check for command packet errors */ if (full_command_packet->command.newcommand.status != 0) { if (tw_dev->srb[request_id] != 0) { @@ -1352,11 +1353,15 @@ twa_interrupt_bail: } /* End twa_interrupt() */ /* This function will load the request id and various sgls for ioctls */ -static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length) +static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length) { TW_Command *oldcommand; TW_Command_Apache *newcommand; TW_SG_Entry *sgl; + unsigned int pae = 0; + + if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4)) + pae = 1; if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { newcommand = &full_command_packet->command.newcommand; @@ -1372,12 +1377,14 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) { /* Load the sg list */ - sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset)); + if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA) + sgl = (TW_SG_Entry *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry)/4) + pae); + else + sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset)); sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); sgl->length = cpu_to_le32(length); - if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4)) - oldcommand->size += 1; + oldcommand->size += pae; } } } /* End twa_load_sgl() */ @@ -1506,7 +1513,8 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, command_que_value = tw_dev->command_packet_phys[request_id]; /* For 9650SE write low 4 bytes first */ - if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { + if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) || + (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) { command_que_value += TW_COMMAND_OFFSET; writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev)); } @@ -1537,7 +1545,8 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, TW_UNMASK_COMMAND_INTERRUPT(tw_dev); goto out; } else { - if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { + if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) || + (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) { /* Now write upper 4 bytes */ writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4); } else { @@ -1561,7 +1570,7 @@ out: } /* End twa_post_command_packet() */ /* This function will reset a device extension */ -static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset) +static int twa_reset_device_extension(TW_Device_Extension *tw_dev) { int i = 0; int retval = 1; @@ -1719,7 +1728,7 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt) mutex_lock(&tw_dev->ioctl_lock); /* Now reset the card and some of the device extension data */ - if (twa_reset_device_extension(tw_dev, 0)) { + if (twa_reset_device_extension(tw_dev)) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset"); goto out; } @@ -2001,11 +2010,14 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id pci_set_master(pdev); - retval = pci_set_dma_mask(pdev, sizeof(dma_addr_t) > 4 ? DMA_64BIT_MASK : DMA_32BIT_MASK); - if (retval) { - TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask"); - goto out_disable_device; - } + if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) + || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) + || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { + TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask"); + retval = -ENODEV; + goto out_disable_device; + } host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension)); if (!host) { @@ -2053,7 +2065,8 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id goto out_iounmap; /* Set host specific parameters */ - if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE) + if ((pdev->device == PCI_DEVICE_ID_3WARE_9650SE) || + (pdev->device == PCI_DEVICE_ID_3WARE_9690SA)) host->max_id = TW_MAX_UNITS_9650SE; else host->max_id = TW_MAX_UNITS; @@ -2160,6 +2173,8 @@ static struct pci_device_id twa_pci_tbl[] __devinitdata = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9690SA, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { } }; MODULE_DEVICE_TABLE(pci, twa_pci_tbl); diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h index 7901517d451..d14a9479e38 100644 --- a/drivers/scsi/3w-9xxx.h +++ b/drivers/scsi/3w-9xxx.h @@ -4,7 +4,7 @@ Written By: Adam Radford <linuxraid@amcc.com> Modifications By: Tom Couch <linuxraid@amcc.com> - Copyright (C) 2004-2006 Applied Micro Circuits Corporation. + Copyright (C) 2004-2007 Applied Micro Circuits Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -419,6 +419,9 @@ static twa_message_type twa_error_table[] = { #ifndef PCI_DEVICE_ID_3WARE_9650SE #define PCI_DEVICE_ID_3WARE_9650SE 0x1004 #endif +#ifndef PCI_DEVICE_ID_3WARE_9690SA +#define PCI_DEVICE_ID_3WARE_9690SA 0x1005 +#endif /* Bitmask macros to eliminate bitfields */ diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a947257b896..d2b3898b750 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -282,7 +282,7 @@ config SCSI_ISCSI_ATTRS config SCSI_SAS_ATTRS tristate "SAS Transport Attributes" - depends on SCSI + depends on SCSI && BLK_DEV_BSG help If you wish to export transport-specific information about each attached SAS device to sysfs, say Y. @@ -291,8 +291,12 @@ source "drivers/scsi/libsas/Kconfig" endmenu -menu "SCSI low-level drivers" +menuconfig SCSI_LOWLEVEL + bool "SCSI low-level drivers" depends on SCSI!=n + default y + +if SCSI_LOWLEVEL config ISCSI_TCP tristate "iSCSI Initiator over TCP/IP" @@ -1800,7 +1804,7 @@ config SCSI_SRP To compile this driver as a module, choose M here: the module will be called libsrp. -endmenu +endif # SCSI_LOWLEVEL source "drivers/scsi/pcmcia/Kconfig" diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c index 6a5784683ed..0c758d1452b 100644 --- a/drivers/scsi/a4000t.c +++ b/drivers/scsi/a4000t.c @@ -79,6 +79,7 @@ static int __devinit a4000t_probe(struct device *dev) goto out_put_host; } + dev_set_drvdata(dev, host); scsi_scan_host(host); return 0; @@ -95,7 +96,7 @@ static int __devinit a4000t_probe(struct device *dev) static __devexit int a4000t_device_remove(struct device *dev) { - struct Scsi_Host *host = dev_to_shost(dev); + struct Scsi_Host *host = dev_get_drvdata(dev); struct NCR_700_Host_Parameters *hostdata = shost_priv(host); scsi_remove_host(host); diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 0b6fd0b654d..a26baab09db 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -751,6 +751,101 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex) inqstrcpy ("V1.0", str->prl); } +static void get_container_serial_callback(void *context, struct fib * fibptr) +{ + struct aac_get_serial_resp * get_serial_reply; + struct scsi_cmnd * scsicmd; + + BUG_ON(fibptr == NULL); + + scsicmd = (struct scsi_cmnd *) context; + if (!aac_valid_context(scsicmd, fibptr)) + return; + + get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr); + /* Failure is irrelevant, using default value instead */ + if (le32_to_cpu(get_serial_reply->status) == CT_OK) { + char sp[13]; + /* EVPD bit set */ + sp[0] = INQD_PDT_DA; + sp[1] = scsicmd->cmnd[2]; + sp[2] = 0; + sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", + le32_to_cpu(get_serial_reply->uid)); + aac_internal_transfer(scsicmd, sp, 0, sizeof(sp)); + } + + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; + + aac_fib_complete(fibptr); + aac_fib_free(fibptr); + scsicmd->scsi_done(scsicmd); +} + +/** + * aac_get_container_serial - get container serial, none blocking. + */ +static int aac_get_container_serial(struct scsi_cmnd * scsicmd) +{ + int status; + struct aac_get_serial *dinfo; + struct fib * cmd_fibcontext; + struct aac_dev * dev; + + dev = (struct aac_dev *)scsicmd->device->host->hostdata; + + if (!(cmd_fibcontext = aac_fib_alloc(dev))) + return -ENOMEM; + + aac_fib_init(cmd_fibcontext); + dinfo = (struct aac_get_serial *) fib_data(cmd_fibcontext); + + dinfo->command = cpu_to_le32(VM_ContainerConfig); + dinfo->type = cpu_to_le32(CT_CID_TO_32BITS_UID); + dinfo->cid = cpu_to_le32(scmd_id(scsicmd)); + + status = aac_fib_send(ContainerCommand, + cmd_fibcontext, + sizeof (struct aac_get_serial), + FsaNormal, + 0, 1, + (fib_callback) get_container_serial_callback, + (void *) scsicmd); + + /* + * Check that the command queued to the controller + */ + if (status == -EINPROGRESS) { + scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + return 0; + } + + printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status); + aac_fib_complete(cmd_fibcontext); + aac_fib_free(cmd_fibcontext); + return -1; +} + +/* Function: setinqserial + * + * Arguments: [1] pointer to void [1] int + * + * Purpose: Sets SCSI Unit Serial number. + * This is a fake. We should read a proper + * serial number from the container. <SuSE>But + * without docs it's quite hard to do it :-) + * So this will have to do in the meantime.</SuSE> + */ + +static int setinqserial(struct aac_dev *dev, void *data, int cid) +{ + /* + * This breaks array migration. + */ + return snprintf((char *)(data), sizeof(struct scsi_inq) - 4, "%08X%02X", + le32_to_cpu(dev->adapter_info.serial[0]), cid); +} + static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code, u8 a_sense_code, u8 incorrect_length, u8 bit_pointer, u16 field_pointer, @@ -1798,6 +1893,49 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid)); memset(&inq_data, 0, sizeof (struct inquiry_data)); + if (scsicmd->cmnd[1] & 0x1 ) { + char *arr = (char *)&inq_data; + + /* EVPD bit set */ + arr[0] = (scmd_id(scsicmd) == host->this_id) ? + INQD_PDT_PROC : INQD_PDT_DA; + if (scsicmd->cmnd[2] == 0) { + /* supported vital product data pages */ + arr[3] = 2; + arr[4] = 0x0; + arr[5] = 0x80; + arr[1] = scsicmd->cmnd[2]; + aac_internal_transfer(scsicmd, &inq_data, 0, + sizeof(inq_data)); + scsicmd->result = DID_OK << 16 | + COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; + } else if (scsicmd->cmnd[2] == 0x80) { + /* unit serial number page */ + arr[3] = setinqserial(dev, &arr[4], + scmd_id(scsicmd)); + arr[1] = scsicmd->cmnd[2]; + aac_internal_transfer(scsicmd, &inq_data, 0, + sizeof(inq_data)); + return aac_get_container_serial(scsicmd); + } else { + /* vpd page not implemented */ + scsicmd->result = DID_OK << 16 | + COMMAND_COMPLETE << 8 | + SAM_STAT_CHECK_CONDITION; + set_sense((u8 *) &dev->fsa_dev[cid].sense_data, + ILLEGAL_REQUEST, + SENCODE_INVALID_CDB_FIELD, + ASENCODE_NO_SENSE, 0, 7, 2, 0); + memcpy(scsicmd->sense_buffer, + &dev->fsa_dev[cid].sense_data, + (sizeof(dev->fsa_dev[cid].sense_data) > + sizeof(scsicmd->sense_buffer)) + ? sizeof(scsicmd->sense_buffer) + : sizeof(dev->fsa_dev[cid].sense_data)); + } + scsicmd->scsi_done(scsicmd); + return 0; + } inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */ inq_data.inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */ inq_data.inqd_len = 31; @@ -2070,7 +2208,7 @@ static int query_disk(struct aac_dev *dev, void __user *arg) } else return -EINVAL; - qd.valid = fsa_dev_ptr[qd.cnum].valid; + qd.valid = fsa_dev_ptr[qd.cnum].valid != 0; qd.locked = fsa_dev_ptr[qd.cnum].locked; qd.deleted = fsa_dev_ptr[qd.cnum].deleted; diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index f1d3b66af87..400d03403cd 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1567,6 +1567,20 @@ struct aac_get_name_resp { u8 data[16]; }; +#define CT_CID_TO_32BITS_UID 165 +struct aac_get_serial { + __le32 command; /* VM_ContainerConfig */ + __le32 type; /* CT_CID_TO_32BITS_UID */ + __le32 cid; +}; + +struct aac_get_serial_resp { + __le32 dummy0; + __le32 dummy1; + __le32 status; /* CT_OK */ + __le32 uid; +}; + /* * The following command is sent to shut down each container. */ diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index d510839c0bb..bb870906b4c 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -80,7 +80,11 @@ static int fib_map_alloc(struct aac_dev *dev) void aac_fib_map_free(struct aac_dev *dev) { - pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa); + pci_free_consistent(dev->pdev, + dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), + dev->hw_fib_va, dev->hw_fib_pa); + dev->hw_fib_va = NULL; + dev->hw_fib_pa = 0; } /** @@ -1087,8 +1091,6 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) * case. */ aac_fib_map_free(aac); - aac->hw_fib_va = NULL; - aac->hw_fib_pa = 0; pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); aac->comm_addr = NULL; aac->comm_phys = 0; @@ -1098,12 +1100,12 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) kfree(aac->fsa_dev); aac->fsa_dev = NULL; if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT) { - if (((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) || - ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_32BIT_MASK)))) + if (((retval = pci_set_dma_mask(aac->pdev, DMA_31BIT_MASK))) || + ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_31BIT_MASK)))) goto out; } else { - if (((retval = pci_set_dma_mask(aac->pdev, 0x7FFFFFFFULL))) || - ((retval = pci_set_consistent_dma_mask(aac->pdev, 0x7FFFFFFFULL)))) + if (((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) || + ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_32BIT_MASK)))) goto out; } if ((retval = (*(aac_get_driver_ident(index)->init))(aac))) diff --git a/drivers/scsi/aic94xx/aic94xx_dev.c b/drivers/scsi/aic94xx/aic94xx_dev.c index c520e5b41fb..3dce618bf41 100644 --- a/drivers/scsi/aic94xx/aic94xx_dev.c +++ b/drivers/scsi/aic94xx/aic94xx_dev.c @@ -126,7 +126,7 @@ static inline int asd_init_sata(struct domain_device *dev) if (w76 & 0x100) /* NCQ? */ qdepth = (w75 & 0x1F) + 1; asd_ddbsite_write_dword(asd_ha, ddb, SATA_TAG_ALLOC_MASK, - (1<<qdepth)-1); + (1ULL<<qdepth)-1); asd_ddbsite_write_byte(asd_ha, ddb, NUM_SATA_TAGS, qdepth); } if (dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM || diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index b8c6810090d..ab00aecc546 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -81,6 +81,9 @@ static struct scsi_host_template aic94xx_sht = { .use_clustering = ENABLE_CLUSTERING, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_bus_reset_handler = sas_eh_bus_reset_handler, + .slave_alloc = sas_slave_alloc, + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, }; static int __devinit asd_map_memio(struct asd_ha_struct *asd_ha) diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index e2ad5bed940..d5d8caba356 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c @@ -74,8 +74,13 @@ static inline int asd_map_scatterlist(struct sas_task *task, return 0; } - num_sg = pci_map_sg(asd_ha->pcidev, task->scatter, task->num_scatter, - task->data_dir); + /* STP tasks come from libata which has already mapped + * the SG list */ + if (sas_protocol_ata(task->task_proto)) + num_sg = task->num_scatter; + else + num_sg = pci_map_sg(asd_ha->pcidev, task->scatter, + task->num_scatter, task->data_dir); if (num_sg == 0) return -ENOMEM; @@ -120,8 +125,9 @@ static inline int asd_map_scatterlist(struct sas_task *task, return 0; err_unmap: - pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter, - task->data_dir); + if (sas_protocol_ata(task->task_proto)) + pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter, + task->data_dir); return res; } @@ -142,8 +148,9 @@ static inline void asd_unmap_scatterlist(struct asd_ascb *ascb) } asd_free_coherent(asd_ha, ascb->sg_arr); - pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter, - task->data_dir); + if (task->task_proto != SAS_PROTOCOL_STP) + pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter, + task->data_dir); } /* ---------- Task complete tasklet ---------- */ @@ -391,7 +398,6 @@ static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task, scb->ata_task.total_xfer_len = cpu_to_le32(task->total_xfer_len); scb->ata_task.fis = task->ata_task.fis; - scb->ata_task.fis.fis_type = 0x27; if (likely(!task->ata_task.device_control_reg_update)) scb->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */ scb->ata_task.fis.flags &= 0xF0; /* PM_PORT field shall be 0 */ diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c index 012cdea7946..cac35408673 100644 --- a/drivers/scsi/bvme6000_scsi.c +++ b/drivers/scsi/bvme6000_scsi.c @@ -74,6 +74,7 @@ bvme6000_probe(struct device *dev) goto out_put_host; } + dev_set_drvdata(dev, host); scsi_scan_host(host); return 0; @@ -89,7 +90,7 @@ bvme6000_probe(struct device *dev) static __devexit int bvme6000_device_remove(struct device *dev) { - struct Scsi_Host *host = dev_to_shost(dev); + struct Scsi_Host *host = dev_get_drvdata(dev); struct NCR_700_Host_Parameters *hostdata = shost_priv(host); scsi_remove_host(host); diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index d5576d54ce7..856e38b1486 100644 --- a/drivers/scsi/esp_scs |