diff options
Diffstat (limited to 'drivers/scsi')
33 files changed, 579 insertions, 63 deletions
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 76c09097175f..6b49f6a2524d 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -1160,13 +1160,12 @@ static int twa_initialize_device_extension(TW_Device_Extension *tw_dev) } /* Allocate event info space */ - tw_dev->event_queue[0] = kmalloc(sizeof(TW_Event) * TW_Q_LENGTH, GFP_KERNEL); + tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL); if (!tw_dev->event_queue[0]) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x18, "Event info memory allocation failed"); goto out; } - memset(tw_dev->event_queue[0], 0, sizeof(TW_Event) * TW_Q_LENGTH); for (i = 0; i < TW_Q_LENGTH; i++) { tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event))); diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 9d2119b53ac9..a947257b8964 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -483,7 +483,7 @@ source "drivers/scsi/aic94xx/Kconfig" # All the I2O code and drivers do not seem to be 64bit safe. config SCSI_DPT_I2O tristate "Adaptec I2O RAID support " - depends on !64BIT && SCSI && PCI + depends on !64BIT && SCSI && PCI && VIRT_TO_BUS help This driver supports all of Adaptec's I2O based RAID controllers as well as the DPT SmartRaid V cards. This is an Adaptec maintained @@ -545,7 +545,7 @@ config SCSI_HPTIOP config SCSI_BUSLOGIC tristate "BusLogic SCSI support" - depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API + depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API && VIRT_TO_BUS ---help--- This is support for BusLogic MultiMaster and FlashPoint SCSI Host Adapters. Consult the SCSI-HOWTO, available from diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 0f8689557158..86a7ba7bad63 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -132,6 +132,7 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/ obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/ obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o obj-$(CONFIG_SCSI_STEX) += stex.o +obj-$(CONFIG_PS3_ROM) += ps3rom.o obj-$(CONFIG_ARM) += arm/ diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index 8b5334c56f0a..79b4df158140 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c @@ -95,6 +95,8 @@ enum { /* The master ring of all esp hosts we are managing in this driver. */ static struct NCR_ESP *espchain; int nesps = 0, esps_in_use = 0, esps_running = 0; +EXPORT_SYMBOL(nesps); +EXPORT_SYMBOL(esps_running); irqreturn_t esp_intr(int irq, void *dev_id); @@ -524,6 +526,7 @@ void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs) /* Eat any bitrot in the chip and we are done... */ trash = esp_read(eregs->esp_intrpt); } +EXPORT_SYMBOL(esp_bootup_reset); /* Allocate structure and insert basic data such as SCSI chip frequency * data and a pointer to the device @@ -772,6 +775,7 @@ const char *esp_info(struct Scsi_Host *host) panic("Bogon ESP revision"); }; } +EXPORT_SYMBOL(esp_info); /* From Wolfgang Stanglmeier's NCR scsi driver. */ struct info_str @@ -902,6 +906,7 @@ int esp_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t off *start = buffer; return esp_host_info(esp, buffer, offset, length); } +EXPORT_SYMBOL(esp_proc_info); static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp) { @@ -3535,6 +3540,7 @@ state_machine: if(esp->dma_irq_exit) esp->dma_irq_exit(esp); } +EXPORT_SYMBOL(esp_handle); #ifndef CONFIG_SMP irqreturn_t esp_intr(int irq, void *dev_id) @@ -3606,11 +3612,10 @@ out: int esp_slave_alloc(struct scsi_device *SDptr) { struct esp_device *esp_dev = - kmalloc(sizeof(struct esp_device), GFP_ATOMIC); + kzalloc(sizeof(struct esp_device), GFP_ATOMIC); if (!esp_dev) return -ENOMEM; - memset(esp_dev, 0, sizeof(struct esp_device)); SDptr->hostdata = esp_dev; return 0; } @@ -3632,6 +3637,7 @@ void esp_release(void) esps_in_use--; esps_running = esps_in_use; } +EXPORT_SYMBOL(esp_release); #endif EXPORT_SYMBOL(esp_abort); diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index f12864abed2f..3a8089705feb 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c @@ -181,13 +181,12 @@ NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq, struct Scsi_Host *host; int ret; - hostdata = kmalloc(sizeof(*hostdata), GFP_KERNEL); + hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL); if (!hostdata) { printk(KERN_ERR "NCR D700: SIOP%d: Failed to allocate host" "data, detatching\n", siop); return -ENOMEM; } - memset(hostdata, 0, sizeof(*hostdata)); if (!request_region(region, 64, "NCR_D700")) { printk(KERN_ERR "NCR D700: Failed to reserve IO region 0x%x\n", diff --git a/drivers/scsi/NCR_Q720.c b/drivers/scsi/NCR_Q720.c index 778844c3544a..a8bbdc2273b8 100644 --- a/drivers/scsi/NCR_Q720.c +++ b/drivers/scsi/NCR_Q720.c @@ -148,11 +148,10 @@ NCR_Q720_probe(struct device *dev) __u32 base_addr, mem_size; void __iomem *mem_base; - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) return -ENOMEM; - memset(p, 0, sizeof(*p)); pos2 = mca_device_read_pos(mca_dev, 2); /* enable device */ pos2 |= NCR_Q720_POS2_BOARD_ENABLE | NCR_Q720_POS2_INTERRUPT_ENABLE; diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 1c0d7578e791..b8c6810090d5 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -462,7 +462,7 @@ static int asd_create_global_caches(void) sizeof(struct asd_dma_tok), 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); + NULL); if (!asd_dma_token_cache) { asd_printk("couldn't create dma token cache\n"); return -ENOMEM; @@ -474,7 +474,7 @@ static int asd_create_global_caches(void) sizeof(struct asd_ascb), 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); + NULL); if (!asd_ascb_cache) { asd_printk("couldn't create ascb cache\n"); goto Err; diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 0464c182c577..005d2b05f32d 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -1159,11 +1159,10 @@ static int __imm_attach(struct parport *pb) init_waitqueue_head(&waiting); - dev = kmalloc(sizeof(imm_struct), GFP_KERNEL); + dev = kzalloc(sizeof(imm_struct), GFP_KERNEL); if (!dev) return -ENOMEM; - memset(dev, 0, sizeof(imm_struct)); dev->base = -1; dev->mode = IMM_AUTODETECT; diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 9f8ed6b81576..492a51bd6aa8 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -7068,14 +7068,13 @@ ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr) subdevice_id = pci_dev->subsystem_device; /* found a controller */ - ha = kmalloc(sizeof (ips_ha_t), GFP_KERNEL); + ha = kzalloc(sizeof (ips_ha_t), GFP_KERNEL); if (ha == NULL) { IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate temporary ha struct\n"); return -1; } - memset(ha, 0, sizeof (ips_ha_t)); ips_sh[index] = NULL; ips_ha[index] = ha; diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index aebcd5fcdc55..7829ab1e2fb4 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1885,7 +1885,7 @@ static int iscsi_tcp_get_addr(struct iscsi_conn *conn, struct socket *sock, struct sockaddr_in *sin; int rc = 0, len; - addr = kmalloc(GFP_KERNEL, sizeof(*addr)); + addr = kmalloc(sizeof(*addr), GFP_KERNEL); if (!addr) return -ENOMEM; diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index 5c32a69e41ba..3126824da36d 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -101,13 +101,12 @@ lasi700_probe(struct parisc_device *dev) struct NCR_700_Host_Parameters *hostdata; struct Scsi_Host *host; - hostdata = kmalloc(sizeof(*hostdata), GFP_KERNEL); + hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL); if (!hostdata) { printk(KERN_ERR "%s: Failed to allocate host data\n", dev->dev.bus_id); return -ENOMEM; } - memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); hostdata->dev = &dev->dev; dma_set_mask(&dev->dev, DMA_32BIT_MASK); diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 965698c8b7bf..1396c83b0c9c 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -292,7 +292,7 @@ EXPORT_SYMBOL_GPL(sas_domain_release_transport); static int __init sas_class_init(void) { sas_task_cache = kmem_cache_create("sas_task", sizeof(struct sas_task), - 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + 0, SLAB_HWCACHE_ALIGN, NULL); if (!sas_task_cache) return -ENOMEM; diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index d70ddfda93fc..9c5342e7a69c 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -40,6 +40,7 @@ #include <linux/err.h> #include <linux/blkdev.h> +#include <linux/freezer.h> #include <linux/scatterlist.h> /* ---------- SCSI Host glue ---------- */ @@ -868,8 +869,6 @@ static int sas_queue_thread(void *_sas_ha) { struct sas_ha_struct *sas_ha = _sas_ha; - current->flags |= PF_NOFREEZE; - while (1) { set_current_state(TASK_INTERRUPTIBLE); schedule(); diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f81f85ee190f..07bd0dcdf0d6 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1830,7 +1830,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) /* Initialize and populate the iocb list per host. */ INIT_LIST_HEAD(&phba->lpfc_iocb_list); for (i = 0; i < LPFC_IOCB_LIST_CNT; i++) { - iocbq_entry = kmalloc(sizeof(struct lpfc_iocbq), GFP_KERNEL); + iocbq_entry = kzalloc(sizeof(struct lpfc_iocbq), GFP_KERNEL); if (iocbq_entry == NULL) { printk(KERN_ERR "%s: only allocated %d iocbs of " "expected %d count. Unloading driver.\n", @@ -1839,7 +1839,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) goto out_free_iocbq; } - memset(iocbq_entry, 0, sizeof(struct lpfc_iocbq)); iotag = lpfc_sli_next_iotag(phba, iocbq_entry); if (iotag == 0) { kfree (iocbq_entry); diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index c46685a03a9f..c6a53dccc16a 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -454,7 +454,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) pci_set_master(pdev); // Allocate the per driver initialization structure - adapter = kmalloc(sizeof(adapter_t), GFP_KERNEL); + adapter = kzalloc(sizeof(adapter_t), GFP_KERNEL); if (adapter == NULL) { con_log(CL_ANN, (KERN_WARNING @@ -462,7 +462,6 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) goto out_probe_one; } - memset(adapter, 0, sizeof(adapter_t)); // set up PCI related soft state and other pre-known parameters @@ -746,10 +745,9 @@ megaraid_init_mbox(adapter_t *adapter) * Allocate and initialize the init data structure for mailbox * controllers */ - raid_dev = kmalloc(sizeof(mraid_device_t), GFP_KERNEL); + raid_dev = kzalloc(sizeof(mraid_device_t), GFP_KERNEL); if (raid_dev == NULL) return -1; - memset(raid_dev, 0, sizeof(mraid_device_t)); /* * Attach the adapter soft state to raid device soft state @@ -1050,8 +1048,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) * since the calling routine does not yet know the number of available * commands. */ - adapter->kscb_list = kmalloc(sizeof(scb_t) * MBOX_MAX_SCSI_CMDS, - GFP_KERNEL); + adapter->kscb_list = kcalloc(MBOX_MAX_SCSI_CMDS, sizeof(scb_t), GFP_KERNEL); if (adapter->kscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING @@ -1059,7 +1056,6 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) __LINE__)); goto out_free_ibuf; } - memset(adapter->kscb_list, 0, sizeof(scb_t) * MBOX_MAX_SCSI_CMDS); // memory allocation for our command packets if (megaraid_mbox_setup_dma_pools(adapter) != 0) { @@ -3495,8 +3491,7 @@ megaraid_cmm_register(adapter_t *adapter) int i; // Allocate memory for the base list of scb for management module. - adapter->uscb_list = kmalloc(sizeof(scb_t) * MBOX_MAX_USER_CMDS, - GFP_KERNEL); + adapter->uscb_list = kcalloc(MBOX_MAX_USER_CMDS, sizeof(scb_t), GFP_KERNEL); if (adapter->uscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING @@ -3504,7 +3499,6 @@ megaraid_cmm_register(adapter_t *adapter) __LINE__)); return -1; } - memset(adapter->uscb_list, 0, sizeof(scb_t) * MBOX_MAX_USER_CMDS); // Initialize the synchronization parameters for resources for diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index 84d9c27133d4..b6587a6d8486 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -890,12 +890,11 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp) if (lld_adp->drvr_type != DRVRTYPE_MBOX) return (-EINVAL); - adapter = kmalloc(sizeof(mraid_mmadp_t), GFP_KERNEL); + adapter = kzalloc(sizeof(mraid_mmadp_t), GFP_KERNEL); if (!adapter) return -ENOMEM; - memset(adapter, 0, sizeof(mraid_mmadp_t)); adapter->unique_id = lld_adp->unique_id; adapter->drvr_type = lld_adp->drvr_type; diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index b7f2e613c903..ebb948c016bb 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -1636,15 +1636,13 @@ static int megasas_alloc_cmds(struct megasas_instance *instance) * Allocate the dynamic array first and then allocate individual * commands. */ - instance->cmd_list = kmalloc(sizeof(struct megasas_cmd *) * max_cmd, - GFP_KERNEL); + instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL); if (!instance->cmd_list) { printk(KERN_DEBUG "megasas: out of memory\n"); return -ENOMEM; } - memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) * max_cmd); for (i = 0; i < max_cmd; i++) { instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd), diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 370802d24acd..2dd0dc9a9aed 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -106,9 +106,8 @@ static int aha152x_probe(struct pcmcia_device *link) DEBUG(0, "aha152x_attach()\n"); /* Create new SCSI device */ - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - memset(info, 0, sizeof(*info)); info->p_dev = link; link->priv = info; diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index c6f8c6e65e05..445cfbbca9b3 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1602,9 +1602,8 @@ static int nsp_cs_probe(struct pcmcia_device *link) nsp_dbg(NSP_DEBUG_INIT, "in"); /* Create new SCSI device */ - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (info == NULL) { return -ENOMEM; } - memset(info, 0, sizeof(*info)); info->p_dev = link; link->priv = info; data->ScsiInfo = info; diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index 697cfb76c3a4..67c5a58d17df 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -162,10 +162,9 @@ static int qlogic_probe(struct pcmcia_device *link) DEBUG(0, "qlogic_attach()\n"); /* Create new SCSI device */ - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - memset(info, 0, sizeof(*info)); info->p_dev = link; link->priv = info; link->io.NumPorts1 = 16; diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 2695b7187b2f..961839ecfe86 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -875,10 +875,9 @@ SYM53C500_probe(struct pcmcia_device *link) DEBUG(0, "SYM53C500_attach()\n"); /* Create new SCSI device */ - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - memset(info, 0, sizeof(*info)); info->p_dev = link; link->priv = info; link->io.NumPorts1 = 16; diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index 2f1fa1eb7e90..67b6d76a6c8d 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -1014,10 +1014,9 @@ static int __ppa_attach(struct parport *pb) int modes, ppb, ppb_hi; int err = -ENOMEM; - dev = kmalloc(sizeof(ppa_struct), GFP_KERNEL); + dev = kzalloc(sizeof(ppa_struct), GFP_KERNEL); if (!dev) return -ENOMEM; - memset(dev, 0, sizeof(ppa_struct)); dev->base = -1; dev->mode = PPA_AUTODETECT; dev->recon_tmo = PPA_RECON_TMO; diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c new file mode 100644 index 000000000000..b50f1e14f2a5 --- /dev/null +++ b/drivers/scsi/ps3rom.c @@ -0,0 +1,533 @@ +/* + * PS3 BD/DVD/CD-ROM Storage Driver + * + * Copyright (C) 2007 Sony Computer Entertainment Inc. + * Copyright 2007 Sony Corp. + * + * 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 the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/cdrom.h> +#include <linux/highmem.h> + +#include <scsi/scsi.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_dbg.h> +#include <scsi/scsi_device.h> +#include <scsi/scsi_host.h> + +#include <asm/lv1call.h> +#include <asm/ps3stor.h> + + +#define DEVICE_NAME "ps3rom" + +#define BOUNCE_SIZE (64*1024) + +#define PS3ROM_MAX_SECTORS (BOUNCE_SIZE / CD_FRAMESIZE) + + +struct ps3rom_private { + struct ps3_storage_device *dev; + struct scsi_cmnd *curr_cmd; +}; + + +#define LV1_STORAGE_SEND_ATAPI_COMMAND (1) + +struct lv1_atapi_cmnd_block { + u8 pkt[32]; /* packet command block */ + u32 pktlen; /* should be 12 for ATAPI 8020 */ + u32 blocks; + u32 block_size; + u32 proto; /* transfer mode */ + u32 in_out; /* transfer direction */ + u64 buffer; /* parameter except command block */ + u32 arglen; /* length above */ +}; + +enum lv1_atapi_proto { + NON_DATA_PROTO = 0, + PIO_DATA_IN_PROTO = 1, + PIO_DATA_OUT_PROTO = 2, + DMA_PROTO = 3 +}; + +enum lv1_atapi_in_out { + DIR_WRITE = 0, /* memory -> device */ + DIR_READ = 1 /* device -> memory */ +}; + + +static int ps3rom_slave_configure(struct scsi_device *scsi_dev) +{ + struct ps3rom_private *priv = shost_priv(scsi_dev->host); + struct ps3_storage_device *dev = priv->dev; + + dev_dbg(&dev->sbd.core, "%s:%u: id %u, lun %u, channel %u\n", __func__, + __LINE__, scsi_dev->id, scsi_dev->lun, scsi_dev->channel); + + /* + * ATAPI SFF8020 devices use MODE_SENSE_10, + * so we can prohibit MODE_SENSE_6 + */ + scsi_dev->use_10_for_ms = 1; + + /* we don't support {READ,WRITE}_6 */ + scsi_dev->use_10_for_rw = 1; + + return 0; +} + +/* + * copy data from device into scatter/gather buffer + */ +static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf) +{ + int k, req_len, act_len, len, active; + void *kaddr; + struct scatterlist *sgpnt; + unsigned int buflen; + + buflen = cmd->request_bufflen; + if (!buflen) + return 0; + + if (!cmd->request_buffer) + return -1; + + sgpnt = cmd->request_buffer; + active = 1; + for (k = 0, req_len = 0, act_len = 0; k < cmd->use_sg; ++k, ++sgpnt) { + if (active) { + kaddr = kmap_atomic(sgpnt->page, KM_IRQ0); + len = sgpnt->length; + if ((req_len + len) > buflen) { + active = 0; + len = buflen - req_len; + } + memcpy(kaddr + sgpnt->offset, buf + req_len, len); + flush_kernel_dcache_page(sgpnt->page); + kunmap_atomic(kaddr, KM_IRQ0); + act_len += len; + } + req_len += sgpnt->length; + } + cmd->resid = req_len - act_len; + return 0; +} + +/* + * copy data from scatter/gather into device's buffer + */ +static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf) +{ + int k, req_len, len, fin; + void *kaddr; + struct scatterlist *sgpnt; + unsigned int buflen; + + buflen = cmd->request_bufflen; + if (!buflen) + return 0; + + if (!cmd->request_buffer) + return -1; + + sgpnt = cmd->request_buffer; + for (k = 0, req_len = 0, fin = 0; k < cmd->use_sg; ++k, ++sgpnt) { + kaddr = kmap_atomic(sgpnt->page, KM_IRQ0); + len = sgpnt->length; + if ((req_len + len) > buflen) { + len = buflen - req_len; + fin = 1; + } + memcpy(buf + req_len, kaddr + sgpnt->offset, len); + kunmap_atomic(kaddr, KM_IRQ0); + if (fin) + return req_len + len; + req_len += sgpnt->length; + } + return req_len; +} + +static int ps3rom_atapi_request(struct ps3_storage_device *dev, + struct scsi_cmnd *cmd) +{ + struct lv1_atapi_cmnd_block atapi_cmnd; + unsigned char opcode = cmd->cmnd[0]; + int res; + u64 lpar; + + dev_dbg(&dev->sbd.core, "%s:%u: send ATAPI command 0x%02x\n", __func__, + __LINE__, opcode); + + memset(&atapi_cmnd, 0, sizeof(struct lv1_atapi_cmnd_block)); + memcpy(&atapi_cmnd.pkt, cmd->cmnd, 12); + atapi_cmnd.pktlen = 12; + atapi_cmnd.block_size = 1; /* transfer size is block_size * blocks */ + atapi_cmnd.blocks = atapi_cmnd.arglen = cmd->request_bufflen; + atapi_cmnd.buffer = dev->bounce_lpar; + + switch (cmd->sc_data_direction) { + case DMA_FROM_DEVICE: + if (cmd->request_bufflen >= CD_FRAMESIZE) + atapi_cmnd.proto = DMA_PROTO; + else + atapi_cmnd.proto = PIO_DATA_IN_PROTO; + atapi_cmnd.in_out = DIR_READ; + break; + + case DMA_TO_DEVICE: + if (cmd->request_bufflen >= CD_FRAMESIZE) + atapi_cmnd.proto = DMA_PROTO; + else + atapi_cmnd.proto = PIO_DATA_OUT_PROTO; + atapi_cmnd.in_out = DIR_WRITE; + res = fetch_to_dev_buffer(cmd, dev->bounce_buf); + if (res < 0) + return DID_ERROR << 16; + break; + + default: + atapi_cmnd.proto = NON_DATA_PROTO; + break; + } + + lpar = ps3_mm_phys_to_lpar(__pa(&atapi_cmnd)); + res = lv1_storage_send_device_command(dev->sbd.dev_id, + LV1_STORAGE_SEND_ATAPI_COMMAND, + lpar, sizeof(atapi_cmnd), + atapi_cmnd.buffer, + atapi_cmnd.arglen, &dev->tag); + if (res == LV1_DENIED_BY_POLICY) { + dev_dbg(&dev->sbd.core, + "%s:%u: ATAPI command 0x%02x denied by policy\n", + __func__, __LINE__, opcode); + return DID_ERROR << 16; + } + + if (res) { + dev_err(&dev->sbd.core, + "%s:%u: ATAPI command 0x%02x failed %d\n", __func__, + __LINE__, opcode, res); + return DID_ERROR << 16; + } + + return 0; +} + +static inline unsigned int srb10_lba(const struct scsi_cmnd *cmd) +{ + return cmd->cmnd[2] << 24 | cmd->cmnd[3] << 16 | cmd->cmnd[4] << 8 | + cmd->cmnd[5]; +} + +static inline unsigned int srb10_len(const struct scsi_cmnd *cmd) +{ + return cmd->cmnd[7] << 8 | cmd->cmnd[8]; +} + +static int ps3rom_read_request(struct ps3_storage_device *dev, + struct scsi_cmnd *cmd, u32 start_sector, + u32 sectors) +{ + int res; + + dev_dbg(&dev->sbd.core, "%s:%u: read %u sectors starting at %u\n", + __func__, __LINE__, sectors, start_sector); + + res = lv1_storage_read(dev->sbd.dev_id, + dev->regions[dev->region_idx].id, start_sector, + sectors, 0, dev->bounce_lpar, &dev->tag); + if (res) { + dev_err(&dev->sbd.core, "%s:%u: read failed %d\n", __func__, + __LINE__, res); + return DID_ERROR << 16; + } + + return 0; +} + +static int ps3rom_write_request(struct ps3_storage_device *dev, + struct scsi_cmnd *cmd, u32 start_sector, + u32 sectors) +{ + int res; + + dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n", + __func__, __LINE__, sectors, start_sector); + + res = fetch_to_dev_buffer(cmd, dev->bounce_buf); + if (res < 0) + return DID_ERROR << 16; + + res = lv1_storage_write(dev->sbd.dev_id, + dev->regions[dev->region_idx].id, start_sector, + sectors, 0, dev->bounce_lpar, &dev->tag); + if (res) { + dev_err(&dev->sbd.core, "%s:%u: write failed %d\n", __func__, + __LINE__, res); + return DID_ERROR << 16; + } + + return 0; +} + +static int ps3rom_queuecommand(struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)) +{ + struct ps3rom_private *priv = shost_priv(cmd->device->host); + struct ps3_storage_device *dev = priv->dev; + unsigned char opcode; + int res; + +#ifdef DEBUG + scsi_print_command(cmd); +#endif + + priv->curr_cmd = cmd; + cmd->scsi_done = done; + + opcode = cmd->cmnd[0]; + /* + * While we can submit READ/WRITE SCSI commands as ATAPI commands, + * it's recommended for various reasons (performance, error handling, + * ...) to use lv1_storage_{read,write}() instead + */ + switch (opcode) { + case READ_10: + res = ps3rom_read_request(dev, cmd, srb10_lba(cmd), + srb10_len(cmd)); + break; + + case WRITE_10: + res = ps3rom_write_request(dev, cmd, srb10_lba(cmd), + srb10_len(cmd)); + break; + + default: + res = ps3rom_atapi_request(dev, cmd); + break; + } + + if (res) { + memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); + cmd->result = res; + cmd->sense_buffer[0] = 0x70; + cmd->sense_buffer[2] = ILLEGAL_REQUEST; + priv->curr_cmd = NULL; + cmd->scsi_done(cmd); + } + + return 0; +} + +static int decode_lv1_status(u64 status, unsigned char *sense_key, + unsigned char *asc, unsigned char *ascq) +{ + if (((status >> 24) & 0xff) != SAM_STAT_CHECK_CONDITION) + return -1; + + *sense_key = (status >> 16) & 0xff; + *asc = (status >> 8) & 0xff; + *ascq = status & 0xff; + return 0; +} + +static irqreturn_t ps3rom_interrupt(int irq, void *data) +{ + struct ps3_storage_device *dev = data; + struct Scsi_Host *host; + struct ps3rom_private *priv; + struct scsi_cmnd *cmd; + int res; + u64 tag, status; + unsigned char sense_key, asc, ascq; + + res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status); + /* + * status = -1 may mean that ATAPI transport completed OK, but + * ATAPI command itself resulted CHECK CONDITION + * so, upper layer should issue REQUEST_SENSE to check the sense data + */ + + if (tag != dev->tag) + dev_err(&dev->sbd.core, + "%s:%u: tag mismatch, got %lx, expected %lx\n", + __func__, __LINE__, tag, dev->tag); + + if (res) { + dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n", + __func__, __LINE__, res, status); + return IRQ_HANDLED; + } + + host = dev->sbd.core.driver_data; + priv = shost_priv(host); + cmd = priv->curr_cmd; + + if (!status) { + /* OK, completed */ + if (cmd->sc_data_direction == DMA_FROM_DEVICE) { + res = fill_from_dev_buffer(cmd, dev->bounce_buf); + if (res) { + cmd->result = DID_ERROR << 16; + goto done; + } + } + cmd->result = DID_OK << 16; + goto done; + } + + if (cmd->cmnd[0] == REQUEST_SENSE) { + /* SCSI spec says request sense should never get error */ + dev_err(&dev->sbd.core, "%s:%u: end error without autosense\n", + __func__, __LINE__); + cmd->result = DID_ERROR << 16 | SAM_STAT_CHECK_CONDITION; + goto done; + } + + if (decode_lv1_status(status, &sense_key, &asc, &ascq)) { + cmd->result = DID_ERROR << 16; + goto done; + } + + cmd->sense_buffer[0] = 0x70; + cmd->sense_buffer[2] = sense_key; + cmd->sense_buffer[7] = 16 - 6; + cmd->sense_buffer[12] = asc; + cmd->sense_buffer[13] = ascq; + cmd->result = SAM_STAT_CHECK_CONDITION; + +done: + priv->curr_cmd = NULL; + cmd->scsi_done(cmd); + return IRQ_HANDLED; +} + +static struct scsi_host_template ps3rom_host_template = { + .name = DEVICE_NAME, + .slave_configure = ps3rom_slave_configure, + .queuecommand = ps3rom_queuecommand, + .can_queue = 1, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 1, + .emulated = 1, /* only sg driver uses this */ + .max_sectors = PS3ROM_MAX_SECTORS, + .use_clustering = ENABLE_CLUSTERING, + .module = THIS_MODULE, +}; + + +static int __devinit ps3rom_probe(struct ps3_system_bus_device *_dev) +{ + struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); + int error; + struct Scsi_Host *host; + struct ps3rom_private *priv; + + if (dev->blk_size != CD_FRAMESIZE) { + dev_err(&dev->sbd.core, + "%s:%u: cannot handle block size %lu\n", __func__, + __LINE__, dev->blk_size); + return -EINVAL; + } + + dev->bounce_size = BOUNCE_SIZE; + dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA); + if (!dev->bounce_buf) + return -ENOMEM; + + error = ps3stor_setup(dev, ps3rom_interrupt); + if (error) + goto fail_free_bounce; + + host = scsi_host_alloc(&ps3rom_host_template, + sizeof(struct ps3rom_private)); + if (!host) { + dev_err(&dev->sbd.core, "%s:%u: scsi_host_alloc failed\n", + __func__, __LINE__); + goto fail_teardown; + } + + priv = shost_priv(host); + dev->sbd.core.driver_data = host; + priv->dev = dev; + + /* One device/LUN per SCSI bus */ + host->max_id = 1; + host->max_lun = 1; + + error = scsi_add_host(host, &dev->sbd.core); + if (error) { + dev_err(&dev->sbd.core, "%s:%u: scsi_host_alloc failed %d\n", + __func__, __LINE__, error); + error = -ENODEV; + goto fail_host_put; + } + + scsi_scan_host(host); + return 0; + +fail_host_put: + scsi_host_put(host); + dev->sbd.core.driver_data = NULL; +fail_teardown: + ps3stor_teardown(dev); +fail_free_bounce: + kfree(dev->bounce_buf); + return error; +} + +static int ps3rom_remove(struct ps3_system_bus_device *_dev) +{ + struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); + struct Scsi_Host *host = dev->sbd.core.driver_data; + + scsi_remove_host(host); + ps3stor_teardown(dev); + scsi_host_put(host); + dev->sbd.core.driver_data = NULL; + kfree(dev->bounce_buf); + return 0; +} + +static struct ps3_system_bus_driver ps3rom = { + .match_id = PS3_MATCH_ID_STOR_ROM, + .core.name = DEVICE_NAME, + .core.owner = THIS_MODULE, + .probe = ps3rom_probe, + .remove = ps3rom_remove +}; + + +static int __init ps3rom_init(void) +{ + return ps3_system_bus_driver_register(&ps3rom); +} + +static void __exit ps3rom_exit(void) +{ + ps3_system_bus_driver_unregister(&ps3rom); +} + +module_init(ps3rom_init); +module_exit(ps3rom_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("PS3 BD/DVD/CD-ROM Storage Driver"); +MODULE_AUTHOR("Sony Corporation"); +MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_ROM); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index b5a77b0c0deb..92376f9dfdd5 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2723,7 +2723,7 @@ qla2x00_module_init(void) /* Allocate cache for SRBs. */ srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); + SLAB_HWCACHE_ALIGN, NULL); if (srb_cachep == NULL) { printk(KERN_ERR "qla2xxx: Unable to allocate SRB cache...Failing load!\n"); diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index e69160a7bc60..b1d565c12c5b 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -1677,7 +1677,7 @@ static int __init qla4xxx_module_init(void) /* Allocate cache for SRBs. */ srb_cachep = kmem_cache_create("qla4xxx_srbs", sizeof(struct srb), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); + SLAB_HWCACHE_ALIGN, NULL); if (srb_cachep == NULL) { printk(KERN_ERR "%s: Unable to allocate SRB cache..." diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index a691dda40d2c..a5de1a829a76 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -288,7 +288,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) if (!pool->users) { pool->slab = kmem_cache_create(pool->name, sizeof(struct scsi_cmnd), 0, - pool->slab_flags, NULL, NULL); + pool->slab_flags, NULL); if (!pool->slab) goto fail; } diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 9adb64ac054c..8a525abda30f 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -19,6 +19,7 @@ #include <linux/timer.h> #include <linux/string.h> #include <linux/kernel.h> +#include <linux/freezer.h> #include <linux/kthread.h> #include <linux/interrupt.h> #include <linux/blkdev.h> @@ -1516,8 +1517,6 @@ int scsi_error_handler(void *data) { struct Scsi_Host *shost = data; - current->flags |= PF_NOFREEZE; - /* * We use TASK_INTERRUPTIBLE so that the thread is not * counted against the load average as a running process. diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 1f5a07bf2a75..da63c544919b 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1661,7 +1661,7 @@ int __init scsi_init_queue(void) scsi_io_context_cache = kmem_cache_create("scsi_io_context", sizeof(struct scsi_io_context), - 0, 0, NULL, NULL); + 0, 0, NULL); if (!scsi_io_context_cache) { printk(KERN_ERR "SCSI: can't init scsi io context cache\n"); return -ENOMEM; @@ -1672,7 +1672,7 @@ int __init scsi_init_queue(void) int size = sgp->size * sizeof(struct scatterlist); sgp->slab = kmem_cache_create(sgp->name, size, 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); + SLAB_HWCACHE_ALIGN, NULL); if (!sgp->slab) { printk(KERN_ERR "SCSI: can't init sg slab %s\n", sgp->name); diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index 2570f48a69c7..371b69c110bc 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -585,7 +585,7 @@ static int __init scsi_tgt_init(void) scsi_tgt_cmd_cache = kmem_cache_create("scsi_tgt_cmd", sizeof(struct scsi_tgt_cmd), - 0, 0, NULL, NULL); + 0, 0, NULL); if (!scsi_tgt_cmd_cache) return -ENOMEM; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 448d316f12d7..424d557284a9 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -684,7 +684,7 @@ static int sd_ioctl(struct inode * inode, struct file * filp, case SCSI_IOCTL_GET_BUS_NUMBER: return scsi_ioctl(sdp, cmd, p); default: - error = scsi_cmd_ioctl(filp, disk, cmd, p); + error = scsi_cmd_ioctl(filp, disk->queue, disk, cmd, p); if (error != -ENOTTY) return error; } diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index 018c65f73ac4..710f19de3d40 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c @@ -100,7 +100,7 @@ sim710_probe_common(struct device *dev, unsigned long base_addr, { struct Scsi_Host * host = NULL; struct NCR_700_Host_Parameters *hostdata = - kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); printk(KERN_NOTICE "sim710: %s\n", dev->bus_id); printk(KERN_NOTICE "sim710: irq = %d, clock = %d, base = 0x%lx, scsi_id = %d\n", @@ -110,7 +110,6 @@ sim710_probe_common(struct device *dev, unsigned long base_addr, printk(KERN_ERR "sim710: Failed to allocate host data\n"); goto out; } - memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); if(request_region(base_addr, 64, "sim710") == NULL) { printk(KERN_ERR "sim710: Failed to reserve IO region 0x%lx\n", diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 55bfeccf68a2..a4f7b8465773 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3549,7 +3549,8 @@ static int st_ioctl(struct inode *inode, struct file *file, !capable(CAP_SYS_RAWIO)) i = -EPERM; else - i = scsi_cmd_ioctl(file, STp->disk, cmd_in, p); + i = scsi_cmd_ioctl(file, STp->disk->queue, + STp->disk, cmd_in, p); if (i != -ENOTTY) return i; break; diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index 14cba1ca38b3..5db1520f8ba9 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c @@ -2082,10 +2082,9 @@ static int dc390_slave_alloc(struct scsi_device *scsi_device) uint id = scsi_device->id; uint lun = scsi_device->lun; - pDCB = kmalloc(sizeof(struct dc390_dcb), GFP_KERNEL); + pDCB = kzalloc(sizeof(struct dc390_dcb), GFP_KERNEL); if (!pDCB) return -ENOMEM; - memset(pDCB, 0, sizeof(struct dc390_dcb)); if (!pACB->DCBCnt++) { pACB->pLinkDCB = pDCB; |