linux/drivers/scsi/ses.c
<<
>>
Prefs
   1/*
   2 * SCSI Enclosure Services
   3 *
   4 * Copyright (C) 2008 James Bottomley <James.Bottomley@HansenPartnership.com>
   5 *
   6**-----------------------------------------------------------------------------
   7**
   8**  This program is free software; you can redistribute it and/or
   9**  modify it under the terms of the GNU General Public License
  10**  version 2 as published by the Free Software Foundation.
  11**
  12**  This program is distributed in the hope that it will be useful,
  13**  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15**  GNU General Public License for more details.
  16**
  17**  You should have received a copy of the GNU General Public License
  18**  along with this program; if not, write to the Free Software
  19**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20**
  21**-----------------------------------------------------------------------------
  22*/
  23
  24#include <linux/slab.h>
  25#include <linux/module.h>
  26#include <linux/kernel.h>
  27#include <linux/enclosure.h>
  28#include <asm/unaligned.h>
  29
  30#include <scsi/scsi.h>
  31#include <scsi/scsi_cmnd.h>
  32#include <scsi/scsi_dbg.h>
  33#include <scsi/scsi_device.h>
  34#include <scsi/scsi_driver.h>
  35#include <scsi/scsi_host.h>
  36
  37struct ses_device {
  38        unsigned char *page1;
  39        unsigned char *page1_types;
  40        unsigned char *page2;
  41        unsigned char *page10;
  42        short page1_len;
  43        short page1_num_types;
  44        short page2_len;
  45        short page10_len;
  46};
  47
  48struct ses_component {
  49        u64 addr;
  50};
  51
  52static int ses_probe(struct device *dev)
  53{
  54        struct scsi_device *sdev = to_scsi_device(dev);
  55        int err = -ENODEV;
  56
  57        if (sdev->type != TYPE_ENCLOSURE)
  58                goto out;
  59
  60        err = 0;
  61        sdev_printk(KERN_NOTICE, sdev, "Attached Enclosure device\n");
  62
  63 out:
  64        return err;
  65}
  66
  67#define SES_TIMEOUT (30 * HZ)
  68#define SES_RETRIES 3
  69
  70static void init_device_slot_control(unsigned char *dest_desc,
  71                                     struct enclosure_component *ecomp,
  72                                     unsigned char *status)
  73{
  74        memcpy(dest_desc, status, 4);
  75        dest_desc[0] = 0;
  76        /* only clear byte 1 for ENCLOSURE_COMPONENT_DEVICE */
  77        if (ecomp->type == ENCLOSURE_COMPONENT_DEVICE)
  78                dest_desc[1] = 0;
  79        dest_desc[2] &= 0xde;
  80        dest_desc[3] &= 0x3c;
  81}
  82
  83
  84static int ses_recv_diag(struct scsi_device *sdev, int page_code,
  85                         void *buf, int bufflen)
  86{
  87        unsigned char cmd[] = {
  88                RECEIVE_DIAGNOSTIC,
  89                1,              /* Set PCV bit */
  90                page_code,
  91                bufflen >> 8,
  92                bufflen & 0xff,
  93                0
  94        };
  95
  96        return scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
  97                                NULL, SES_TIMEOUT, SES_RETRIES, NULL);
  98}
  99
 100static int ses_send_diag(struct scsi_device *sdev, int page_code,
 101                         void *buf, int bufflen)
 102{
 103        u32 result;
 104
 105        unsigned char cmd[] = {
 106                SEND_DIAGNOSTIC,
 107                0x10,           /* Set PF bit */
 108                0,
 109                bufflen >> 8,
 110                bufflen & 0xff,
 111                0
 112        };
 113
 114        result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen,
 115                                  NULL, SES_TIMEOUT, SES_RETRIES, NULL);
 116        if (result)
 117                sdev_printk(KERN_ERR, sdev, "SEND DIAGNOSTIC result: %8x\n",
 118                            result);
 119        return result;
 120}
 121
 122static int ses_set_page2_descriptor(struct enclosure_device *edev,
 123                                      struct enclosure_component *ecomp,
 124                                      unsigned char *desc)
 125{
 126        int i, j, count = 0, descriptor = ecomp->number;
 127        struct scsi_device *sdev = to_scsi_device(edev->edev.parent);
 128        struct ses_device *ses_dev = edev->scratch;
 129        unsigned char *type_ptr = ses_dev->page1_types;
 130        unsigned char *desc_ptr = ses_dev->page2 + 8;
 131
 132        /* Clear everything */
 133        memset(desc_ptr, 0, ses_dev->page2_len - 8);
 134        for (i = 0; i < ses_dev->page1_num_types; i++, type_ptr += 4) {
 135                for (j = 0; j < type_ptr[1]; j++) {
 136                        desc_ptr += 4;
 137                        if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE &&
 138                            type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE)
 139                                continue;
 140                        if (count++ == descriptor) {
 141                                memcpy(desc_ptr, desc, 4);
 142                                /* set select */
 143                                desc_ptr[0] |= 0x80;
 144                                /* clear reserved, just in case */
 145                                desc_ptr[0] &= 0xf0;
 146                        }
 147                }
 148        }
 149
 150        return ses_send_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len);
 151}
 152
 153static unsigned char *ses_get_page2_descriptor(struct enclosure_device *edev,
 154                                      struct enclosure_component *ecomp)
 155{
 156        int i, j, count = 0, descriptor = ecomp->number;
 157        struct scsi_device *sdev = to_scsi_device(edev->edev.parent);
 158        struct ses_device *ses_dev = edev->scratch;
 159        unsigned char *type_ptr = ses_dev->page1_types;
 160        unsigned char *desc_ptr = ses_dev->page2 + 8;
 161
 162        ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len);
 163
 164        for (i = 0; i < ses_dev->page1_num_types; i++, type_ptr += 4) {
 165                for (j = 0; j < type_ptr[1]; j++) {
 166                        desc_ptr += 4;
 167                        if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE &&
 168                            type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE)
 169                                continue;
 170                        if (count++ == descriptor)
 171                                return desc_ptr;
 172                }
 173        }
 174        return NULL;
 175}
 176
 177/* For device slot and array device slot elements, byte 3 bit 6
 178 * is "fault sensed" while byte 3 bit 5 is "fault reqstd". As this
 179 * code stands these bits are shifted 4 positions right so in
 180 * sysfs they will appear as bits 2 and 1 respectively. Strange. */
 181static void ses_get_fault(struct enclosure_device *edev,
 182                          struct enclosure_component *ecomp)
 183{
 184        unsigned char *desc;
 185
 186        desc = ses_get_page2_descriptor(edev, ecomp);
 187        if (desc)
 188                ecomp->fault = (desc[3] & 0x60) >> 4;
 189}
 190
 191static int ses_set_fault(struct enclosure_device *edev,
 192                          struct enclosure_component *ecomp,
 193                         enum enclosure_component_setting val)
 194{
 195        unsigned char desc[4];
 196        unsigned char *desc_ptr;
 197
 198        desc_ptr = ses_get_page2_descriptor(edev, ecomp);
 199
 200        if (!desc_ptr)
 201                return -EIO;
 202
 203        init_device_slot_control(desc, ecomp, desc_ptr);
 204
 205        switch (val) {
 206        case ENCLOSURE_SETTING_DISABLED:
 207                desc[3] &= 0xdf;
 208                break;
 209        case ENCLOSURE_SETTING_ENABLED:
 210                desc[3] |= 0x20;
 211                break;
 212        default:
 213                /* SES doesn't do the SGPIO blink settings */
 214                return -EINVAL;
 215        }
 216
 217        return ses_set_page2_descriptor(edev, ecomp, desc);
 218}
 219
 220static void ses_get_status(struct enclosure_device *edev,
 221                           struct enclosure_component *ecomp)
 222{
 223        unsigned char *desc;
 224
 225        desc = ses_get_page2_descriptor(edev, ecomp);
 226        if (desc)
 227                ecomp->status = (desc[0] & 0x0f);
 228}
 229
 230static void ses_get_locate(struct enclosure_device *edev,
 231                           struct enclosure_component *ecomp)
 232{
 233        unsigned char *desc;
 234
 235        desc = ses_get_page2_descriptor(edev, ecomp);
 236        if (desc)
 237                ecomp->locate = (desc[2] & 0x02) ? 1 : 0;
 238}
 239
 240static int ses_set_locate(struct enclosure_device *edev,
 241                          struct enclosure_component *ecomp,
 242                          enum enclosure_component_setting val)
 243{
 244        unsigned char desc[4];
 245        unsigned char *desc_ptr;
 246
 247        desc_ptr = ses_get_page2_descriptor(edev, ecomp);
 248
 249        if (!desc_ptr)
 250                return -EIO;
 251
 252        init_device_slot_control(desc, ecomp, desc_ptr);
 253
 254        switch (val) {
 255        case ENCLOSURE_SETTING_DISABLED:
 256                desc[2] &= 0xfd;
 257                break;
 258        case ENCLOSURE_SETTING_ENABLED:
 259                desc[2] |= 0x02;
 260                break;
 261        default:
 262                /* SES doesn't do the SGPIO blink settings */
 263                return -EINVAL;
 264        }
 265        return ses_set_page2_descriptor(edev, ecomp, desc);
 266}
 267
 268static int ses_set_active(struct enclosure_device *edev,
 269                          struct enclosure_component *ecomp,
 270                          enum enclosure_component_setting val)
 271{
 272        unsigned char desc[4];
 273        unsigned char *desc_ptr;
 274
 275        desc_ptr = ses_get_page2_descriptor(edev, ecomp);
 276
 277        if (!desc_ptr)
 278                return -EIO;
 279
 280        init_device_slot_control(desc, ecomp, desc_ptr);
 281
 282        switch (val) {
 283        case ENCLOSURE_SETTING_DISABLED:
 284                desc[2] &= 0x7f;
 285                ecomp->active = 0;
 286                break;
 287        case ENCLOSURE_SETTING_ENABLED:
 288                desc[2] |= 0x80;
 289                ecomp->active = 1;
 290                break;
 291        default:
 292                /* SES doesn't do the SGPIO blink settings */
 293                return -EINVAL;
 294        }
 295        return ses_set_page2_descriptor(edev, ecomp, desc);
 296}
 297
 298static int ses_show_id(struct enclosure_device *edev, char *buf)
 299{
 300        struct ses_device *ses_dev = edev->scratch;
 301        unsigned long long id = get_unaligned_be64(ses_dev->page1+8+4);
 302
 303        return sprintf(buf, "%#llx\n", id);
 304}
 305
 306static void ses_get_power_status(struct enclosure_device *edev,
 307                                 struct enclosure_component *ecomp)
 308{
 309        unsigned char *desc;
 310
 311        desc = ses_get_page2_descriptor(edev, ecomp);
 312        if (desc)
 313                ecomp->power_status = (desc[3] & 0x10) ? 0 : 1;
 314}
 315
 316static int ses_set_power_status(struct enclosure_device *edev,
 317                                struct enclosure_component *ecomp,
 318                                int val)
 319{
 320        unsigned char desc[4];
 321        unsigned char *desc_ptr;
 322
 323        desc_ptr = ses_get_page2_descriptor(edev, ecomp);
 324
 325        if (!desc_ptr)
 326                return -EIO;
 327
 328        init_device_slot_control(desc, ecomp, desc_ptr);
 329
 330        switch (val) {
 331        /* power = 1 is device_off = 0 and vice versa */
 332        case 0:
 333                desc[3] |= 0x10;
 334                break;
 335        case 1:
 336                desc[3] &= 0xef;
 337                break;
 338        default:
 339                return -EINVAL;
 340        }
 341        ecomp->power_status = val;
 342        return ses_set_page2_descriptor(edev, ecomp, desc);
 343}
 344
 345static struct enclosure_component_callbacks ses_enclosure_callbacks = {
 346        .get_fault              = ses_get_fault,
 347        .set_fault              = ses_set_fault,
 348        .get_status             = ses_get_status,
 349        .get_locate             = ses_get_locate,
 350        .set_locate             = ses_set_locate,
 351        .get_power_status       = ses_get_power_status,
 352        .set_power_status       = ses_set_power_status,
 353        .set_active             = ses_set_active,
 354        .show_id                = ses_show_id,
 355};
 356
 357struct ses_host_edev {
 358        struct Scsi_Host *shost;
 359        struct enclosure_device *edev;
 360};
 361
 362#if 0
 363int ses_match_host(struct enclosure_device *edev, void *data)
 364{
 365        struct ses_host_edev *sed = data;
 366        struct scsi_device *sdev;
 367
 368        if (!scsi_is_sdev_device(edev->edev.parent))
 369                return 0;
 370
 371        sdev = to_scsi_device(edev->edev.parent);
 372
 373        if (sdev->host != sed->shost)
 374                return 0;
 375
 376        sed->edev = edev;
 377        return 1;
 378}
 379#endif  /*  0  */
 380
 381static void ses_process_descriptor(struct enclosure_component *ecomp,
 382                                   unsigned char *desc)
 383{
 384        int eip = desc[0] & 0x10;
 385        int invalid = desc[0] & 0x80;
 386        enum scsi_protocol proto = desc[0] & 0x0f;
 387        u64 addr = 0;
 388        int slot = -1;
 389        struct ses_component *scomp = ecomp->scratch;
 390        unsigned char *d;
 391
 392        if (invalid)
 393                return;
 394
 395        switch (proto) {
 396        case SCSI_PROTOCOL_FCP:
 397                if (eip) {
 398                        d = desc + 4;
 399                        slot = d[3];
 400                }
 401                break;
 402        case SCSI_PROTOCOL_SAS:
 403                if (eip) {
 404                        d = desc + 4;
 405                        slot = d[3];
 406                        d = desc + 8;
 407                } else
 408                        d = desc + 4;
 409                /* only take the phy0 addr */
 410                addr = (u64)d[12] << 56 |
 411                        (u64)d[13] << 48 |
 412                        (u64)d[14] << 40 |
 413                        (u64)d[15] << 32 |
 414                        (u64)d[16] << 24 |
 415                        (u64)d[17] << 16 |
 416                        (u64)d[18] << 8 |
 417                        (u64)d[19];
 418                break;
 419        default:
 420                /* FIXME: Need to add more protocols than just SAS */
 421                break;
 422        }
 423        ecomp->slot = slot;
 424        scomp->addr = addr;
 425}
 426
 427struct efd {
 428        u64 addr;
 429        struct device *dev;
 430};
 431
 432static int ses_enclosure_find_by_addr(struct enclosure_device *edev,
 433                                      void *data)
 434{
 435        struct efd *efd = data;
 436        int i;
 437        struct ses_component *scomp;
 438
 439        if (!edev->component[0].scratch)
 440                return 0;
 441
 442        for (i = 0; i < edev->components; i++) {
 443                scomp = edev->component[i].scratch;
 444                if (scomp->addr != efd->addr)
 445                        continue;
 446
 447                if (enclosure_add_device(edev, i, efd->dev) == 0)
 448                        kobject_uevent(&efd->dev->kobj, KOBJ_CHANGE);
 449                return 1;
 450        }
 451        return 0;
 452}
 453
 454#define INIT_ALLOC_SIZE 32
 455
 456static void ses_enclosure_data_process(struct enclosure_device *edev,
 457                                       struct scsi_device *sdev,
 458                                       int create)
 459{
 460        u32 result;
 461        unsigned char *buf = NULL, *type_ptr, *desc_ptr, *addl_desc_ptr = NULL;
 462        int i, j, page7_len, len, components;
 463        struct ses_device *ses_dev = edev->scratch;
 464        int types = ses_dev->page1_num_types;
 465        unsigned char *hdr_buf = kzalloc(INIT_ALLOC_SIZE, GFP_KERNEL);
 466
 467        if (!hdr_buf)
 468                goto simple_populate;
 469
 470        /* re-read page 10 */
 471        if (ses_dev->page10)
 472                ses_recv_diag(sdev, 10, ses_dev->page10, ses_dev->page10_len);
 473        /* Page 7 for the descriptors is optional */
 474        result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE);
 475        if (result)
 476                goto simple_populate;
 477
 478        page7_len = len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 479        /* add 1 for trailing '\0' we'll use */
 480        buf = kzalloc(len + 1, GFP_KERNEL);
 481        if (!buf)
 482                goto simple_populate;
 483        result = ses_recv_diag(sdev, 7, buf, len);
 484        if (result) {
 485 simple_populate:
 486                kfree(buf);
 487                buf = NULL;
 488                desc_ptr = NULL;
 489                len = 0;
 490                page7_len = 0;
 491        } else {
 492                desc_ptr = buf + 8;
 493                len = (desc_ptr[2] << 8) + desc_ptr[3];
 494                /* skip past overall descriptor */
 495                desc_ptr += len + 4;
 496        }
 497        if (ses_dev->page10)
 498                addl_desc_ptr = ses_dev->page10 + 8;
 499        type_ptr = ses_dev->page1_types;
 500        components = 0;
 501        for (i = 0; i < types; i++, type_ptr += 4) {
 502                for (j = 0; j < type_ptr[1]; j++) {
 503                        char *name = NULL;
 504                        struct enclosure_component *ecomp;
 505
 506                        if (desc_ptr) {
 507                                if (desc_ptr >= buf + page7_len) {
 508                                        desc_ptr = NULL;
 509                                } else {
 510                                        len = (desc_ptr[2] << 8) + desc_ptr[3];
 511                                        desc_ptr += 4;
 512                                        /* Add trailing zero - pushes into
 513                                         * reserved space */
 514                                        desc_ptr[len] = '\0';
 515                                        name = desc_ptr;
 516                                }
 517                        }
 518                        if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
 519                            type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) {
 520
 521                                if (create)
 522                                        ecomp = enclosure_component_alloc(
 523                                                edev,
 524                                                components++,
 525                                                type_ptr[0],
 526                                                name);
 527                                else
 528                                        ecomp = &edev->component[components++];
 529
 530                                if (!IS_ERR(ecomp)) {
 531                                        ses_get_power_status(edev, ecomp);
 532                                        if (addl_desc_ptr)
 533                                                ses_process_descriptor(
 534                                                        ecomp,
 535                                                        addl_desc_ptr);
 536                                        if (create)
 537                                                enclosure_component_register(
 538                                                        ecomp);
 539                                }
 540                        }
 541                        if (desc_ptr)
 542                                desc_ptr += len;
 543
 544                        if (addl_desc_ptr)
 545                                addl_desc_ptr += addl_desc_ptr[1] + 2;
 546
 547                }
 548        }
 549        kfree(buf);
 550        kfree(hdr_buf);
 551}
 552
 553static void ses_match_to_enclosure(struct enclosure_device *edev,
 554                                   struct scsi_device *sdev)
 555{
 556        unsigned char *desc;
 557        struct efd efd = {
 558                .addr = 0,
 559        };
 560
 561        ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0);
 562
 563        if (!sdev->vpd_pg83_len)
 564                return;
 565
 566        desc = sdev->vpd_pg83 + 4;
 567        while (desc < sdev->vpd_pg83 + sdev->vpd_pg83_len) {
 568                enum scsi_protocol proto = desc[0] >> 4;
 569                u8 code_set = desc[0] & 0x0f;
 570                u8 piv = desc[1] & 0x80;
 571                u8 assoc = (desc[1] & 0x30) >> 4;
 572                u8 type = desc[1] & 0x0f;
 573                u8 len = desc[3];
 574
 575                if (piv && code_set == 1 && assoc == 1
 576                    && proto == SCSI_PROTOCOL_SAS && type == 3 && len == 8)
 577                        efd.addr = get_unaligned_be64(&desc[4]);
 578
 579                desc += len + 4;
 580        }
 581        if (efd.addr) {
 582                efd.dev = &sdev->sdev_gendev;
 583
 584                enclosure_for_each_device(ses_enclosure_find_by_addr, &efd);
 585        }
 586}
 587
 588static int ses_intf_add(struct device *cdev,
 589                        struct class_interface *intf)
 590{
 591        struct scsi_device *sdev = to_scsi_device(cdev->parent);
 592        struct scsi_device *tmp_sdev;
 593        unsigned char *buf = NULL, *hdr_buf, *type_ptr;
 594        struct ses_device *ses_dev;
 595        u32 result;
 596        int i, types, len, components = 0;
 597        int err = -ENOMEM;
 598        int num_enclosures;
 599        struct enclosure_device *edev;
 600        struct ses_component *scomp = NULL;
 601
 602        if (!scsi_device_enclosure(sdev)) {
 603                /* not an enclosure, but might be in one */
 604                struct enclosure_device *prev = NULL;
 605
 606                while ((edev = enclosure_find(&sdev->host->shost_gendev, prev)) != NULL) {
 607                        ses_match_to_enclosure(edev, sdev);
 608                        prev = edev;
 609                }
 610                return -ENODEV;
 611        }
 612
 613        /* TYPE_ENCLOSURE prints a message in probe */
 614        if (sdev->type != TYPE_ENCLOSURE)
 615                sdev_printk(KERN_NOTICE, sdev, "Embedded Enclosure Device\n");
 616
 617        ses_dev = kzalloc(sizeof(*ses_dev), GFP_KERNEL);
 618        hdr_buf = kzalloc(INIT_ALLOC_SIZE, GFP_KERNEL);
 619        if (!hdr_buf || !ses_dev)
 620                goto err_init_free;
 621
 622        result = ses_recv_diag(sdev, 1, hdr_buf, INIT_ALLOC_SIZE);
 623        if (result)
 624                goto recv_failed;
 625
 626        len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 627        buf = kzalloc(len, GFP_KERNEL);
 628        if (!buf)
 629                goto err_free;
 630
 631        result = ses_recv_diag(sdev, 1, buf, len);
 632        if (result)
 633                goto recv_failed;
 634
 635        types = 0;
 636
 637        /* we always have one main enclosure and the rest are referred
 638         * to as secondary subenclosures */
 639        num_enclosures = buf[1] + 1;
 640
 641        /* begin at the enclosure descriptor */
 642        type_ptr = buf + 8;
 643        /* skip all the enclosure descriptors */
 644        for (i = 0; i < num_enclosures && type_ptr < buf + len; i++) {
 645                types += type_ptr[2];
 646                type_ptr += type_ptr[3] + 4;
 647        }
 648
 649        ses_dev->page1_types = type_ptr;
 650        ses_dev->page1_num_types = types;
 651
 652        for (i = 0; i < types && type_ptr < buf + len; i++, type_ptr += 4) {
 653                if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
 654                    type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE)
 655                        components += type_ptr[1];
 656        }
 657        ses_dev->page1 = buf;
 658        ses_dev->page1_len = len;
 659        buf = NULL;
 660
 661        result = ses_recv_diag(sdev, 2, hdr_buf, INIT_ALLOC_SIZE);
 662        if (result)
 663                goto recv_failed;
 664
 665        len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 666        buf = kzalloc(len, GFP_KERNEL);
 667        if (!buf)
 668                goto err_free;
 669
 670        /* make sure getting page 2 actually works */
 671        result = ses_recv_diag(sdev, 2, buf, len);
 672        if (result)
 673                goto recv_failed;
 674        ses_dev->page2 = buf;
 675        ses_dev->page2_len = len;
 676        buf = NULL;
 677
 678        /* The additional information page --- allows us
 679         * to match up the devices */
 680        result = ses_recv_diag(sdev, 10, hdr_buf, INIT_ALLOC_SIZE);
 681        if (!result) {
 682
 683                len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 684                buf = kzalloc(len, GFP_KERNEL);
 685                if (!buf)
 686                        goto err_free;
 687
 688                result = ses_recv_diag(sdev, 10, buf, len);
 689                if (result)
 690                        goto recv_failed;
 691                ses_dev->page10 = buf;
 692                ses_dev->page10_len = len;
 693                buf = NULL;
 694        }
 695        scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL);
 696        if (!scomp)
 697                goto err_free;
 698
 699        edev = enclosure_register(cdev->parent, dev_name(&sdev->sdev_gendev),
 700                                  components, &ses_enclosure_callbacks);
 701        if (IS_ERR(edev)) {
 702                err = PTR_ERR(edev);
 703                goto err_free;
 704        }
 705
 706        kfree(hdr_buf);
 707
 708        edev->scratch = ses_dev;
 709        for (i = 0; i < components; i++)
 710                edev->component[i].scratch = scomp + i;
 711
 712        ses_enclosure_data_process(edev, sdev, 1);
 713
 714        /* see if there are any devices matching before
 715         * we found the enclosure */
 716        shost_for_each_device(tmp_sdev, sdev->host) {
 717                if (tmp_sdev->lun != 0 || scsi_device_enclosure(tmp_sdev))
 718                        continue;
 719                ses_match_to_enclosure(edev, tmp_sdev);
 720        }
 721
 722        return 0;
 723
 724 recv_failed:
 725        sdev_printk(KERN_ERR, sdev, "Failed to get diagnostic page 0x%x\n",
 726                    result);
 727        err = -ENODEV;
 728 err_free:
 729        kfree(buf);
 730        kfree(scomp);
 731        kfree(ses_dev->page10);
 732        kfree(ses_dev->page2);
 733        kfree(ses_dev->page1);
 734 err_init_free:
 735        kfree(ses_dev);
 736        kfree(hdr_buf);
 737        sdev_printk(KERN_ERR, sdev, "Failed to bind enclosure %d\n", err);
 738        return err;
 739}
 740
 741static int ses_remove(struct device *dev)
 742{
 743        return 0;
 744}
 745
 746static void ses_intf_remove_component(struct scsi_device *sdev)
 747{
 748        struct enclosure_device *edev, *prev = NULL;
 749
 750        while ((edev = enclosure_find(&sdev->host->shost_gendev, prev)) != NULL) {
 751                prev = edev;
 752                if (!enclosure_remove_device(edev, &sdev->sdev_gendev))
 753                        break;
 754        }
 755        if (edev)
 756                put_device(&edev->edev);
 757}
 758
 759static void ses_intf_remove_enclosure(struct scsi_device *sdev)
 760{
 761        struct enclosure_device *edev;
 762        struct ses_device *ses_dev;
 763
 764        /*  exact match to this enclosure */
 765        edev = enclosure_find(&sdev->sdev_gendev, NULL);
 766        if (!edev)
 767                return;
 768
 769        ses_dev = edev->scratch;
 770        edev->scratch = NULL;
 771
 772        kfree(ses_dev->page10);
 773        kfree(ses_dev->page1);
 774        kfree(ses_dev->page2);
 775        kfree(ses_dev);
 776
 777        kfree(edev->component[0].scratch);
 778
 779        put_device(&edev->edev);
 780        enclosure_unregister(edev);
 781}
 782
 783static void ses_intf_remove(struct device *cdev,
 784                            struct class_interface *intf)
 785{
 786        struct scsi_device *sdev = to_scsi_device(cdev->parent);
 787
 788        if (!scsi_device_enclosure(sdev))
 789                ses_intf_remove_component(sdev);
 790        else
 791                ses_intf_remove_enclosure(sdev);
 792}
 793
 794static struct class_interface ses_interface = {
 795        .add_dev        = ses_intf_add,
 796        .remove_dev     = ses_intf_remove,
 797};
 798
 799static struct scsi_driver ses_template = {
 800        .gendrv = {
 801                .name           = "ses",
 802                .owner          = THIS_MODULE,
 803                .probe          = ses_probe,
 804                .remove         = ses_remove,
 805        },
 806};
 807
 808static int __init ses_init(void)
 809{
 810        int err;
 811
 812        err = scsi_register_interface(&ses_interface);
 813        if (err)
 814                return err;
 815
 816        err = scsi_register_driver(&ses_template.gendrv);
 817        if (err)
 818                goto out_unreg;
 819
 820        return 0;
 821
 822 out_unreg:
 823        scsi_unregister_interface(&ses_interface);
 824        return err;
 825}
 826
 827static void __exit ses_exit(void)
 828{
 829        scsi_unregister_driver(&ses_template.gendrv);
 830        scsi_unregister_interface(&ses_interface);
 831}
 832
 833module_init(ses_init);
 834module_exit(ses_exit);
 835
 836MODULE_ALIAS_SCSI_DEVICE(TYPE_ENCLOSURE);
 837
 838MODULE_AUTHOR("James Bottomley");
 839MODULE_DESCRIPTION("SCSI Enclosure Services (ses) driver");
 840MODULE_LICENSE("GPL v2");
 841