diff options
Diffstat (limited to 'drivers/scsi/aacraid')
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 69 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 10 |
2 files changed, 33 insertions, 46 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index c05092fd3a9d..369fcf78f396 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -205,7 +205,7 @@ MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health" | |||
205 | 205 | ||
206 | int aac_check_reset = 1; | 206 | int aac_check_reset = 1; |
207 | module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR); | 207 | module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR); |
208 | MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the" | 208 | MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the" |
209 | " adapter. a value of -1 forces the reset to adapters programmed to" | 209 | " adapter. a value of -1 forces the reset to adapters programmed to" |
210 | " ignore it."); | 210 | " ignore it."); |
211 | 211 | ||
@@ -379,24 +379,6 @@ int aac_get_containers(struct aac_dev *dev) | |||
379 | return status; | 379 | return status; |
380 | } | 380 | } |
381 | 381 | ||
382 | static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len) | ||
383 | { | ||
384 | void *buf; | ||
385 | int transfer_len; | ||
386 | struct scatterlist *sg = scsi_sglist(scsicmd); | ||
387 | |||
388 | buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; | ||
389 | transfer_len = min(sg->length, len + offset); | ||
390 | |||
391 | transfer_len -= offset; | ||
392 | if (buf && transfer_len > 0) | ||
393 | memcpy(buf + offset, data, transfer_len); | ||
394 | |||
395 | flush_kernel_dcache_page(kmap_atomic_to_page(buf - sg->offset)); | ||
396 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | ||
397 | |||
398 | } | ||
399 | |||
400 | static void get_container_name_callback(void *context, struct fib * fibptr) | 382 | static void get_container_name_callback(void *context, struct fib * fibptr) |
401 | { | 383 | { |
402 | struct aac_get_name_resp * get_name_reply; | 384 | struct aac_get_name_resp * get_name_reply; |
@@ -419,14 +401,17 @@ static void get_container_name_callback(void *context, struct fib * fibptr) | |||
419 | while (*sp == ' ') | 401 | while (*sp == ' ') |
420 | ++sp; | 402 | ++sp; |
421 | if (*sp) { | 403 | if (*sp) { |
404 | struct inquiry_data inq; | ||
422 | char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]; | 405 | char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]; |
423 | int count = sizeof(d); | 406 | int count = sizeof(d); |
424 | char *dp = d; | 407 | char *dp = d; |
425 | do { | 408 | do { |
426 | *dp++ = (*sp) ? *sp++ : ' '; | 409 | *dp++ = (*sp) ? *sp++ : ' '; |
427 | } while (--count > 0); | 410 | } while (--count > 0); |
428 | aac_internal_transfer(scsicmd, d, | 411 | |
429 | offsetof(struct inquiry_data, inqd_pid), sizeof(d)); | 412 | scsi_sg_copy_to_buffer(scsicmd, &inq, sizeof(inq)); |
413 | memcpy(inq.inqd_pid, d, sizeof(d)); | ||
414 | scsi_sg_copy_from_buffer(scsicmd, &inq, sizeof(inq)); | ||
430 | } | 415 | } |
431 | } | 416 | } |
432 | 417 | ||
@@ -811,7 +796,7 @@ static void get_container_serial_callback(void *context, struct fib * fibptr) | |||
811 | sp[2] = 0; | 796 | sp[2] = 0; |
812 | sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", | 797 | sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", |
813 | le32_to_cpu(get_serial_reply->uid)); | 798 | le32_to_cpu(get_serial_reply->uid)); |
814 | aac_internal_transfer(scsicmd, sp, 0, sizeof(sp)); | 799 | scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp)); |
815 | } | 800 | } |
816 | 801 | ||
817 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 802 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
@@ -1986,8 +1971,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1986 | arr[4] = 0x0; | 1971 | arr[4] = 0x0; |
1987 | arr[5] = 0x80; | 1972 | arr[5] = 0x80; |
1988 | arr[1] = scsicmd->cmnd[2]; | 1973 | arr[1] = scsicmd->cmnd[2]; |
1989 | aac_internal_transfer(scsicmd, &inq_data, 0, | 1974 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, |
1990 | sizeof(inq_data)); | 1975 | sizeof(inq_data)); |
1991 | scsicmd->result = DID_OK << 16 | | 1976 | scsicmd->result = DID_OK << 16 | |
1992 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1977 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
1993 | } else if (scsicmd->cmnd[2] == 0x80) { | 1978 | } else if (scsicmd->cmnd[2] == 0x80) { |
@@ -1995,8 +1980,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1995 | arr[3] = setinqserial(dev, &arr[4], | 1980 | arr[3] = setinqserial(dev, &arr[4], |
1996 | scmd_id(scsicmd)); | 1981 | scmd_id(scsicmd)); |
1997 | arr[1] = scsicmd->cmnd[2]; | 1982 | arr[1] = scsicmd->cmnd[2]; |
1998 | aac_internal_transfer(scsicmd, &inq_data, 0, | 1983 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, |
1999 | sizeof(inq_data)); | 1984 | sizeof(inq_data)); |
2000 | return aac_get_container_serial(scsicmd); | 1985 | return aac_get_container_serial(scsicmd); |
2001 | } else { | 1986 | } else { |
2002 | /* vpd page not implemented */ | 1987 | /* vpd page not implemented */ |
@@ -2027,7 +2012,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2027 | if (cid == host->this_id) { | 2012 | if (cid == host->this_id) { |
2028 | setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types)); | 2013 | setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types)); |
2029 | inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ | 2014 | inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ |
2030 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | 2015 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, |
2016 | sizeof(inq_data)); | ||
2031 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 2017 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
2032 | scsicmd->scsi_done(scsicmd); | 2018 | scsicmd->scsi_done(scsicmd); |
2033 | return 0; | 2019 | return 0; |
@@ -2036,7 +2022,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2036 | return -1; | 2022 | return -1; |
2037 | setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); | 2023 | setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); |
2038 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ | 2024 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ |
2039 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | 2025 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, sizeof(inq_data)); |
2040 | return aac_get_container_name(scsicmd); | 2026 | return aac_get_container_name(scsicmd); |
2041 | } | 2027 | } |
2042 | case SERVICE_ACTION_IN: | 2028 | case SERVICE_ACTION_IN: |
@@ -2047,6 +2033,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2047 | { | 2033 | { |
2048 | u64 capacity; | 2034 | u64 capacity; |
2049 | char cp[13]; | 2035 | char cp[13]; |
2036 | unsigned int alloc_len; | ||
2050 | 2037 | ||
2051 | dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); | 2038 | dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); |
2052 | capacity = fsa_dev_ptr[cid].size - 1; | 2039 | capacity = fsa_dev_ptr[cid].size - 1; |
@@ -2063,18 +2050,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2063 | cp[10] = 2; | 2050 | cp[10] = 2; |
2064 | cp[11] = 0; | 2051 | cp[11] = 0; |
2065 | cp[12] = 0; | 2052 | cp[12] = 0; |
2066 | aac_internal_transfer(scsicmd, cp, 0, | ||
2067 | min_t(size_t, scsicmd->cmnd[13], sizeof(cp))); | ||
2068 | if (sizeof(cp) < scsicmd->cmnd[13]) { | ||
2069 | unsigned int len, offset = sizeof(cp); | ||
2070 | 2053 | ||
2071 | memset(cp, 0, offset); | 2054 | alloc_len = ((scsicmd->cmnd[10] << 24) |
2072 | do { | 2055 | + (scsicmd->cmnd[11] << 16) |
2073 | len = min_t(size_t, scsicmd->cmnd[13] - offset, | 2056 | + (scsicmd->cmnd[12] << 8) + scsicmd->cmnd[13]); |
2074 | sizeof(cp)); | 2057 | |
2075 | aac_internal_transfer(scsicmd, cp, offset, len); | 2058 | alloc_len = min_t(size_t, alloc_len, sizeof(cp)); |
2076 | } while ((offset += len) < scsicmd->cmnd[13]); | 2059 | scsi_sg_copy_from_buffer(scsicmd, cp, alloc_len); |
2077 | } | 2060 | if (alloc_len < scsi_bufflen(scsicmd)) |
2061 | scsi_set_resid(scsicmd, | ||
2062 | scsi_bufflen(scsicmd) - alloc_len); | ||
2078 | 2063 | ||
2079 | /* Do not cache partition table for arrays */ | 2064 | /* Do not cache partition table for arrays */ |
2080 | scsicmd->device->removable = 1; | 2065 | scsicmd->device->removable = 1; |
@@ -2104,7 +2089,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2104 | cp[5] = 0; | 2089 | cp[5] = 0; |
2105 | cp[6] = 2; | 2090 | cp[6] = 2; |
2106 | cp[7] = 0; | 2091 | cp[7] = 0; |
2107 | aac_internal_transfer(scsicmd, cp, 0, sizeof(cp)); | 2092 | scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp)); |
2108 | /* Do not cache partition table for arrays */ | 2093 | /* Do not cache partition table for arrays */ |
2109 | scsicmd->device->removable = 1; | 2094 | scsicmd->device->removable = 1; |
2110 | 2095 | ||
@@ -2139,7 +2124,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2139 | if (mode_buf_length > scsicmd->cmnd[4]) | 2124 | if (mode_buf_length > scsicmd->cmnd[4]) |
2140 | mode_buf_length = scsicmd->cmnd[4]; | 2125 | mode_buf_length = scsicmd->cmnd[4]; |
2141 | } | 2126 | } |
2142 | aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length); | 2127 | scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length); |
2143 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 2128 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
2144 | scsicmd->scsi_done(scsicmd); | 2129 | scsicmd->scsi_done(scsicmd); |
2145 | 2130 | ||
@@ -2174,7 +2159,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2174 | if (mode_buf_length > scsicmd->cmnd[8]) | 2159 | if (mode_buf_length > scsicmd->cmnd[8]) |
2175 | mode_buf_length = scsicmd->cmnd[8]; | 2160 | mode_buf_length = scsicmd->cmnd[8]; |
2176 | } | 2161 | } |
2177 | aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length); | 2162 | scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length); |
2178 | 2163 | ||
2179 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 2164 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
2180 | scsicmd->scsi_done(scsicmd); | 2165 | scsicmd->scsi_done(scsicmd); |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 47434499e82b..23a8e9f8dcb4 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -515,10 +515,12 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
515 | } | 515 | } |
516 | udelay(5); | 516 | udelay(5); |
517 | } | 517 | } |
518 | } else | 518 | } else if (down_interruptible(&fibptr->event_wait) == 0) { |
519 | (void)down_interruptible(&fibptr->event_wait); | 519 | fibptr->done = 2; |
520 | up(&fibptr->event_wait); | ||
521 | } | ||
520 | spin_lock_irqsave(&fibptr->event_lock, flags); | 522 | spin_lock_irqsave(&fibptr->event_lock, flags); |
521 | if (fibptr->done == 0) { | 523 | if ((fibptr->done == 0) || (fibptr->done == 2)) { |
522 | fibptr->done = 2; /* Tell interrupt we aborted */ | 524 | fibptr->done = 2; /* Tell interrupt we aborted */ |
523 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | 525 | spin_unlock_irqrestore(&fibptr->event_lock, flags); |
524 | return -EINTR; | 526 | return -EINTR; |
@@ -594,7 +596,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) | |||
594 | if (le32_to_cpu(*q->headers.consumer) >= q->entries) | 596 | if (le32_to_cpu(*q->headers.consumer) >= q->entries) |
595 | *q->headers.consumer = cpu_to_le32(1); | 597 | *q->headers.consumer = cpu_to_le32(1); |
596 | else | 598 | else |
597 | *q->headers.consumer = cpu_to_le32(le32_to_cpu(*q->headers.consumer)+1); | 599 | le32_add_cpu(q->headers.consumer, 1); |
598 | 600 | ||
599 | if (wasfull) { | 601 | if (wasfull) { |
600 | switch (qid) { | 602 | switch (qid) { |