mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-for-linus-2.6
This commit is contained in:
commit
9600c11ba3
45 changed files with 4234 additions and 1584 deletions
|
|
@ -1109,15 +1109,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
|
|||
return (0);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ahc_linux_get_memsize(void)
|
||||
{
|
||||
struct sysinfo si;
|
||||
|
||||
si_meminfo(&si);
|
||||
return ((uint64_t)si.totalram << PAGE_SHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Place the SCSI bus into a known state by either resetting it,
|
||||
* or forcing transfer negotiations on the next command to any
|
||||
|
|
|
|||
|
|
@ -494,8 +494,6 @@ ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
|
|||
int ahc_linux_register_host(struct ahc_softc *,
|
||||
struct scsi_host_template *);
|
||||
|
||||
uint64_t ahc_linux_get_memsize(void);
|
||||
|
||||
/*************************** Pretty Printing **********************************/
|
||||
struct info_str {
|
||||
char *buffer;
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
struct ahc_pci_identity *entry;
|
||||
char *name;
|
||||
int error;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
pci = pdev;
|
||||
entry = ahc_find_pci_device(pci);
|
||||
|
|
@ -209,11 +210,12 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
pci_set_master(pdev);
|
||||
|
||||
if (sizeof(dma_addr_t) > 4
|
||||
&& ahc_linux_get_memsize() > 0x80000000
|
||||
&& pci_set_dma_mask(pdev, mask_39bit) == 0) {
|
||||
&& ahc->features & AHC_LARGE_SCBS
|
||||
&& dma_set_mask(dev, mask_39bit) == 0
|
||||
&& dma_get_required_mask(dev) > DMA_32BIT_MASK) {
|
||||
ahc->flags |= AHC_39BIT_ADDRESSING;
|
||||
} else {
|
||||
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
|
||||
if (dma_set_mask(dev, DMA_32BIT_MASK)) {
|
||||
printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
|
||||
return (-ENODEV);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -996,6 +996,7 @@ oktosend:
|
|||
#ifdef ED_DBGP
|
||||
printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id);
|
||||
#endif
|
||||
dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus;
|
||||
outl(dev->id[c][target_id].prdaddr, tmpcip);
|
||||
tmpcip = tmpcip - 2;
|
||||
outb(0x06, tmpcip);
|
||||
|
|
@ -2572,7 +2573,7 @@ static void atp870u_free_tables(struct Scsi_Host *host)
|
|||
for (k = 0; k < 16; k++) {
|
||||
if (!atp_dev->id[j][k].prd_table)
|
||||
continue;
|
||||
pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prdaddr);
|
||||
pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prd_bus);
|
||||
atp_dev->id[j][k].prd_table = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -2584,12 +2585,13 @@ static int atp870u_init_tables(struct Scsi_Host *host)
|
|||
int c,k;
|
||||
for(c=0;c < 2;c++) {
|
||||
for(k=0;k<16;k++) {
|
||||
atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prdaddr));
|
||||
atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prd_bus));
|
||||
if (!atp_dev->id[c][k].prd_table) {
|
||||
printk("atp870u_init_tables fail\n");
|
||||
atp870u_free_tables(host);
|
||||
return -ENOMEM;
|
||||
}
|
||||
atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus;
|
||||
atp_dev->id[c][k].devsp=0x20;
|
||||
atp_dev->id[c][k].devtype = 0x7f;
|
||||
atp_dev->id[c][k].curr_req = NULL;
|
||||
|
|
|
|||
|
|
@ -54,8 +54,9 @@ struct atp_unit
|
|||
unsigned long tran_len;
|
||||
unsigned long last_len;
|
||||
unsigned char *prd_pos;
|
||||
unsigned char *prd_table;
|
||||
dma_addr_t prdaddr;
|
||||
unsigned char *prd_table; /* Kernel address of PRD table */
|
||||
dma_addr_t prd_bus; /* Bus address of PRD */
|
||||
dma_addr_t prdaddr; /* Dynamically updated in driver */
|
||||
struct scsi_cmnd *curr_req;
|
||||
} id[2][16];
|
||||
struct Scsi_Host *host;
|
||||
|
|
|
|||
|
|
@ -1360,3 +1360,5 @@ static Scsi_Host_Template driver_template = {
|
|||
.use_clustering = DISABLE_CLUSTERING,
|
||||
};
|
||||
#include "scsi_module.c"
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
|
|||
switch (oldstate) {
|
||||
case SHOST_CREATED:
|
||||
case SHOST_RUNNING:
|
||||
case SHOST_CANCEL_RECOVERY:
|
||||
break;
|
||||
default:
|
||||
goto illegal;
|
||||
|
|
@ -107,12 +108,31 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
|
|||
case SHOST_DEL:
|
||||
switch (oldstate) {
|
||||
case SHOST_CANCEL:
|
||||
case SHOST_DEL_RECOVERY:
|
||||
break;
|
||||
default:
|
||||
goto illegal;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHOST_CANCEL_RECOVERY:
|
||||
switch (oldstate) {
|
||||
case SHOST_CANCEL:
|
||||
case SHOST_RECOVERY:
|
||||
break;
|
||||
default:
|
||||
goto illegal;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHOST_DEL_RECOVERY:
|
||||
switch (oldstate) {
|
||||
case SHOST_CANCEL_RECOVERY:
|
||||
break;
|
||||
default:
|
||||
goto illegal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
shost->shost_state = state;
|
||||
return 0;
|
||||
|
|
@ -134,13 +154,24 @@ EXPORT_SYMBOL(scsi_host_set_state);
|
|||
**/
|
||||
void scsi_remove_host(struct Scsi_Host *shost)
|
||||
{
|
||||
unsigned long flags;
|
||||
down(&shost->scan_mutex);
|
||||
scsi_host_set_state(shost, SHOST_CANCEL);
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
if (scsi_host_set_state(shost, SHOST_CANCEL))
|
||||
if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) {
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
up(&shost->scan_mutex);
|
||||
return;
|
||||
}
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
up(&shost->scan_mutex);
|
||||
scsi_forget_host(shost);
|
||||
scsi_proc_host_rm(shost);
|
||||
|
||||
scsi_host_set_state(shost, SHOST_DEL);
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
if (scsi_host_set_state(shost, SHOST_DEL))
|
||||
BUG_ON(scsi_host_set_state(shost, SHOST_DEL_RECOVERY));
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
||||
transport_unregister_device(&shost->shost_gendev);
|
||||
class_device_unregister(&shost->shost_classdev);
|
||||
|
|
|
|||
|
|
@ -460,6 +460,8 @@ MODULE_PARM(adisplay, "1i");
|
|||
MODULE_PARM(normal, "1i");
|
||||
MODULE_PARM(ansi, "1i");
|
||||
#endif
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
#endif
|
||||
/*counter of concurrent disk read/writes, to turn on/off disk led */
|
||||
static int disk_rw_in_progress = 0;
|
||||
|
|
|
|||
|
|
@ -727,6 +727,16 @@ static void adapter_info_rsp(struct srp_event_struct *evt_struct)
|
|||
if (hostdata->madapter_info.port_max_txu[0])
|
||||
hostdata->host->max_sectors =
|
||||
hostdata->madapter_info.port_max_txu[0] >> 9;
|
||||
|
||||
if (hostdata->madapter_info.os_type == 3 &&
|
||||
strcmp(hostdata->madapter_info.srp_version, "1.6a") <= 0) {
|
||||
printk("ibmvscsi: host (Ver. %s) doesn't support large"
|
||||
"transfers\n",
|
||||
hostdata->madapter_info.srp_version);
|
||||
printk("ibmvscsi: limiting scatterlists to %d\n",
|
||||
MAX_INDIRECT_BUFS);
|
||||
hostdata->host->sg_tablesize = MAX_INDIRECT_BUFS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1265,9 +1265,8 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery)
|
|||
list_for_each_safe(lh, lh_sf, &active_list) {
|
||||
scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
|
||||
list_del_init(lh);
|
||||
if (recovery) {
|
||||
scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD);
|
||||
} else {
|
||||
if (recovery &&
|
||||
!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD)) {
|
||||
scmd->result = (DID_ABORT << 16);
|
||||
scsi_finish_command(scmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ static struct {
|
|||
{"RELISYS", "Scorpio", NULL, BLIST_NOLUN}, /* responds to all lun */
|
||||
{"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */
|
||||
{"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN},
|
||||
{"transtec", "T5008", "0001", BLIST_NOREPORTLUN },
|
||||
{"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* locks up */
|
||||
{"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* locks up */
|
||||
{"YAMAHA", "CRW8424S", "1.0", BLIST_NOLUN}, /* locks up */
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
void scsi_eh_wakeup(struct Scsi_Host *shost)
|
||||
{
|
||||
if (shost->host_busy == shost->host_failed) {
|
||||
up(shost->eh_wait);
|
||||
wake_up_process(shost->ehandler);
|
||||
SCSI_LOG_ERROR_RECOVERY(5,
|
||||
printk("Waking error handler thread\n"));
|
||||
}
|
||||
|
|
@ -68,19 +68,24 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
|
|||
{
|
||||
struct Scsi_Host *shost = scmd->device->host;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (shost->eh_wait == NULL)
|
||||
if (!shost->ehandler)
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
if (scsi_host_set_state(shost, SHOST_RECOVERY))
|
||||
if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY))
|
||||
goto out_unlock;
|
||||
|
||||
ret = 1;
|
||||
scmd->eh_eflags |= eh_flag;
|
||||
list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
|
||||
scsi_host_set_state(shost, SHOST_RECOVERY);
|
||||
shost->host_failed++;
|
||||
scsi_eh_wakeup(shost);
|
||||
out_unlock:
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -176,8 +181,8 @@ void scsi_times_out(struct scsi_cmnd *scmd)
|
|||
}
|
||||
|
||||
if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) {
|
||||
panic("Error handler thread not present at %p %p %s %d",
|
||||
scmd, scmd->device->host, __FILE__, __LINE__);
|
||||
scmd->result |= DID_TIME_OUT << 16;
|
||||
__scsi_done(scmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -196,8 +201,7 @@ int scsi_block_when_processing_errors(struct scsi_device *sdev)
|
|||
{
|
||||
int online;
|
||||
|
||||
wait_event(sdev->host->host_wait, (sdev->host->shost_state !=
|
||||
SHOST_RECOVERY));
|
||||
wait_event(sdev->host->host_wait, !scsi_host_in_recovery(sdev->host));
|
||||
|
||||
online = scsi_device_online(sdev);
|
||||
|
||||
|
|
@ -1441,6 +1445,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
|
|||
static void scsi_restart_operations(struct Scsi_Host *shost)
|
||||
{
|
||||
struct scsi_device *sdev;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* If the door was locked, we need to insert a door lock request
|
||||
|
|
@ -1460,7 +1465,11 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
|
|||
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n",
|
||||
__FUNCTION__));
|
||||
|
||||
scsi_host_set_state(shost, SHOST_RUNNING);
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
if (scsi_host_set_state(shost, SHOST_RUNNING))
|
||||
if (scsi_host_set_state(shost, SHOST_CANCEL))
|
||||
BUG_ON(scsi_host_set_state(shost, SHOST_DEL));
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
||||
wake_up(&shost->host_wait);
|
||||
|
||||
|
|
@ -1582,40 +1591,31 @@ int scsi_error_handler(void *data)
|
|||
{
|
||||
struct Scsi_Host *shost = (struct Scsi_Host *) data;
|
||||
int rtn;
|
||||
DECLARE_MUTEX_LOCKED(sem);
|
||||
|
||||
current->flags |= PF_NOFREEZE;
|
||||
shost->eh_wait = &sem;
|
||||
|
||||
|
||||
/*
|
||||
* Wake up the thread that created us.
|
||||
* Note - we always use TASK_INTERRUPTIBLE even if the module
|
||||
* was loaded as part of the kernel. The reason is that
|
||||
* UNINTERRUPTIBLE would cause this thread to be counted in
|
||||
* the load average as a running process, and an interruptible
|
||||
* wait doesn't.
|
||||
*/
|
||||
SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of"
|
||||
" scsi_eh_%d\n",shost->host_no));
|
||||
|
||||
while (1) {
|
||||
/*
|
||||
* If we get a signal, it means we are supposed to go
|
||||
* away and die. This typically happens if the user is
|
||||
* trying to unload a module.
|
||||
*/
|
||||
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
|
||||
" scsi_eh_%d"
|
||||
" sleeping\n",shost->host_no));
|
||||
|
||||
/*
|
||||
* Note - we always use down_interruptible with the semaphore
|
||||
* even if the module was loaded as part of the kernel. The
|
||||
* reason is that down() will cause this thread to be counted
|
||||
* in the load average as a running process, and down
|
||||
* interruptible doesn't. Given that we need to allow this
|
||||
* thread to die if the driver was loaded as a module, using
|
||||
* semaphores isn't unreasonable.
|
||||
*/
|
||||
down_interruptible(&sem);
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
while (!kthread_should_stop()) {
|
||||
if (shost->host_failed == 0 ||
|
||||
shost->host_failed != shost->host_busy) {
|
||||
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
|
||||
" scsi_eh_%d"
|
||||
" sleeping\n",
|
||||
shost->host_no));
|
||||
schedule();
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
continue;
|
||||
}
|
||||
|
||||
__set_current_state(TASK_RUNNING);
|
||||
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
|
||||
" scsi_eh_%d waking"
|
||||
" up\n",shost->host_no));
|
||||
|
|
@ -1642,7 +1642,7 @@ int scsi_error_handler(void *data)
|
|||
* which are still online.
|
||||
*/
|
||||
scsi_restart_operations(shost);
|
||||
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
}
|
||||
|
||||
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d"
|
||||
|
|
@ -1651,7 +1651,7 @@ int scsi_error_handler(void *data)
|
|||
/*
|
||||
* Make sure that nobody tries to wake us up again.
|
||||
*/
|
||||
shost->eh_wait = NULL;
|
||||
shost->ehandler = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -458,7 +458,7 @@ int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
|
|||
* error processing, as long as the device was opened
|
||||
* non-blocking */
|
||||
if (filp && filp->f_flags & O_NONBLOCK) {
|
||||
if (sdev->host->shost_state == SHOST_RECOVERY)
|
||||
if (scsi_host_in_recovery(sdev->host))
|
||||
return -ENODEV;
|
||||
} else if (!scsi_block_when_processing_errors(sdev))
|
||||
return -ENODEV;
|
||||
|
|
|
|||
|
|
@ -118,7 +118,6 @@ static void scsi_unprep_request(struct request *req)
|
|||
req->flags &= ~REQ_DONTPREP;
|
||||
req->special = (req->flags & REQ_SPECIAL) ? cmd->sc_request : NULL;
|
||||
|
||||
scsi_release_buffers(cmd);
|
||||
scsi_put_command(cmd);
|
||||
}
|
||||
|
||||
|
|
@ -140,14 +139,12 @@ static void scsi_unprep_request(struct request *req)
|
|||
* commands.
|
||||
* Notes: This could be called either from an interrupt context or a
|
||||
* normal process context.
|
||||
* Notes: Upon return, cmd is a stale pointer.
|
||||
*/
|
||||
int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
|
||||
{
|
||||
struct Scsi_Host *host = cmd->device->host;
|
||||
struct scsi_device *device = cmd->device;
|
||||
struct request_queue *q = device->request_queue;
|
||||
struct request *req = cmd->request;
|
||||
unsigned long flags;
|
||||
|
||||
SCSI_LOG_MLQUEUE(1,
|
||||
|
|
@ -188,9 +185,8 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
|
|||
* function. The SCSI request function detects the blocked condition
|
||||
* and plugs the queue appropriately.
|
||||
*/
|
||||
scsi_unprep_request(req);
|
||||
spin_lock_irqsave(q->queue_lock, flags);
|
||||
blk_requeue_request(q, req);
|
||||
blk_requeue_request(q, cmd->request);
|
||||
spin_unlock_irqrestore(q->queue_lock, flags);
|
||||
|
||||
scsi_run_queue(q);
|
||||
|
|
@ -451,7 +447,7 @@ void scsi_device_unbusy(struct scsi_device *sdev)
|
|||
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
shost->host_busy--;
|
||||
if (unlikely((shost->shost_state == SHOST_RECOVERY) &&
|
||||
if (unlikely(scsi_host_in_recovery(shost) &&
|
||||
shost->host_failed))
|
||||
scsi_eh_wakeup(shost);
|
||||
spin_unlock(shost->host_lock);
|
||||
|
|
@ -1268,6 +1264,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
|
|||
}
|
||||
} else {
|
||||
memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
|
||||
cmd->cmd_len = req->cmd_len;
|
||||
if (rq_data_dir(req) == WRITE)
|
||||
cmd->sc_data_direction = DMA_TO_DEVICE;
|
||||
else if (req->data_len)
|
||||
|
|
@ -1342,7 +1339,7 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
|
|||
struct Scsi_Host *shost,
|
||||
struct scsi_device *sdev)
|
||||
{
|
||||
if (shost->shost_state == SHOST_RECOVERY)
|
||||
if (scsi_host_in_recovery(shost))
|
||||
return 0;
|
||||
if (shost->host_busy == 0 && shost->host_blocked) {
|
||||
/*
|
||||
|
|
@ -1514,7 +1511,6 @@ static void scsi_request_fn(struct request_queue *q)
|
|||
* cases (host limits or settings) should run the queue at some
|
||||
* later time.
|
||||
*/
|
||||
scsi_unprep_request(req);
|
||||
spin_lock_irq(q->queue_lock);
|
||||
blk_requeue_request(q, req);
|
||||
sdev->device_busy--;
|
||||
|
|
|
|||
|
|
@ -1466,23 +1466,17 @@ EXPORT_SYMBOL(scsi_scan_single_target);
|
|||
|
||||
void scsi_forget_host(struct Scsi_Host *shost)
|
||||
{
|
||||
struct scsi_target *starget, *tmp;
|
||||
struct scsi_device *sdev;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Ok, this look a bit strange. We always look for the first device
|
||||
* on the list as scsi_remove_device removes them from it - thus we
|
||||
* also have to release the lock.
|
||||
* We don't need to get another reference to the device before
|
||||
* releasing the lock as we already own the reference from
|
||||
* scsi_register_device that's release in scsi_remove_device. And
|
||||
* after that we don't look at sdev anymore.
|
||||
*/
|
||||
restart:
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
list_for_each_entry_safe(starget, tmp, &shost->__targets, siblings) {
|
||||
list_for_each_entry(sdev, &shost->__devices, siblings) {
|
||||
if (sdev->sdev_state == SDEV_DEL)
|
||||
continue;
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
scsi_remove_target(&starget->dev);
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
__scsi_remove_device(sdev);
|
||||
goto restart;
|
||||
}
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ static struct {
|
|||
{ SHOST_CANCEL, "cancel" },
|
||||
{ SHOST_DEL, "deleted" },
|
||||
{ SHOST_RECOVERY, "recovery" },
|
||||
{ SHOST_CANCEL_RECOVERY, "cancel/recovery" },
|
||||
{ SHOST_DEL_RECOVERY, "deleted/recovery", },
|
||||
};
|
||||
const char *scsi_host_state_name(enum scsi_host_state state)
|
||||
{
|
||||
|
|
@ -707,9 +709,11 @@ void __scsi_remove_device(struct scsi_device *sdev)
|
|||
**/
|
||||
void scsi_remove_device(struct scsi_device *sdev)
|
||||
{
|
||||
down(&sdev->host->scan_mutex);
|
||||
struct Scsi_Host *shost = sdev->host;
|
||||
|
||||
down(&shost->scan_mutex);
|
||||
__scsi_remove_device(sdev);
|
||||
up(&sdev->host->scan_mutex);
|
||||
up(&shost->scan_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(scsi_remove_device);
|
||||
|
||||
|
|
@ -717,17 +721,20 @@ void __scsi_remove_target(struct scsi_target *starget)
|
|||
{
|
||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||
unsigned long flags;
|
||||
struct scsi_device *sdev, *tmp;
|
||||
struct scsi_device *sdev;
|
||||
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
starget->reap_ref++;
|
||||
list_for_each_entry_safe(sdev, tmp, &shost->__devices, siblings) {
|
||||
restart:
|
||||
list_for_each_entry(sdev, &shost->__devices, siblings) {
|
||||
if (sdev->channel != starget->channel ||
|
||||
sdev->id != starget->id)
|
||||
sdev->id != starget->id ||
|
||||
sdev->sdev_state == SDEV_DEL)
|
||||
continue;
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
scsi_remove_device(sdev);
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
goto restart;
|
||||
}
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
scsi_target_reap(starget);
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|||
return 0;
|
||||
|
||||
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
|
||||
SCpnt->cmd_len = rq->cmd_len;
|
||||
if (rq_data_dir(rq) == WRITE)
|
||||
SCpnt->sc_data_direction = DMA_TO_DEVICE;
|
||||
else if (rq->data_len)
|
||||
|
|
|
|||
|
|
@ -1027,7 +1027,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
|
|||
if (sdp->detached)
|
||||
return -ENODEV;
|
||||
if (filp->f_flags & O_NONBLOCK) {
|
||||
if (sdp->device->host->shost_state == SHOST_RECOVERY)
|
||||
if (scsi_host_in_recovery(sdp->device->host))
|
||||
return -EBUSY;
|
||||
} else if (!scsi_block_when_processing_errors(sdp->device))
|
||||
return -EBUSY;
|
||||
|
|
|
|||
|
|
@ -326,6 +326,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
|
|||
return 0;
|
||||
|
||||
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
|
||||
SCpnt->cmd_len = rq->cmd_len;
|
||||
if (!rq->data_len)
|
||||
SCpnt->sc_data_direction = DMA_NONE;
|
||||
else if (rq_data_dir(rq) == WRITE)
|
||||
|
|
|
|||
|
|
@ -4206,6 +4206,7 @@ static int st_init_command(struct scsi_cmnd *SCpnt)
|
|||
return 0;
|
||||
|
||||
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
|
||||
SCpnt->cmd_len = rq->cmd_len;
|
||||
|
||||
if (rq_data_dir(rq) == WRITE)
|
||||
SCpnt->sc_data_direction = DMA_TO_DEVICE;
|
||||
|
|
|
|||
Loading…
Reference in a new issue